Skip to content

Commit a1cdfe9

Browse files
committed
Fix #11592: Scala.js: Handle default params of native JS classes.
They must not be emitted, just like regular methods inside native JS classes are not emitted. This ensures that if the default value is `= js.native`, it is not emitted, and therefore does not report an error tha calling `js.native` is illegal in non-native code.
1 parent d15df36 commit a1cdfe9

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

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

+11-11
Original file line numberDiff line numberDiff line change
@@ -290,12 +290,12 @@ class JSCodeGen()(using genCtx: Context) {
290290
"genScalaClass() must be called only for normal classes: "+sym)
291291
assert(sym.superClass != NoSymbol, sym)
292292

293-
/*if (hasDefaultCtorArgsAndRawJSModule(sym)) {
294-
reporter.error(pos,
295-
"Implementation restriction: constructors of " +
296-
"Scala classes cannot have default parameters " +
297-
"if their companion module is JS native.")
298-
}*/
293+
if (hasDefaultCtorArgsAndJSModule(sym)) {
294+
report.error(
295+
"Implementation restriction: " +
296+
"constructors of Scala classes cannot have default parameters if their companion module is JS native.",
297+
td)
298+
}
299299

300300
val classIdent = encodeClassNameIdent(sym)
301301
val originalName = originalNameOfClass(sym)
@@ -965,9 +965,8 @@ class JSCodeGen()(using genCtx: Context) {
965965

966966
if (hasDefaultCtorArgsAndJSModule(classSym)) {
967967
report.error(
968-
"Implementation restriction: constructors of " +
969-
"non-native JS classes cannot have default parameters " +
970-
"if their companion module is JS native.",
968+
"Implementation restriction: " +
969+
"constructors of non-native JS classes cannot have default parameters if their companion module is JS native.",
971970
classSym.srcPos)
972971
val ctorDef = js.JSMethodDef(js.MemberFlags.empty,
973972
js.StringLiteral("constructor"), Nil, None, js.Skip())(
@@ -1067,9 +1066,10 @@ class JSCodeGen()(using genCtx: Context) {
10671066
Some(js.MethodDef(js.MemberFlags.empty, methodName, originalName,
10681067
jsParams, toIRType(patchedResultType(sym)), None)(
10691068
OptimizerHints.empty, None))
1070-
} else /*if (isJSNativeCtorDefaultParam(sym)) {
1069+
} else if (sym.isJSNativeCtorDefaultParam) {
1070+
// #11592
10711071
None
1072-
} else if (sym.isClassConstructor && isHijackedBoxedClass(sym.owner)) {
1072+
} else /*if (sym.isClassConstructor && isHijackedBoxedClass(sym.owner)) {
10731073
None
10741074
} else*/ {
10751075
/*def isTraitImplForwarder = dd.rhs match {

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

+7
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ object JSSymUtils {
158158
}
159159
}
160160

161+
/** Is this symbol a default param accessor for the constructor of a native JS class? */
162+
def isJSNativeCtorDefaultParam(using Context): Boolean = {
163+
sym.name.is(DefaultGetterName)
164+
&& sym.name.exclude(DefaultGetterName) == nme.CONSTRUCTOR
165+
&& sym.owner.linkedClass.hasAnnotation(jsdefn.JSNativeAnnot)
166+
}
167+
161168
def jsCallingConvention(using Context): JSCallingConvention =
162169
JSCallingConvention.of(sym)
163170

tests/sjs-junit/test/org/scalajs/testsuite/compiler/RegressionTestScala3.scala

+12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import org.junit.Assert.*
44
import org.junit.Test
55

66
import scala.scalajs.js
7+
import scala.scalajs.js.annotation._
78

89
class RegressionTestScala3 {
910
import RegressionTestScala3.*
@@ -21,6 +22,11 @@ class RegressionTestScala3 {
2122
assertEquals(-1, obj2.y)
2223
assertEquals(4, obj2.foo(5))
2324
}
25+
26+
@Test def testJSNativeDefaultCtorParamIssue11592(): Unit = {
27+
assertEquals("foo", new RangeErrorIssue11592("foo").message)
28+
assertEquals("", new RangeErrorIssue11592().message)
29+
}
2430
}
2531

2632
object RegressionTestScala3 {
@@ -33,6 +39,12 @@ object RegressionTestScala3 {
3339

3440
def foo(x: Int): Int = new ChildClass().concreteMethod(x)
3541
}
42+
43+
@js.native
44+
@JSGlobal("RangeError")
45+
class RangeErrorIssue11592(msg: String = js.native) extends js.Object {
46+
val message: String = js.native
47+
}
3648
}
3749

3850
// This class needs to be at the top-level, not in an object, to reproduce the issue

0 commit comments

Comments
 (0)