diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/translate/utils/AnnotationsUtils.java b/js/js.frontend/src/org/jetbrains/kotlin/js/translate/utils/AnnotationsUtils.java index 76fc4612d61..c03e7cedd27 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/translate/utils/AnnotationsUtils.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/translate/utils/AnnotationsUtils.java @@ -83,18 +83,24 @@ public final class AnnotationsUtils { @Nullable public static String getNameForAnnotatedObject(@NotNull DeclarationDescriptor descriptor) { + String defaultJsName = getJsName(descriptor); + for (PredefinedAnnotation annotation : PredefinedAnnotation.Companion.getWITH_CUSTOM_NAME()) { if (!hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) { continue; } String name = getNameForAnnotatedObject(descriptor, annotation); if (name == null) { - name = getJsName(descriptor); + name = defaultJsName; } return name != null ? name : descriptor.getName().asString(); } - return getJsName(descriptor); + if (defaultJsName == null && isEffectivelyExternal(descriptor)) { + return descriptor.getName().asString(); + } + + return defaultJsName; } @Nullable @@ -112,7 +118,7 @@ public final class AnnotationsUtils { } public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) { - if (hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE)) return true; + if (hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE) || isEffectivelyExternal(descriptor)) return true; if (descriptor instanceof PropertyAccessorDescriptor) { PropertyAccessorDescriptor accessor = (PropertyAccessorDescriptor) descriptor; @@ -126,6 +132,13 @@ public final class AnnotationsUtils { return isNativeObject(descriptor) && DescriptorUtils.isInterface(descriptor); } + private static boolean isEffectivelyExternal(@NotNull DeclarationDescriptor descriptor) { + if (descriptor instanceof MemberDescriptor && ((MemberDescriptor) descriptor).isExternal()) return true; + + ClassDescriptor containingClass = DescriptorUtils.getContainingClass(descriptor); + return containingClass != null && isEffectivelyExternal(containingClass); + } + public static boolean isLibraryObject(@NotNull DeclarationDescriptor descriptor) { return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.LIBRARY); } @@ -151,6 +164,7 @@ public final class AnnotationsUtils { public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof MemberDescriptor && ((MemberDescriptor) descriptor).isPlatform()) return true; + if (isEffectivelyExternal(descriptor)) return true; for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) { if (hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) { diff --git a/js/js.libraries/src/core/annotations.kt b/js/js.libraries/src/core/annotations.kt index e75476fccc6..b3dc29f57db 100644 --- a/js/js.libraries/src/core/annotations.kt +++ b/js/js.libraries/src/core/annotations.kt @@ -20,18 +20,22 @@ import kotlin.annotation.AnnotationTarget.* @native @Target(CLASS, FUNCTION, PROPERTY, CONSTRUCTOR, VALUE_PARAMETER, PROPERTY_GETTER, PROPERTY_SETTER) +@Deprecated("Use `external` modifier instead") public annotation class native(@Deprecated public val name: String = "") @native @Target(FUNCTION) +@Deprecated public annotation class nativeGetter @native @Target(FUNCTION) +@Deprecated public annotation class nativeSetter @native @Target(FUNCTION) +@Deprecated public annotation class nativeInvoke @native diff --git a/js/js.libraries/src/core/concurrent.kt b/js/js.libraries/src/core/concurrent.kt index 2641683f84d..5ca28f1d680 100644 --- a/js/js.libraries/src/core/concurrent.kt +++ b/js/js.libraries/src/core/concurrent.kt @@ -22,12 +22,15 @@ package kotlin // so they annotated as 'native' to avoid warnings/errors from some minifiers. // They was reserved word in ECMAScript 2, but is not since ECMAScript 5. -@native +// Additional note: +// Although it's reasonable to mark these annotations as `@native` (`external` since 1.1), +// we prohibit marking annotations this way. +// TODO: Another workaround is required to remove these annotations from kotlin.js + @Target(AnnotationTarget.PROPERTY, AnnotationTarget.FIELD) @Retention(AnnotationRetention.SOURCE) public annotation class Volatile -@native @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) @Retention(AnnotationRetention.SOURCE) public annotation class Synchronized