Skip to content

Commit ff402a0

Browse files
committed
Upgrade to Scala.js 1.5.0.
This includes forward ports of the compiler changes in the following upstream commits: - scala-js/scala-js@5a15add Encode fields of type Nothing with scala.runtime.Nothing$. - scala-js/scala-js@294efab Do not emit abstract methods in non-native JS classes. - scala-js/scala-js@f0476c0 Encode allowed LHS of Assign in type system - scala-js/scala-js@df5b3c6 Replace `rest` field in `ir.ParamDef` with special members It does *not* contain the changes from the upstream commit - scala-js/scala-js@7edacf5 Generalize js.Function's to allow user-defined ones. Porting the support for custom JS function types is left for a separate commit for this repo. This means that we need to blacklist the new upstream test file `CustomJSFunctionTest.scala`.
1 parent 11265bc commit ff402a0

File tree

6 files changed

+70
-49
lines changed

6 files changed

+70
-49
lines changed

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

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ class JSCodeGen()(using genCtx: Context) {
758758
(paramName, paramInfo) <- m.info.paramNamess.flatten.zip(m.info.paramInfoss.flatten)
759759
} yield {
760760
js.ParamDef(freshLocalIdent(paramName), NoOriginalName,
761-
toIRType(paramInfo), mutable = false, rest = false)
761+
toIRType(paramInfo), mutable = false)
762762
}
763763
val resultType = toIRType(m.info.resultType)
764764

