File tree Expand file tree Collapse file tree 5 files changed +65
-1
lines changed
compiler/src/dotty/tools/backend/sjs Expand file tree Collapse file tree 5 files changed +65
-1
lines changed Original file line number Diff line number Diff line change @@ -3840,6 +3840,19 @@ class JSCodeGen()(using genCtx: Context) {
38403840 // BoxedUnit.UNIT, which is the boxed version of ()
38413841 js.Undefined ()
38423842
3843+ case JS_NEW_TARGET =>
3844+ // js.new.target
3845+ val valid = currentMethodSym.get.isClassConstructor && currentClassSym.isNonNativeJSClass
3846+ if (! valid) {
3847+ report.error(
3848+ " Illegal use of js.`new`.target.\n " +
3849+ " It can only be used in the constructor of a JS class, " +
3850+ " as a statement or in the rhs of a val or var.\n " +
3851+ " It cannot be used inside a lambda or by-name parameter, nor in any other location." ,
3852+ tree.sourcePos)
3853+ }
3854+ js.JSNewTarget ()
3855+
38433856 case JS_IMPORT =>
38443857 // js.import(arg)
38453858 val arg = genArgs1
Original file line number Diff line number Diff line change @@ -147,6 +147,11 @@ final class JSDefinitions()(using Context) {
147147 @ threadUnsafe lazy val JSConstructorTag_materializeR = JSConstructorTagModule .requiredMethodRef(" materialize" )
148148 def JSConstructorTag_materialize (using Context ) = JSConstructorTag_materializeR .symbol
149149
150+ @ threadUnsafe lazy val JSNewModuleRef = requiredModuleRef(" scala.scalajs.js.new" )
151+ def JSNewModule (using Context ) = JSNewModuleRef .symbol
152+ @ threadUnsafe lazy val JSNew_targetR = JSNewModule .requiredMethodRef(" target" )
153+ def JSNew_target (using Context ) = JSNew_targetR .symbol
154+
150155 @ threadUnsafe lazy val JSImportModuleRef = requiredModuleRef(" scala.scalajs.js.import" )
151156 def JSImportModule (using Context ) = JSImportModuleRef .symbol
152157 @ 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 {
2424
2525 inline val UNITVAL = JS_NATIVE + 1 // () value, which is undefined
2626
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)
2830 inline val JS_IMPORT_META = JS_IMPORT + 1 // js.import.meta
2931
3032 inline val CONSTRUCTOROF = JS_IMPORT_META + 1 // runtime.constructorOf(clazz)
@@ -106,6 +108,8 @@ class JSPrimitives(ictx: Context) extends DottyPrimitives(ictx) {
106108
107109 addPrimitive(defn.BoxedUnit_UNIT , UNITVAL )
108110
111+ addPrimitive(jsdefn.JSNew_target , JS_NEW_TARGET )
112+
109113 addPrimitive(jsdefn.JSImport_apply , JS_IMPORT )
110114 addPrimitive(jsdefn.JSImport_meta , JS_IMPORT_META )
111115
Original file line number Diff line number Diff line change @@ -1254,6 +1254,7 @@ object Build {
12541254 )).get
12551255
12561256 ++ (dir / " js/src/test/require-2.12" ** " *.scala" ).get
1257+ ++ (dir / " js/src/test/require-new-target" ** " *.scala" ).get
12571258 ++ (dir / " js/src/test/require-sam" ** " *.scala" ).get
12581259 ++ (dir / " js/src/test/scala-new-collections" ** " *.scala" ).get
12591260
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