File tree 5 files changed +65
-1
lines changed
compiler/src/dotty/tools/backend/sjs
5 files changed +65
-1
lines changed Original file line number Diff line number Diff line change @@ -3791,6 +3791,19 @@ class JSCodeGen()(using genCtx: Context) {
3791
3791
// BoxedUnit.UNIT, which is the boxed version of ()
3792
3792
js.Undefined ()
3793
3793
3794
+ case JS_NEW_TARGET =>
3795
+ // js.new.target
3796
+ val valid = currentMethodSym.get.isClassConstructor && currentClassSym.isNonNativeJSClass
3797
+ if (! valid) {
3798
+ report.error(
3799
+ " Illegal use of js.`new`.target.\n " +
3800
+ " It can only be used in the constructor of a JS class, " +
3801
+ " as a statement or in the rhs of a val or var.\n " +
3802
+ " It cannot be used inside a lambda or by-name parameter, nor in any other location." ,
3803
+ tree.sourcePos)
3804
+ }
3805
+ js.JSNewTarget ()
3806
+
3794
3807
case JS_IMPORT =>
3795
3808
// js.import(arg)
3796
3809
val arg = genArgs1
Original file line number Diff line number Diff line change @@ -145,6 +145,11 @@ final class JSDefinitions()(using Context) {
145
145
@ threadUnsafe lazy val JSConstructorTag_materializeR = JSConstructorTagModule .requiredMethodRef(" materialize" )
146
146
def JSConstructorTag_materialize (using Context ) = JSConstructorTag_materializeR .symbol
147
147
148
+ @ threadUnsafe lazy val JSNewModuleRef = requiredModuleRef(" scala.scalajs.js.new" )
149
+ def JSNewModule (using Context ) = JSNewModuleRef .symbol
150
+ @ threadUnsafe lazy val JSNew_targetR = JSNewModule .requiredMethodRef(" target" )
151
+ def JSNew_target (using Context ) = JSNew_targetR .symbol
152
+
148
153
@ threadUnsafe lazy val JSImportModuleRef = requiredModuleRef(" scala.scalajs.js.import" )
149
154
def JSImportModule (using Context ) = JSImportModuleRef .symbol
150
155
@ threadUnsafe lazy val JSImport_applyR = JSImportModule .requiredMethodRef(nme.apply)
Original file line number Diff line number Diff line change @@ -24,7 +24,9 @@ object JSPrimitives {
24
24
25
25
inline val UNITVAL = JS_NATIVE + 1 // () value, which is undefined
26
26
27
- inline val JS_IMPORT = UNITVAL + 1 // js.import.apply(specifier)
27
+ inline val JS_NEW_TARGET = UNITVAL + 1 // js.new.target
28
+
29
+ inline val JS_IMPORT = JS_NEW_TARGET + 1 // js.import.apply(specifier)
28
30
inline val JS_IMPORT_META = JS_IMPORT + 1 // js.import.meta
29
31
30
32
inline val CONSTRUCTOROF = JS_IMPORT_META + 1 // runtime.constructorOf(clazz)
@@ -105,6 +107,8 @@ class JSPrimitives(ictx: Context) extends DottyPrimitives(ictx) {
105
107
106
108
addPrimitive(defn.BoxedUnit_UNIT , UNITVAL )
107
109
110
+ addPrimitive(jsdefn.JSNew_target , JS_NEW_TARGET )
111
+
108
112
addPrimitive(jsdefn.JSImport_apply , JS_IMPORT )
109
113
addPrimitive(jsdefn.JSImport_meta , JS_IMPORT_META )
110
114
Original file line number Diff line number Diff line change @@ -1218,6 +1218,7 @@ object Build {
1218
1218
)).get
1219
1219
1220
1220
++ (dir / " js/src/test/require-2.12" ** " *.scala" ).get
1221
+ ++ (dir / " js/src/test/require-new-target" ** " *.scala" ).get
1221
1222
++ (dir / " js/src/test/require-sam" ** " *.scala" ).get
1222
1223
++ (dir / " js/src/test/scala-new-collections" ** " *.scala" ).get
1223
1224
++ (dir / " js/src/test/require-no-modules" ** " *.scala" ).get
Original file line number Diff line number Diff line change
1
+ import scala .scalajs .js
2
+ import scala .scalajs .js .annotation .*
3
+
4
+ object IllegalInScalaClass {
5
+ class A {
6
+ js.`new`.target // error: Illegal use of js.`new`.target.
7
+
8
+ def this (x : Int ) = {
9
+ this ()
10
+ js.`new`.target // error: Illegal use of js.`new`.target.
11
+ }
12
+ }
13
+
14
+ class B {
15
+ def foo (x : Int ): Unit =
16
+ js.`new`.target // error: Illegal use of js.`new`.target.
17
+ }
18
+
19
+ class C extends js.Object {
20
+ class D {
21
+ js.`new`.target // error: Illegal use of js.`new`.target.
22
+ }
23
+ }
24
+ }
25
+
26
+ object IllegalInDefOrLazyVal {
27
+ class A extends js.Object {
28
+ lazy val x = js.`new`.target // error: Illegal use of js.`new`.target.
29
+ def y : js.Dynamic = js.`new`.target // error: Illegal use of js.`new`.target.
30
+ def z (x : Int ): Any = js.`new`.target // error: Illegal use of js.`new`.target.
31
+ }
32
+ }
33
+
34
+ object IllegalInLambdaOrByName {
35
+ class A extends js.Object {
36
+ val x = () => js.`new`.target // error: Illegal use of js.`new`.target.
37
+ val y = Option (null ).getOrElse(js.`new`.target) // error: Illegal use of js.`new`.target.
38
+ val z : js.Function1 [Int , Any ] = (x : Int ) => js.`new`.target // error: Illegal use of js.`new`.target.
39
+ val w : js.ThisFunction0 [Any , Any ] = (x : Any ) => js.`new`.target // error: Illegal use of js.`new`.target.
40
+ }
41
+ }
You can’t perform that action at this time.
0 commit comments