@@ -811,11 +811,16 @@ class JSCodeGen()(using genCtx: Context) {
811811

812812
val flags = js.MemberFlags.empty.withMutable(mutable).withNamespace(namespace)
813813

814-
val irTpe =
814+
val irTpe0 =
815815
if (isJSClass) genExposedFieldIRType(f)
816816
else if (isTopLevelExport) jstpe.AnyType
817817
else toIRType(f.info)
818818

819+
// scala-js/#4370 Fields cannot have type NothingType
820+
val irTpe =
821+
if (irTpe0 == jstpe.NothingType) encodeClassType(defn.NothingClass)
822+
else irTpe0
823+
819824
if (isJSClass && f.isJSExposed)
820825
js.JSFieldDef(flags, genExpr(f.jsName)(f.sourcePos), irTpe) :: Nil
821826
else
@@ -896,7 +901,7 @@ class JSCodeGen()(using genCtx: Context) {
896901
val fqcnArg = js.StringLiteral(sym.fullName.toString)
897902
val runtimeClassArg = js.ClassOf(toTypeRef(sym.info))
898903
val loadModuleFunArg =
899-
js.Closure(arrow = true, Nil, Nil, genLoadModule(sym), Nil)
904+
js.Closure(arrow = true, Nil, Nil, None, genLoadModule(sym), Nil)
900905

901906
val stat = genApplyMethod(
902907
genLoadModule(jsdefn.ReflectModule),
@@ -924,14 +929,14 @@ class JSCodeGen()(using genCtx: Context) {
924929
} yield {
925930
val paramType = js.ClassOf(toTypeRef(paramInfo))
926931
val paramDef = js.ParamDef(freshLocalIdent(paramName),
927-
NoOriginalName, jstpe.AnyType, mutable = false, rest = false)
932+
NoOriginalName, jstpe.AnyType, mutable = false)
928933
val actualParam = unbox(paramDef.ref, paramInfo)
929934
(paramType, paramDef, actualParam)
930935
}).unzip3
931936

932937
val paramTypesArray = js.JSArrayConstr(parameterTypes)
933938

934-
val newInstanceFun = js.Closure(arrow = true, Nil, formalParams, {
939+
val newInstanceFun = js.Closure(arrow = true, Nil, formalParams, None, {
935940
js.New(encodeClassName(sym), encodeMethodSym(ctor), actualParams)
936941
}, Nil)
937942

@@ -965,7 +970,7 @@ class JSCodeGen()(using genCtx: Context) {
965970
"if their companion module is JS native.",
966971
classSym.srcPos)
967972
val ctorDef = js.JSMethodDef(js.MemberFlags.empty,
968-
js.StringLiteral("constructor"), Nil, js.Skip())(
973+
js.StringLiteral("constructor"), Nil, None, js.Skip())(
969974
OptimizerHints.empty, None)
970975
(None, ctorDef)
971976
} else {
@@ -985,7 +990,7 @@ class JSCodeGen()(using genCtx: Context) {
985990
val captureParamsWithJSSuperClass = captureParams.map { params =>
986991
val jsSuperClassParam = js.ParamDef(
987992
js.LocalIdent(JSSuperClassParamName), NoOriginalName,
988-
jstpe.AnyType, mutable = false, rest = false)
993+
jstpe.AnyType, mutable = false)
989994
jsSuperClassParam :: params
990995
}
991996

@@ -1055,6 +1060,9 @@ class JSCodeGen()(using genCtx: Context) {
10551060

10561061
if (primitives.isPrimitive(sym)) {
10571062
None
1063+
} else if (sym.is(Deferred) && currentClassSym.isNonNativeJSClass) {
1064+
// scala-js/#4409: Do not emit abstract methods in non-native JS classes
1065+
None
10581066
} else if (sym.is(Deferred)) {
10591067
Some(js.MethodDef(js.MemberFlags.empty, methodName, originalName,
10601068
jsParams, toIRType(patchedResultType(sym)), None)(
@@ -1153,7 +1161,7 @@ class JSCodeGen()(using genCtx: Context) {
11531161
val flags =
11541162
js.MemberFlags.empty.withNamespace(staticNamespace)
11551163
val thisParamDef = js.ParamDef(thisLocalIdent, thisOriginalName,
1156-
jstpe.AnyType, mutable = false, rest = false)
1164+
jstpe.AnyType, mutable = false)
11571165

11581166
js.MethodDef(flags, methodName, originalName,
11591167
thisParamDef :: jsParams, resultIRType, Some(genBody()))(
@@ -1222,7 +1230,7 @@ class JSCodeGen()(using genCtx: Context) {
12221230

12231231
private def genParamDef(sym: Symbol, ptpe: jstpe.Type, pos: Position): js.ParamDef = {
12241232
js.ParamDef(encodeLocalSym(sym)(implicitly, pos, implicitly),
1225-
originalNameOfLocal(sym), ptpe, mutable = false, rest = false)(pos)
1233+
originalNameOfLocal(sym), ptpe, mutable = false)(pos)
12261234
}
12271235

12281236
// Generate statements and expressions -------------------------------------
@@ -1930,10 +1938,11 @@ class JSCodeGen()(using genCtx: Context) {
19301938
val jsClassCaptures = originalClassDef.jsClassCaptures.getOrElse {
19311939
throw new AssertionError(s"no class captures for anonymous JS class at $pos")
19321940
}
1933-
val js.JSMethodDef(_, _, ctorParams, ctorBody) = constructor.getOrElse {
1941+
val js.JSMethodDef(_, _, ctorParams, ctorRestParam, ctorBody) = constructor.getOrElse {
19341942
throw new AssertionError("No ctor found")
19351943
}
1936-
assert(ctorParams.isEmpty, s"non-empty constructor params for anonymous JS class at $pos")
1944+
assert(ctorParams.isEmpty && ctorRestParam.isEmpty,
1945+
s"non-empty constructor params for anonymous JS class at $pos")
19371946

19381947
/* The first class capture is always a reference to the super class.
19391948
* This is enforced by genJSClassCapturesAndConstructor.
@@ -1950,8 +1959,8 @@ class JSCodeGen()(using genCtx: Context) {
19501959
def selfRef(implicit pos: ir.Position) =
19511960
js.VarRef(selfName)(jstpe.AnyType)
19521961

1953-
def memberLambda(params: List[js.ParamDef], body: js.Tree)(implicit pos: ir.Position): js.Closure =
1954-
js.Closure(arrow = false, captureParams = Nil, params, body, captureValues = Nil)
1962+
def memberLambda(params: List[js.ParamDef], restParam: Option[js.ParamDef], body: js.Tree)(implicit pos: ir.Position): js.Closure =
1963+
js.Closure(arrow = false, captureParams = Nil, params, restParam, body, captureValues = Nil)
19551964

19561965
val memberDefinitions0 = instanceMembers.toList.map {
19571966
case fdef: js.FieldDef =>
@@ -1966,16 +1975,16 @@ class JSCodeGen()(using genCtx: Context) {
19661975

19671976
case mdef: js.JSMethodDef =>
19681977
implicit val pos = mdef.pos
1969-
val impl = memberLambda(mdef.args, mdef.body)
1978+
val impl = memberLambda(mdef.args, mdef.restParam, mdef.body)
19701979
js.Assign(js.JSSelect(selfRef, mdef.name), impl)
19711980

19721981
case pdef: js.JSPropertyDef =>
19731982
implicit val pos = pdef.pos
19741983
val optGetter = pdef.getterBody.map { body =>
1975-
js.StringLiteral("get") -> memberLambda(params = Nil, body)
1984+
js.StringLiteral("get") -> memberLambda(params = Nil, restParam = None, body)
19761985
}
19771986
val optSetter = pdef.setterArgAndBody.map { case (arg, body) =>
1978-
js.StringLiteral("set") -> memberLambda(params = arg :: Nil, body)
1987+
js.StringLiteral("set") -> memberLambda(params = arg :: Nil, restParam = None, body)
19791988
}
19801989
val descriptor = js.JSObjectConstr(
19811990
optGetter.toList :::
@@ -2067,7 +2076,7 @@ class JSCodeGen()(using genCtx: Context) {
20672076
}
20682077
}.transform(ctorBody, isStat = true)
20692078

2070-
val closure = js.Closure(arrow = true, jsClassCaptures, Nil,
2079+
val closure = js.Closure(arrow = true, jsClassCaptures, Nil, None,
20712080
js.Block(inlinedCtorStats, selfRef), jsSuperClassValue :: args)
20722081
js.JSFunctionApply(closure, Nil)
20732082
}
@@ -2519,7 +2528,7 @@ class JSCodeGen()(using genCtx: Context) {
25192528
ErrorType(msg)
25202529
}
25212530

2522-
def genSelect(): js.Tree =
2531+
def genSelect(): js.AssignLhs =
25232532
js.ArraySelect(genArray, genArgs(0))(toIRType(elementType))
25242533

25252534
if (isArrayGet(code)) {
@@ -2679,8 +2688,8 @@ class JSCodeGen()(using genCtx: Context) {
26792688
case _ =>
26802689
def jsFunName = genExpr(jsNameOf(sym))
26812690

2682-
def genSuperReference(propName: js.Tree): js.Tree = {
2683-
jsSuperClassValue.fold[js.Tree] {
2691+
def genSuperReference(propName: js.Tree): js.AssignLhs = {
2692+
jsSuperClassValue.fold[js.AssignLhs] {
26842693
genJSSelectOrGlobalRef(receiver, propName)
26852694
} { superClassValue =>
26862695
js.JSSuperSelect(superClassValue, ruleOutGlobalScope(receiver), propName)
@@ -3075,7 +3084,7 @@ class JSCodeGen()(using genCtx: Context) {
30753084
case _ => (freshLocalIdent(), NoOriginalName)
30763085
}
30773086
val formalCapture = js.ParamDef(formalIdent, originalName,
3078-
toIRType(value.tpe), mutable = false, rest = false)
3087+
toIRType(value.tpe), mutable = false)
30793088
val actualCapture = genExpr(value)
30803089
(formalCapture, actualCapture)
30813090
}
@@ -3087,8 +3096,7 @@ class JSCodeGen()(using genCtx: Context) {
30873096
val formalAndActualParams = formalParamNamesAndTypes.map {
30883097
case (name, tpe) =>
30893098
val formalParam = js.ParamDef(freshLocalIdent(name.toString),
3090-
OriginalName(name.toString), jstpe.AnyType, mutable = false,
3091-
rest = false)
3099+
OriginalName(name.toString), jstpe.AnyType, mutable = false)
30923100
val actualParam = unbox(formalParam.ref, tpe)
30933101
(formalParam, actualParam)
30943102
}
@@ -3115,14 +3123,15 @@ class JSCodeGen()(using genCtx: Context) {
31153123
arrow = false,
31163124
formalCaptures,
31173125
otherParams,
3126+
None,
31183127
js.Block(
31193128
js.VarDef(thisParam.name, thisParam.originalName,
31203129
thisParam.ptpe, mutable = false,
31213130
js.This()(thisParam.ptpe)(thisParam.pos))(thisParam.pos),
31223131
genBody),
31233132
actualCaptures)
31243133
} else {
3125-
val closure = js.Closure(arrow = true, formalCaptures, formalParams, genBody, actualCaptures)
3134+
val closure = js.Closure(arrow = true, formalCaptures, formalParams, None, genBody, actualCaptures)
31263135

31273136
if (jsdefn.isJSFunctionClass(funInterfaceSym)) {
31283137
closure
@@ -3894,7 +3903,7 @@ class JSCodeGen()(using genCtx: Context) {
38943903
}
38953904
}
38963905

3897-
private def genAssignableField(sym: Symbol, qualifier: Tree)(implicit pos: SourcePosition): (js.Tree, Boolean) = {
3906+
private def genAssignableField(sym: Symbol, qualifier: Tree)(implicit pos: SourcePosition): (js.AssignLhs, Boolean) = {
38983907
def qual = genExpr(qualifier)
38993908

39003909
if (sym.owner.isNonNativeJSClass) {
@@ -3921,17 +3930,27 @@ class JSCodeGen()(using genCtx: Context) {
39213930
val f = js.JSSelect(genLoadJSConstructor(companionClass), js.StringLiteral(jsName))
39223931
(f, true)
39233932
} else {
3924-
val f =
3925-
val className = encodeClassName(sym.owner)
3926-
val fieldIdent = encodeFieldSym(sym)
3927-
val irType = toIRType(sym.info)
3933+
val className = encodeClassName(sym.owner)
3934+
val fieldIdent = encodeFieldSym(sym)
3935+
3936+
/* #4370 Fields cannot have type NothingType, so we box them as
3937+
* scala.runtime.Nothing$ instead. They will be initialized with
3938+
* `null`, and any attempt to access them will throw a
3939+
* `ClassCastException` (generated in the unboxing code).
3940+
*/
3941+
val (irType, boxed) = toIRType(sym.info) match
3942+
case jstpe.NothingType =>
3943+
(encodeClassType(defn.NothingClass), true)
3944+
case ftpe =>
3945+
(ftpe, false)
39283946

3947+
val f =
39293948
if sym.is(JavaStatic) then
39303949
js.SelectStatic(className, fieldIdent)(irType)
39313950
else
39323951
js.Select(qual, className, fieldIdent)(irType)
39333952

3934-
(f, false)
3953+
(f, boxed)
39353954
}
39363955
}
39373956

@@ -4048,7 +4067,7 @@ class JSCodeGen()(using genCtx: Context) {
40484067
* Otherwise, report a compile error.
40494068
*/
40504069
private def genJSSelectOrGlobalRef(qual: MaybeGlobalScope, item: js.Tree)(
4051-
implicit pos: SourcePosition): js.Tree = {
4070+
implicit pos: SourcePosition): js.AssignLhs = {
40524071
qual match {
40534072
case MaybeGlobalScope.NotGlobalScope(qualTree) =>
40544073
js.JSSelect(qualTree, item)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ object JSConstructorGen {
2424
reportError: String => Unit)(
2525
implicit pos: Position): js.JSMethodDef = {
2626

27-
val js.JSMethodDef(_, dispatchName, dispatchArgs, dispatchResolution) =
27+
val js.JSMethodDef(_, dispatchName, dispatchArgs, dispatchRestParam, dispatchResolution) =
2828
dispatch
2929

3030
val jsConstructorBuilder = mkJSConstructorBuilder(ctors, reportError)
@@ -50,7 +50,7 @@ object JSConstructorGen {
5050
val newBody = js.Block(overloadSelection ::: prePrimaryCtorBody ::
5151
primaryCtorBody :: postPrimaryCtorBody :: js.Undefined() :: Nil)
5252

53-
js.JSMethodDef(js.MemberFlags.empty, dispatchName, dispatchArgs, newBody)(
53+
js.JSMethodDef(js.MemberFlags.empty, dispatchName, dispatchArgs, dispatchRestParam, newBody)(
5454
dispatch.optimizerHints, None)
5555
}
5656

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
390390
None
391391
} else {
392392
val formalArgsRegistry = new FormalArgsRegistry(1, false)
393-
val List(arg) = formalArgsRegistry.genFormalArgs()
393+
val (List(arg), None) = formalArgsRegistry.genFormalArgs()
394394
val body = genExportSameArgc(jsName, formalArgsRegistry, setters.map(Exported.apply), static, None)
395395
Some((arg, body))
396396
}
@@ -425,7 +425,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
425425
val formalArgsRegistry = new FormalArgsRegistry(minArgc, needsRestParam)
426426

427427
// Generate the list of formal parameters
428-
val formalArgs = formalArgsRegistry.genFormalArgs()
428+
val (formalArgs, restParam) = formalArgsRegistry.genFormalArgs()
429429

430430
/* Generate the body
431431
* We have a fast-path for methods that are not overloaded. In addition to
@@ -440,7 +440,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
440440
if (alts.tail.isEmpty) genApplyForSingleExported(formalArgsRegistry, alts.head, static)
441441
else genExportMethodMultiAlts(formalArgsRegistry, maxNonRepeatedArgc, alts, jsName, static)
442442

443-
js.JSMethodDef(flags, genExpr(jsName), formalArgs, body)(OptimizerHints.empty, None)
443+
js.JSMethodDef(flags, genExpr(jsName), formalArgs, restParam, body)(OptimizerHints.empty, None)
444444
}
445445

446446
private def genExportMethodMultiAlts(formalArgsRegistry: FormalArgsRegistry,
@@ -855,7 +855,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
855855
implicit val pos: Position = sym.span
856856
for ((name, info) <- namesAndInfosNow) yield {
857857
js.ParamDef(freshLocalIdent(name.mangledString), NoOriginalName, toIRType(info),
858-
mutable = false, rest = false)
858+
mutable = false)
859859
}
860860
}
861861

@@ -1047,18 +1047,19 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
10471047
if (needsRestParam) freshLocalIdent("rest")(NoPosition).name
10481048
else null
10491049

1050-
def genFormalArgs()(implicit pos: Position): List[js.ParamDef] = {
1050+
def genFormalArgs()(implicit pos: Position): (List[js.ParamDef], Option[js.ParamDef]) = {
10511051
val fixedParamDefs = fixedParamNames.toList.map { paramName =>
1052-
js.ParamDef(js.LocalIdent(paramName), NoOriginalName, jstpe.AnyType, mutable = false, rest = false)
1052+
js.ParamDef(js.LocalIdent(paramName), NoOriginalName, jstpe.AnyType, mutable = false)
10531053
}
10541054

1055-
if (needsRestParam) {
1056-
val restParamDef =
1057-
js.ParamDef(js.LocalIdent(restParamName), NoOriginalName, jstpe.AnyType, mutable = false, rest = true)
1058-
fixedParamDefs :+ restParamDef
1059-
} else {
1060-
fixedParamDefs
1055+
val restParam = {
1056+
if (needsRestParam)
1057+
Some(js.ParamDef(js.LocalIdent(restParamName), NoOriginalName, jstpe.AnyType, mutable = false))
1058+
else
1059+
None
10611060
}
1061+
1062+
(fixedParamDefs, restParam)
10621063
}
10631064

10641065
def genArgRef(index: Int)(implicit pos: Position): js.Tree = {

project/Build.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1115,7 +1115,9 @@ object Build {
11151115
++ (dir / "js/src/test/require-2.12" ** (("*.scala": FileFilter)
11161116
-- "JSOptionalTest212.scala" // TODO: Enable once we use a Scala.js with https://github.com/scala-js/scala-js/pull/4451 in
11171117
)).get
1118-
++ (dir / "js/src/test/require-sam" ** "*.scala").get
1118+
++ (dir / "js/src/test/require-sam" ** (("*.scala": FileFilter)
1119+
-- "CustomJSFunctionTest.scala" // TODO: Custom JS function types are not implemented yet
1120+
)).get
11191121
++ (dir / "js/src/test/scala-new-collections" ** "*.scala").get
11201122
)
11211123
},

project/plugins.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// e.g. addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.1.0")
44

5-
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.4.0")
5+
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.0")
66

77
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.6")
88

sbt-dotty/sbt-test/scala2-compat/erasure-scalajs/build.sbt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
lazy val scala2Lib = project.in(file("scala2Lib"))
22
.enablePlugins(ScalaJSPlugin)
33
.settings(
4-
// TODO: switch to 2.13.5 once we've upgrade sbt-scalajs to 1.5.0
5-
scalaVersion := "2.13.4"
4+
scalaVersion := "2.13.5"
65
)
76

87
lazy val dottyApp = project.in(file("dottyApp"))

0 commit comments

Comments
 (0)