From dcfa08de6aad511e3b6790cc03ad53322114ea11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 26 Jan 2024 09:28:39 +0100 Subject: [PATCH] Fix #19528: Actually remove Dynamic from interfaces of native JS classes. One boolean value was the wrong way around for native JS classes and traits. That caused `scala.Dynamic` not to be removed from the super-interfaces of native JS classes at the IR level, causing the linking error. (cherry picked from commit 59ebb8565dc829a1d4e32f74db5e8c2b67d37219) --- .../dotty/tools/backend/sjs/JSCodeGen.scala | 2 +- .../jsinterop/CustomDynamicTestScala3.scala | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/sjs-junit/test/org/scalajs/testsuite/jsinterop/CustomDynamicTestScala3.scala diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index eee791852fde..ea3ea9d50cf7 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -642,7 +642,7 @@ class JSCodeGen()(using genCtx: Context) { kind, None, superClass, - genClassInterfaces(sym, forJSClass = false), + genClassInterfaces(sym, forJSClass = true), None, jsNativeLoadSpec, Nil, diff --git a/tests/sjs-junit/test/org/scalajs/testsuite/jsinterop/CustomDynamicTestScala3.scala b/tests/sjs-junit/test/org/scalajs/testsuite/jsinterop/CustomDynamicTestScala3.scala new file mode 100644 index 000000000000..45e3b8a405c7 --- /dev/null +++ b/tests/sjs-junit/test/org/scalajs/testsuite/jsinterop/CustomDynamicTestScala3.scala @@ -0,0 +1,58 @@ +package org.scalajs.testsuite.jsinterop + +import scala.language.dynamics + +import org.junit.Assert.* +import org.junit.Test + +import scala.scalajs.js +import scala.scalajs.js.annotation.* + +class CustomDynamicTestScala3 { + import CustomDynamicTestScala3.* + + @Test + def testCustomDynamicClass_Issue19528(): Unit = { + val obj = new CustomDynamicClass() + + assertEquals(false, obj.hasOwnProperty("foo")) + obj.foo = "bar" + assertEquals("bar", obj.foo) + assertEquals(true, obj.hasOwnProperty("foo")) + } + + @Test + def testCustomDynamicTrait_Issue19528(): Unit = { + val obj = new js.Object().asInstanceOf[CustomDynamicTrait] + + assertEquals(false, obj.hasOwnProperty("foo")) + obj.foo = "bar" + assertEquals("bar", obj.foo) + assertEquals(true, obj.hasOwnProperty("foo")) + } +} + +object CustomDynamicTestScala3 { + @js.native + @JSGlobal("Object") + class CustomDynamicClass extends js.Any with Dynamic { + @JSBracketAccess + def selectDynamic(name: String): js.Any = js.native + @JSBracketAccess + def updateDynamic(name: String)(value: js.Any): Unit = js.native + + @JSBracketCall + def applyDynamic(name: String)(args: js.Any*): js.Any = js.native + } + + @js.native + trait CustomDynamicTrait extends js.Any with Dynamic { + @JSBracketAccess + def selectDynamic(name: String): js.Any = js.native + @JSBracketAccess + def updateDynamic(name: String)(value: js.Any): Unit = js.native + + @JSBracketCall + def applyDynamic(name: String)(args: js.Any*): js.Any = js.native + } +}