@@ -167,7 +167,7 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
167
167
else if (enclosingOwner is OwnerKind .JSType )
168
168
transformValOrDefDefInJSType(tree)
169
169
else
170
- transformScalaValOrDefDef (tree)
170
+ super .transform (tree) // There is nothing special to do for a Scala val or def
171
171
}
172
172
}
173
173
@@ -198,11 +198,6 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
198
198
}
199
199
}
200
200
201
- private def transformScalaValOrDefDef (tree : ValOrDefDef )(using Context ): Tree = {
202
- // There is nothing special to do for a Scala val or def
203
- super .transform(tree)
204
- }
205
-
206
201
private def transformTemplate (tree : Template )(using Context ): Template = {
207
202
// First, recursively transform the template
208
203
val transformedTree = super .transform(tree).asInstanceOf [Template ]
@@ -245,23 +240,6 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
245
240
246
241
private def transformStatOrExpr (tree : Tree )(using Context ): Tree = {
247
242
tree match {
248
- /* This might not be needed in dotty.
249
- /* Anonymous function, need to check that it is not used as a SAM for a
250
- * JS type, unless it is js.FunctionN or js.ThisFunctionN.
251
- * See #2921.
252
- */
253
- case tree: Function =>
254
- val tpeSym = tree.tpe.typeSymbol
255
- if (isJSAny(tpeSym) && !AllJSFunctionClasses.contains(tpeSym)) {
256
- report.error(
257
- "Using an anonymous function as a SAM for the JavaScript " +
258
- "type " + tpeSym.fullNameString + " is not allowed. " +
259
- "Use an anonymous class instead.",
260
- tree)
261
- }
262
- super.transform(tree)
263
- */
264
-
265
243
// Validate js.constructorOf[T]
266
244
case TypeApply (ctorOfTree, List (tpeArg))
267
245
if ctorOfTree.symbol == jsdefn.JSPackage_constructorOf =>
@@ -310,50 +288,13 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
310
288
}
311
289
}
312
290
313
- /** Performs checks and rewrites specific to classes / objects extending
314
- * js.Any.
315
- */
291
+ /** Performs checks and rewrites specific to classes / objects extending `js.Any`. */
316
292
private def transformJSClassDef (classDef : TypeDef )(using Context ): Tree = {
317
293
val sym = classDef.symbol
294
+ val isJSNative = sym.hasAnnotation(jsdefn.JSNativeAnnot )
318
295
319
296
sym.addAnnotation(jsdefn.JSTypeAnnot )
320
297
321
- /* val isJSLambda =
322
- sym.isAnonymousClass && AllJSFunctionClasses.exists(sym.isSubClass(_))
323
- if (isJSLambda)
324
- transformJSLambdaClassDef(classDef)
325
- else*/
326
- transformNonLambdaJSClassDef(classDef)
327
- }
328
-
329
- /*
330
- /** Performs checks and rewrites specific to JS lambdas, i.e., anonymous
331
- * classes extending one of the JS function types.
332
- *
333
- * JS lambdas are special because they are completely hijacked by the
334
- * back-end, so although at this phase they look like normal anonymous
335
- * classes, they do not behave like ones.
336
- */
337
- private def transformJSLambdaClassDef(classDef: TypeDef)(using Context): Tree = {
338
- /* For the purposes of checking inner members, a JS lambda acts as a JS
339
- * native class owner.
340
- *
341
- * TODO This is probably not right, but historically it has always been
342
- * that way. It should be revisited.
343
- */
344
- enterOwner(OwnerKind.JSNativeClass) {
345
- super.transform(classDef)
346
- }
347
- }
348
- */
349
-
350
- /** Performs checks and rewrites for all JS classes, traits and objects
351
- * except JS lambdas.
352
- */
353
- private def transformNonLambdaJSClassDef (classDef : TypeDef )(using Context ): Tree = {
354
- val sym = classDef.symbol
355
- val isJSNative = sym.hasAnnotation(jsdefn.JSNativeAnnot )
356
-
357
298
// Forbid @EnableReflectiveInstantiation on JS types
358
299
sym.getAnnotation(jsdefn.EnableReflectiveInstantiationAnnot ).foreach { annot =>
359
300
report.error(
@@ -393,7 +334,7 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
393
334
case parentSym if parentSym == defn.DynamicClass =>
394
335
/* We have to allow scala.Dynamic to be able to define js.Dynamic
395
336
* and similar constructs.
396
- * This causes the unsoundness filed as #1385.
337
+ * This causes the unsoundness filed as scala-js/scala-js #1385.
397
338
*/
398
339
case parentSym =>
399
340
/* This is a Scala class or trait other than AnyRef and Dynamic,
@@ -466,7 +407,7 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
466
407
errorPos)
467
408
}
468
409
469
- // Check for overrides with different JS names - issue #1983
410
+ // Check for overrides with different JS names - issue scala-js/scala-js #1983
470
411
if (overriding.jsName != overridden.jsName)
471
412
emitOverrideError(" has a different JS name" )
472
413
@@ -562,20 +503,19 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
562
503
case JSName .Literal (jsName) =>
563
504
checkGlobalRefName(jsName)
564
505
case JSName .Computed (_) =>
565
- () // compile error above
506
+ () // compile error above or in `checkJSNameArgument`
566
507
}
567
508
}
568
509
}
569
510
} else {
570
- def firstElementOfPath (pathName : String ): String = {
511
+ def checkGlobalRefPath (pathName : String ): Unit = {
571
512
val dotIndex = pathName.indexOf('.' )
572
- if (dotIndex < 0 ) pathName
573
- else pathName.substring(0 , dotIndex)
513
+ val globalRef =
514
+ if (dotIndex < 0 ) pathName
515
+ else pathName.substring(0 , dotIndex)
516
+ checkGlobalRefName(globalRef)
574
517
}
575
518
576
- def checkGlobalRefPath (pathName : String ): Unit =
577
- checkGlobalRefName(firstElementOfPath(pathName))
578
-
579
519
checkAndGetJSNativeLoadingSpecAnnotOf(pos, sym) match {
580
520
case Some (annot) if annot.symbol == jsdefn.JSGlobalScopeAnnot =>
581
521
if (! sym.is(Module )) {
@@ -657,15 +597,17 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
657
597
}
658
598
659
599
case nme.equals_ if sym.info.matches(defn.Any_equals .info) =>
660
- report.warning(
661
- " Overriding equals in a JS class does not change how it is compared. " +
662
- " To silence this warning, change the name of the method and optionally add @JSName(\" equals\" )." ,
600
+ report.error(
601
+ " error overriding method equals(that: Any): Boolean in a JS class;\n " +
602
+ " method equals(that: Any): Boolean is considered final in trait js.Any;\n " +
603
+ " if you want to define a method named \" equals\" in JavaScript, use a different name and add @JSName(\" equals\" )." ,
663
604
sym)
664
605
665
606
case nme.hashCode_ if sym.info.matches(defn.Any_hashCode .info) =>
666
- report.warning(
667
- " Overriding hashCode in a JS class does not change its hash code. " +
668
- " To silence this warning, change the name of the method and optionally add @JSName(\" hashCode\" )." ,
607
+ report.error(
608
+ " error overriding method hashCode(): Int in a JS class;\n " +
609
+ " method hashCode(): Int is considered final in trait js.Any;\n " +
610
+ " if you want to define a method named \" hashCode\" in JavaScript, use a different name and add @JSName(\" hashCode\" )." ,
669
611
sym)
670
612
671
613
case _ =>
@@ -907,7 +849,7 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
907
849
// it is not private
908
850
! isPrivateMaybeWithin(sym) &&
909
851
// it is not a constructor
910
- ! sym.isConstructor // && !sym.isValueParameter && !sym.isParamWithDefault
852
+ ! sym.isConstructor
911
853
}
912
854
913
855
if (shouldBeExposed)
@@ -971,6 +913,11 @@ object PrepJSInterop {
971
913
val AnyClass = ScalaClass | JSNativeClass | JSClass
972
914
}
973
915
916
+ /** Tests if the symbol extend `js.Any`.
917
+ *
918
+ * This is different from `sym.isJSType` because it returns `false` for the
919
+ * pseudo-union type.
920
+ */
974
921
def isJSAny (sym : Symbol )(using Context ): Boolean =
975
922
sym.isSubClass(jsdefn.JSAnyClass )
976
923
0 commit comments