Skip to content

Commit 64f8cfa

Browse files
authored
Upgrade to Scala.js 1.20.1. (#23884)
And related changes.
2 parents d0f0819 + 4f898c5 commit 64f8cfa

15 files changed

+325
-107
lines changed

compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala

Lines changed: 194 additions & 60 deletions
Large diffs are not rendered by default.

compiler/src/dotty/tools/backend/sjs/JSDefinitions.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ final class JSDefinitions()(using Context) {
8585
def JSGlobalScopeAnnot(using Context) = JSGlobalScopeAnnotType.symbol.asClass
8686
@threadUnsafe lazy val JSNameAnnotType: TypeRef = requiredClassRef("scala.scalajs.js.annotation.JSName")
8787
def JSNameAnnot(using Context) = JSNameAnnotType.symbol.asClass
88+
@threadUnsafe lazy val JSOperatorAnnotType: TypeRef = requiredClassRef("scala.scalajs.js.annotation.JSOperator")
89+
def JSOperatorAnnot(using Context) = JSOperatorAnnotType.symbol.asClass
8890
@threadUnsafe lazy val JSFullNameAnnotType: TypeRef = requiredClassRef("scala.scalajs.js.annotation.JSFullName")
8991
def JSFullNameAnnot(using Context) = JSFullNameAnnotType.symbol.asClass
9092
@threadUnsafe lazy val JSBracketAccessAnnotType: TypeRef = requiredClassRef("scala.scalajs.js.annotation.JSBracketAccess")
@@ -213,6 +215,14 @@ final class JSDefinitions()(using Context) {
213215
@threadUnsafe lazy val WrappedArrayType: TypeRef = requiredClassRef("scala.scalajs.js.WrappedArray")
214216
def WrappedArrayClass(using Context) = WrappedArrayType.symbol.asClass
215217

218+
@threadUnsafe lazy val LinkingInfoModuleRef = requiredModuleRef("scala.scalajs.LinkingInfo")
219+
def LinkingInfoModule(using Context) = LinkingInfoModuleRef.symbol
220+
@threadUnsafe lazy val LinkingInfo_linkTimeIfR = LinkingInfoModule.requiredMethodRef("linkTimeIf")
221+
def LinkingInfo_linkTimeIf(using Context) = LinkingInfo_linkTimeIfR.symbol
222+
223+
@threadUnsafe lazy val LinkTimePropertyAnnotType: TypeRef = requiredClassRef("scala.scalajs.annotation.linkTimeProperty")
224+
def LinkTimePropertyAnnot(using Context) = LinkTimePropertyAnnotType.symbol.asClass
225+
216226
@threadUnsafe lazy val ScalaRunTime_isArrayR = defn.ScalaRuntimeModule.requiredMethodRef("isArray", List(???, ???))
217227
def ScalaRunTime_isArray(using Context): Symbol = ScalaRunTime_isArrayR.symbol
218228

compiler/src/dotty/tools/backend/sjs/JSPrimitives.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ object JSPrimitives {
4747
inline val UNWRAP_FROM_THROWABLE = WRAP_AS_THROWABLE + 1 // js.special.unwrapFromThrowable
4848
inline val DEBUGGER = UNWRAP_FROM_THROWABLE + 1 // js.special.debugger
4949

50-
inline val THROW = DEBUGGER + 1 // <special-ops>.throw
51-
inline val NEW_ARRAY = THROW + 1 // scala.runtime.Arrays.newArray
50+
inline val LINKTIME_IF = DEBUGGER + 1 // LinkingInfo.linkTimeIf
51+
52+
inline val THROW = LINKTIME_IF + 1 // <special-ops>.throw
53+
inline val NEW_ARRAY = THROW + 1 // scala.runtime.Arrays.newArray
5254

5355
inline val UNION_FROM = NEW_ARRAY + 1 // js.|.from
5456
inline val UNION_FROM_TYPE_CONSTRUCTOR = UNION_FROM + 1 // js.|.fromTypeConstructor
@@ -135,6 +137,8 @@ class JSPrimitives(ictx: Context) extends DottyPrimitives(ictx) {
135137
addPrimitive(jsdefn.Special_unwrapFromThrowable, UNWRAP_FROM_THROWABLE)
136138
addPrimitive(jsdefn.Special_debugger, DEBUGGER)
137139

140+
addPrimitive(jsdefn.LinkingInfo_linkTimeIf, LINKTIME_IF)
141+
138142
addPrimitive(defn.throwMethod, THROW)
139143
addPrimitive(defn.newArrayMethod, NEW_ARRAY)
140144

compiler/src/dotty/tools/dotc/transform/sjs/JSSymUtils.scala

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,16 @@ object JSSymUtils {
7373
lazy val pc = sym.info.paramNamess.map(_.size).sum
7474

7575
sym.name match {
76-
case nme.apply => Call
77-
case JSUnaryOpMethodName(code) if pc == 0 => UnaryOp(code)
78-
case JSBinaryOpMethodName(code) if pc == 1 => BinaryOp(code)
79-
case _ => default
76+
case nme.apply =>
77+
Call
78+
case JSUnaryOpMethodName(code, defaultsToOp)
79+
if (defaultsToOp || sym.hasAnnotation(jsdefn.JSOperatorAnnot)) && pc == 0 =>
80+
UnaryOp(code)
81+
case JSBinaryOpMethodName(code, defaultsToOp)
82+
if (defaultsToOp || sym.hasAnnotation(jsdefn.JSOperatorAnnot)) && pc == 1 =>
83+
BinaryOp(code)
84+
case _ =>
85+
default
8086
}
8187
} else {
8288
default
@@ -182,6 +188,7 @@ object JSSymUtils {
182188
sym.info.paramNamess.flatten.zip(sym.info.paramInfoss.flatten)
183189

184190
val paramInfosAtElimRepeated = atPhase(elimRepeatedPhase) {
191+
// See also JSCodeGen.genActualArgs
185192
val list =
186193
for ((name, info) <- paramNamesAndTypes) yield {
187194
val v =
@@ -230,43 +237,70 @@ object JSSymUtils {
230237
end sjsNeedsField
231238
}
232239

240+
/** Extractor for a `TermName` that *may* be a JS unary operator.
241+
*
242+
* If it may be a JS unary operator, then a method with that name may have
243+
* the `@JSOperator` annotation, and it will be treated as such.
244+
*
245+
* If a method has neither `@JSName` nor `@JSOperator`, then a default is
246+
* chosen. If the `Boolean` value is `true`, the default is to treat the
247+
* method as if it had `@JSOperator`. If it is `false`, the default is *not*
248+
* to treat it as an operator.
249+
*
250+
* Currently, all JS unary operators default to `@JSOperator`.
251+
*/
233252
private object JSUnaryOpMethodName {
234253
private val map = Map(
235-
nme.UNARY_+ -> js.JSUnaryOp.+,
236-
nme.UNARY_- -> js.JSUnaryOp.-,
237-
nme.UNARY_~ -> js.JSUnaryOp.~,
238-
nme.UNARY_! -> js.JSUnaryOp.!
254+
nme.UNARY_+ -> (js.JSUnaryOp.+, true),
255+
nme.UNARY_- -> (js.JSUnaryOp.-, true),
256+
nme.UNARY_~ -> (js.JSUnaryOp.~, true),
257+
nme.UNARY_! -> (js.JSUnaryOp.!, true),
239258
)
240259

241-
def unapply(name: TermName): Option[js.JSUnaryOp.Code] =
260+
def unapply(name: TermName): Option[(js.JSUnaryOp.Code, Boolean)] =
242261
map.get(name)
243262
}
244263

264+
/** Extractor for a `TermName` that *may* be a JS binary operator.
265+
*
266+
* If it may be a JS binary operator, then a method with that name may have
267+
* the `@JSOperator` annotation, and it will be treated as such.
268+
*
269+
* If a method has neither `@JSName` nor `@JSOperator`, then a default is
270+
* chosen. If the `Boolean` value is `true`, the default is to treat the
271+
* method as if it had `@JSOperator`. If it is `false`, the default is *not*
272+
* to treat it as an operator.
273+
*
274+
* Most JS binary operators default to `@JSOperator`. Currently, the only
275+
* exception is `**`, for backward compatibility reasons.
276+
*/
245277
private object JSBinaryOpMethodName {
246278
private val map = Map(
247-
nme.ADD -> js.JSBinaryOp.+,
248-
nme.SUB -> js.JSBinaryOp.-,
249-
nme.MUL -> js.JSBinaryOp.*,
250-
nme.DIV -> js.JSBinaryOp./,
251-
nme.MOD -> js.JSBinaryOp.%,
252-
253-
nme.LSL -> js.JSBinaryOp.<<,
254-
nme.ASR -> js.JSBinaryOp.>>,
255-
nme.LSR -> js.JSBinaryOp.>>>,
256-
nme.OR -> js.JSBinaryOp.|,
257-
nme.AND -> js.JSBinaryOp.&,
258-
nme.XOR -> js.JSBinaryOp.^,
259-
260-
nme.LT -> js.JSBinaryOp.<,
261-
nme.LE -> js.JSBinaryOp.<=,
262-
nme.GT -> js.JSBinaryOp.>,
263-
nme.GE -> js.JSBinaryOp.>=,
264-
265-
nme.ZAND -> js.JSBinaryOp.&&,
266-
nme.ZOR -> js.JSBinaryOp.||
279+
nme.ADD -> (js.JSBinaryOp.+, true),
280+
nme.SUB -> (js.JSBinaryOp.-, true),
281+
nme.MUL -> (js.JSBinaryOp.*, true),
282+
nme.DIV -> (js.JSBinaryOp./, true),
283+
nme.MOD -> (js.JSBinaryOp.%, true),
284+
285+
nme.LSL -> (js.JSBinaryOp.<<, true),
286+
nme.ASR -> (js.JSBinaryOp.>>, true),
287+
nme.LSR -> (js.JSBinaryOp.>>>, true),
288+
nme.OR -> (js.JSBinaryOp.|, true),
289+
nme.AND -> (js.JSBinaryOp.&, true),
290+
nme.XOR -> (js.JSBinaryOp.^, true),
291+
292+
nme.LT -> (js.JSBinaryOp.<, true),
293+
nme.LE -> (js.JSBinaryOp.<=, true),
294+
nme.GT -> (js.JSBinaryOp.>, true),
295+
nme.GE -> (js.JSBinaryOp.>=, true),
296+
297+
nme.ZAND -> (js.JSBinaryOp.&&, true),
298+
nme.ZOR -> (js.JSBinaryOp.||, true),
299+
300+
termName("**") -> (js.JSBinaryOp.**, false),
267301
)
268302

269-
def unapply(name: TermName): Option[js.JSBinaryOp.Code] =
303+
def unapply(name: TermName): Option[(js.JSBinaryOp.Code, Boolean)] =
270304
map.get(name)
271305
}
272306
}

compiler/test/dotty/tools/vulpix/ParallelTesting.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,13 @@ trait ParallelTesting extends RunnerOrchestration:
7171
def outDir: JFile
7272
def flags: TestFlags
7373
def sourceFiles: Array[JFile]
74-
def checkFile: Option[JFile]
74+
def checkFileBasePathCandidates: Array[String]
75+
76+
final def checkFile: Option[JFile] =
77+
checkFileBasePathCandidates
78+
.iterator
79+
.flatMap(base => Iterator(new JFile(s"$base.$testPlatform.check"), new JFile(s"$base.check")))
80+
.find(_.exists())
7581

7682
def runClassPath: String = outDir.getPath + JFile.pathSeparator + flags.runClassPath
7783

@@ -186,9 +192,8 @@ trait ParallelTesting extends RunnerOrchestration:
186192
) extends TestSource {
187193
def sourceFiles: Array[JFile] = files.filter(isSourceFile)
188194

189-
def checkFile: Option[JFile] =
190-
sourceFiles.map(f => new JFile(f.getPath.replaceFirst("\\.(scala|java)$", ".check")))
191-
.find(_.exists())
195+
def checkFileBasePathCandidates: Array[String] =
196+
sourceFiles.map(f => f.getPath.replaceFirst("\\.(scala|java)$", ""))
192197
}
193198

194199
/** A test source whose files will be compiled separately according to their
@@ -221,11 +226,8 @@ trait ParallelTesting extends RunnerOrchestration:
221226

222227
def sourceFiles = compilationGroups.map(_._2).flatten.toArray
223228

224-
def checkFile: Option[JFile] =
225-
val platform =
226-
if allToolArgs.getOrElse(ToolName.Target, Nil).nonEmpty then s".$testPlatform"
227-
else ""
228-
Some(new JFile(dir.getPath + platform + ".check")).filter(_.exists)
229+
def checkFileBasePathCandidates: Array[String] =
230+
Array(dir.getPath)
229231
}
230232

231233
protected def shouldSkipTestSource(testSource: TestSource): Boolean = false

project/ScalaLibraryPlugin.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import scala.jdk.CollectionConverters.*
66
import java.nio.file.Files
77
import xsbti.VirtualFileRef
88
import sbt.internal.inc.Stamper
9+
import org.scalajs.sbtplugin.ScalaJSPlugin.autoImport.scalaJSVersion
910

1011
object ScalaLibraryPlugin extends AutoPlugin {
1112

1213
override def trigger = noTrigger
1314

14-
private val scala2Version = "2.13.16"
15-
private val scalaJSVersion = "1.19.0"
15+
private val scala2Version = "2.13.16"
1616

1717
val fetchScala2ClassFiles = taskKey[(Set[File], File)]("Fetch the files to use that were compiled with Scala 2")
1818
val fetchScala2SJSIR = taskKey[(Set[File], File)]("Fetch the .sjsir to use from Scala 2")

project/plugins.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
libraryDependencySchemes +=
77
"org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always
88

9-
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.19.0")
9+
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.20.1")
1010

1111
addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.2.1")
1212

tests/run/i17761.scala-js.check

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Normal
2+
test
3+
WrappedVarArgs(class java.lang.String, int)
4+
WrappedVarArgs(test, 42)
5+
Transparent
6+
test
7+
ArraySeq(class java.lang.String, int)
8+
ArraySeq(test, 42)

tests/run/i3207.scala-js.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
WrappedVarArgs()
2+
WrappedVarArgs(A, B)

tests/run/i768.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ArraySeq(a, bc)

0 commit comments

Comments
 (0)