Skip to content

Commit

Permalink
Upgrade to Scala.js 1.9.0.
Browse files Browse the repository at this point in the history
This includes a forward-port of the upstream changes in

* scala-js/scala-js@887d957
  Require an explicit name in @jsglobal for 'apply' and setter names.
* scala-js/scala-js@354cfdf
  Allow @jsglobal without explicit names inside Scala objects.
* scala-js/scala-js@9fa6a83
  Fix scala#4069: Make @jsimport's second arg default to the annotatee's name.
  • Loading branch information
sjrd committed Mar 2, 2022
1 parent d499109 commit cd7f528
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 14 deletions.
9 changes: 8 additions & 1 deletion compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4564,7 +4564,14 @@ class JSCodeGen()(using genCtx: Context) {
val module = annot.argumentConstantString(0).getOrElse {
unexpected("could not read the module argument as a string literal")
}
val path = annot.argumentConstantString(1).fold[List[String]](Nil)(parsePath)
val path = annot.argumentConstantString(1).fold {
if (annot.arguments.sizeIs < 2)
parsePath(sym.defaultJSName)
else
Nil
} { pathName =>
parsePath(pathName)
}
val importSpec = Import(module, path)
annot.argumentConstantString(2).fold[js.JSNativeLoadSpec] {
importSpec
Expand Down
33 changes: 26 additions & 7 deletions compiler/src/dotty/tools/dotc/transform/sjs/PrepJSInterop.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import Contexts._
import Decorators._
import DenotTransformers._
import Flags._
import NameKinds.DefaultGetterName
import NameKinds.{DefaultGetterName, ModuleClassName}
import NameOps._
import StdNames._
import Symbols._
import SymUtils._
Expand Down Expand Up @@ -559,9 +560,14 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
case Some(annot) if annot.symbol == jsdefn.JSGlobalAnnot =>
checkJSGlobalLiteral(annot)
val pathName = annot.argumentConstantString(0).getOrElse {
if ((enclosingOwner is OwnerKind.ScalaMod) && !sym.owner.isPackageObject) {
val symTermName = sym.name.exclude(NameKinds.ModuleClassName).toTermName
if (symTermName == nme.apply) {
report.error(
"Native JS members inside non-native objects must have an explicit name in @JSGlobal",
"Native JS definitions named 'apply' must have an explicit name in @JSGlobal",
annot.tree)
} else if (symTermName.isSetterName) {
report.error(
"Native JS definitions with a name ending in '_=' must have an explicit name in @JSGlobal",
annot.tree)
}
sym.defaultJSName
Expand All @@ -570,6 +576,18 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP

case Some(annot) if annot.symbol == jsdefn.JSImportAnnot =>
checkJSImportLiteral(annot)
if (annot.arguments.sizeIs < 2) {
val symTermName = sym.name.exclude(NameKinds.ModuleClassName).toTermName
if (symTermName == nme.apply) {
report.error(
"Native JS definitions named 'apply' must have an explicit name in @JSImport",
annot.tree)
} else if (symTermName.isSetterName) {
report.error(
"Native JS definitions with a name ending in '_=' must have an explicit name in @JSImport",
annot.tree)
}
}
annot.argumentConstantString(2).foreach { globalPathName =>
checkGlobalRefPath(globalPathName)
}
Expand Down Expand Up @@ -1107,18 +1125,19 @@ object PrepJSInterop {
*/
private def checkJSImportLiteral(annot: Annotation)(using Context): Unit = {
val args = annot.arguments
assert(args.size == 2 || args.size == 3,
i"@JSImport annotation $annot does not have exactly 2 or 3 arguments")
val argCount = args.size
assert(argCount >= 1 && argCount <= 3,
i"@JSImport annotation $annot does not have between 1 and 3 arguments")

val firstArgIsValid = annot.argumentConstantString(0).isDefined
if (!firstArgIsValid)
report.error("The first argument to @JSImport must be a literal string.", args.head)

val secondArgIsValid = annot.argumentConstantString(1).isDefined || args(1).symbol == jsdefn.JSImportNamespaceModule
val secondArgIsValid = argCount < 2 || annot.argumentConstantString(1).isDefined || args(1).symbol == jsdefn.JSImportNamespaceModule
if (!secondArgIsValid)
report.error("The second argument to @JSImport must be literal string or the JSImport.Namespace object.", args(1))

val thirdArgIsValid = args.size < 3 || annot.argumentConstantString(2).isDefined
val thirdArgIsValid = argCount < 3 || annot.argumentConstantString(2).isDefined
if (!thirdArgIsValid)
report.error("The third argument to @JSImport, when present, must be a literal string.", args(2))
}
Expand Down
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// e.g. addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.1.0")

addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.7.1")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.9.0")

addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.10")

Expand Down
44 changes: 42 additions & 2 deletions tests/neg-scalajs/native-load-spec-need-explicit-name.check
Original file line number Diff line number Diff line change
@@ -1,8 +1,48 @@
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:6:2 ----------------------------------------------
6 | @JSGlobal // error
| ^^^^^^^^^
| Native JS members inside non-native objects must have an explicit name in @JSGlobal
| Native JS definitions named 'apply' must have an explicit name in @JSGlobal
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:10:2 ---------------------------------------------
10 | @JSGlobal // error
| ^^^^^^^^^
| Native JS members inside non-native objects must have an explicit name in @JSGlobal
| Native JS definitions named 'apply' must have an explicit name in @JSGlobal
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:14:2 ---------------------------------------------
14 | @JSGlobal // error
| ^^^^^^^^^
| Native JS definitions with a name ending in '_=' must have an explicit name in @JSGlobal
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:20:2 ---------------------------------------------
20 | @JSGlobal // error
| ^^^^^^^^^
| Native JS definitions with a name ending in '_=' must have an explicit name in @JSGlobal
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:19:2 ---------------------------------------------
19 | @js.native // error
| ^^^^^^^^^^
| @js.native is not allowed on vars, lazy vals and setter defs
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:24:2 ---------------------------------------------
24 | @JSGlobal // error
| ^^^^^^^^^
| Native JS definitions named 'apply' must have an explicit name in @JSGlobal
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:30:3 ---------------------------------------------
30 | @JSImport("bar.js") // error
| ^^^^^^^^^^^^^^^^^^^
| Native JS definitions named 'apply' must have an explicit name in @JSImport
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:34:3 ---------------------------------------------
34 | @JSImport("bar.js") // error
| ^^^^^^^^^^^^^^^^^^^
| Native JS definitions named 'apply' must have an explicit name in @JSImport
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:38:3 ---------------------------------------------
38 | @JSImport("bar.js") // error
| ^^^^^^^^^^^^^^^^^^^
| Native JS definitions with a name ending in '_=' must have an explicit name in @JSImport
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:44:3 ---------------------------------------------
44 | @JSImport("bar.js") // error
| ^^^^^^^^^^^^^^^^^^^
| Native JS definitions with a name ending in '_=' must have an explicit name in @JSImport
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:43:2 ---------------------------------------------
43 | @js.native // error
| ^^^^^^^^^^
| @js.native is not allowed on vars, lazy vals and setter defs
-- Error: tests/neg-scalajs/native-load-spec-need-explicit-name.scala:48:3 ---------------------------------------------
48 | @JSImport("bar.js") // error
| ^^^^^^^^^^^^^^^^^^^
| Native JS definitions named 'apply' must have an explicit name in @JSImport
44 changes: 41 additions & 3 deletions tests/neg-scalajs/native-load-spec-need-explicit-name.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,52 @@
import scala.scalajs.js
import scala.scalajs.js.annotation.*

object A {
object A1 {
@js.native
@JSGlobal // error
class B extends js.Object
class apply extends js.Object

@js.native
@JSGlobal // error
object C extends js.Object
object apply extends js.Object

@js.native
@JSGlobal // error
class foo_= extends js.Object
}

object A2 {
@js.native // error
@JSGlobal // error
def foo_=(x: Int): Unit = js.native

@js.native
@JSGlobal // error
def apply(x: Int): Int = js.native
}

object B1 {
@js.native
@JSImport("bar.js") // error
class apply extends js.Object

@js.native
@JSImport("bar.js") // error
object apply extends js.Object

@js.native
@JSImport("bar.js") // error
class foo_= extends js.Object
}

object B2 {
@js.native // error
@JSImport("bar.js") // error
def foo_=(x: Int): Unit = js.native

@js.native
@JSImport("bar.js") // error
def apply(x: Int): Int = js.native
}

// scala-js#2401
Expand Down

0 comments on commit cd7f528

Please sign in to comment.