@@ -302,8 +302,10 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
302
302
super .transform(tree)
303
303
304
304
case _ : Export =>
305
- if anyEnclosingOwner is OwnerKind .JSNative then
305
+ if enclosingOwner is OwnerKind .JSNative then
306
306
report.error(" Native JS traits, classes and objects cannot contain exported definitions." , tree)
307
+ else if enclosingOwner is OwnerKind .JSTrait then
308
+ report.error(" Non-native JS traits cannot contain exported definitions." , tree)
307
309
308
310
super .transform(tree)
309
311
@@ -465,7 +467,8 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
465
467
val kind = {
466
468
if (! isJSNative) {
467
469
if (sym.is(ModuleClass )) OwnerKind .JSMod
468
- else OwnerKind .JSClass
470
+ else if (sym.is(Trait )) OwnerKind .JSTrait
471
+ else OwnerKind .JSNonTraitClass
469
472
} else {
470
473
if (sym.is(ModuleClass )) OwnerKind .JSNativeMod
471
474
else OwnerKind .JSNativeClass
@@ -825,38 +828,38 @@ class PrepJSInterop extends MacroTransform with IdentityDenotTransformer { thisP
825
828
/** Removes annotations from exported definitions (e.g. `export foo.bar`):
826
829
* - `js.native`
827
830
* - `js.annotation.*`
828
- * - `js.annotation.internal.*`
829
831
*/
830
832
private def stripJSAnnotsOnExported (sym : Symbol )(using Context ): Unit =
831
833
if ! sym.is(Exported ) then return
832
834
833
835
val JSNativeAnnot = jsdefn.JSNativeAnnot
834
836
val JSAnnotPackage = jsdefn.JSAnnotPackage
835
- val JSAnnotInternalPackage = jsdefn.JSAnnotInternalPackage
836
837
837
838
extension (sym : Symbol ) def isJSAnnot =
838
- (sym eq JSNativeAnnot ) || (sym.owner eq JSAnnotPackage ) || (sym.owner eq JSAnnotInternalPackage )
839
+ (sym eq JSNativeAnnot ) || (sym.owner eq JSAnnotPackage )
839
840
840
841
val newAnnots = sym.annotations.filterConserve(! _.symbol.isJSAnnot)
841
842
if newAnnots ne sym.annotations then
842
843
sym.annotations = newAnnots
843
844
end stripJSAnnotsOnExported
844
845
845
846
private def checkRHSCallsJSNative (tree : ValOrDefDef , longKindStr : String )(using Context ): Unit = {
846
- if ! tree.symbol.is(Exported ) then
847
- // Check that the rhs is exactly `= js.native`
848
- tree.rhs match {
849
- case sel : Select if sel.symbol == jsdefn.JSPackage_native =>
850
- // ok
851
- case _ =>
852
- val pos = if (tree.rhs != EmptyTree ) tree.rhs.srcPos else tree.srcPos
853
- report.error(s " $longKindStr may only call js.native. " , pos)
854
- }
847
+ if tree.symbol.is(Exported ) then
848
+ return // we already report an error that exports are not allowed here, this prevents extra errors.
849
+
850
+ // Check that the rhs is exactly `= js.native`
851
+ tree.rhs match {
852
+ case sel : Select if sel.symbol == jsdefn.JSPackage_native =>
853
+ // ok
854
+ case _ =>
855
+ val pos = if (tree.rhs != EmptyTree ) tree.rhs.srcPos else tree.srcPos
856
+ report.error(s " $longKindStr may only call js.native. " , pos)
857
+ }
855
858
856
- // Check that the resul type was explicitly specified
857
- // (This is stronger than Scala 2, which only warns, and only if it was inferred as Nothing.)
858
- if (tree.tpt.span.isSynthetic)
859
- report.error(i " The type of ${tree.name} must be explicitly specified because it is JS native. " , tree)
859
+ // Check that the resul type was explicitly specified
860
+ // (This is stronger than Scala 2, which only warns, and only if it was inferred as Nothing.)
861
+ if (tree.tpt.span.isSynthetic)
862
+ report.error(i " The type of ${tree.name} must be explicitly specified because it is JS native. " , tree)
860
863
}
861
864
862
865
private def checkJSNativeSpecificAnnotsOnNonJSNative (memberDef : MemberDef )(using Context ): Unit = {
@@ -1021,10 +1024,12 @@ object PrepJSInterop {
1021
1024
val JSNativeClass = new OwnerKind (0x04 )
1022
1025
/** A native JS object, which extends js.Any. */
1023
1026
val JSNativeMod = new OwnerKind (0x08 )
1024
- /** A non-native JS class/trait. */
1025
- val JSClass = new OwnerKind (0x10 )
1027
+ /** A non-native JS class (not a trait). */
1028
+ val JSNonTraitClass = new OwnerKind (0x10 )
1029
+ /** A non-native JS trait. */
1030
+ val JSTrait = new OwnerKind (0x20 )
1026
1031
/** A non-native JS object. */
1027
- val JSMod = new OwnerKind (0x20 )
1032
+ val JSMod = new OwnerKind (0x40 )
1028
1033
1029
1034
// Compound kinds
1030
1035
@@ -1034,12 +1039,12 @@ object PrepJSInterop {
1034
1039
/** A native JS class/trait/object. */
1035
1040
val JSNative = JSNativeClass | JSNativeMod
1036
1041
/** A non-native JS class/trait/object. */
1037
- val JSNonNative = JSClass | JSMod
1042
+ val JSNonNative = JSNonTraitClass | JSTrait | JSMod
1038
1043
/** A JS type, i.e., something extending js.Any. */
1039
1044
val JSType = JSNative | JSNonNative
1040
1045
1041
1046
/** Any kind of class/trait, i.e., a Scala or JS class/trait. */
1042
- val AnyClass = ScalaClass | JSNativeClass | JSClass
1047
+ val AnyClass = ScalaClass | JSNativeClass | JSNonTraitClass | JSTrait
1043
1048
}
1044
1049
1045
1050
/** Tests if the symbol extend `js.Any`.
0 commit comments