diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt index 38f6b27c4f4..84bec0d5b76 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/annotations/symbolAnnotationsUtils.kt @@ -83,6 +83,8 @@ internal fun KtAnnotatedSymbol.hasDeprecatedAnnotation( internal fun KtAnnotatedSymbol.hasJvmOverloadsAnnotation(): Boolean = hasAnnotation(JVM_OVERLOADS_CLASS_ID) +internal fun KtAnnotatedSymbol.hasJvmNameAnnotation(): Boolean = hasAnnotation(JvmStandardClassIds.Annotations.JvmName) + internal fun KtAnnotatedSymbol.hasJvmStaticAnnotation( useSiteTargetFilter: AnnotationUseSiteTargetFilter = AnyAnnotationUseSiteTargetFilter, ): Boolean = hasAnnotation(JvmStandardClassIds.Annotations.JvmStatic, useSiteTargetFilter) diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt index 905fc362da2..494c3e820aa 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt @@ -37,6 +37,7 @@ import org.jetbrains.kotlin.config.JvmDefaultMode import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.lexer.KtTokens.* +import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmNameAnnotation import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmOverloadsAnnotation import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmStaticAnnotation import org.jetbrains.kotlin.light.classes.symbol.annotations.isHiddenOrSynthetic @@ -325,28 +326,34 @@ internal fun SymbolLightClassBase.createPropertyAccessors( } if (declaration.isJvmField) return - val propertyTypeIsValueClass = declaration.hasTypeForValueClassInSignature() - - /* - * For top-level properties with value class in return type compiler mangles only setter - * - * @JvmInline - * value class Some(val value: String) - * - * var topLevelProp: Some = Some("1") - * - * Compiles to - * public final class FooKt { - * public final static getTopLevelProp()Ljava/lang/String; - * - * public final static setTopLevelProp-5lyY9Q4(Ljava/lang/String;)V - * - * private static Ljava/lang/String; topLevelProp - * } - */ - if (this !is SymbolLightClassForFacade && propertyTypeIsValueClass) return + val propertyTypeIsValueClass = declaration.hasTypeForValueClassInSignature(suppressJvmNameCheck = true) fun KtPropertyAccessorSymbol.needToCreateAccessor(siteTarget: AnnotationUseSiteTarget): Boolean { + when { + !propertyTypeIsValueClass -> {} + /* + * For top-level properties with value class in return type compiler mangles only setter + * + * @JvmInline + * value class Some(val value: String) + * + * var topLevelProp: Some = Some("1") + * + * Compiles to + * public final class FooKt { + * public final static getTopLevelProp()Ljava/lang/String; + * + * public final static setTopLevelProp-5lyY9Q4(Ljava/lang/String;)V + * + * private static Ljava/lang/String; topLevelProp + * } + */ + this is KtPropertyGetterSymbol && this@createPropertyAccessors is SymbolLightClassForFacade -> {} + // Accessors with JvmName can be accessible from Java + hasJvmNameAnnotation() -> {} + else -> return false + } + val useSiteTargetFilterForPropertyAccessor = siteTarget.toOptionalFilter() if (onlyJvmStatic && !hasJvmStaticAnnotation(useSiteTargetFilterForPropertyAccessor) && @@ -388,7 +395,7 @@ internal fun SymbolLightClassBase.createPropertyAccessors( } val setter = declaration.setter?.takeIf { - !isAnnotationType && it.needToCreateAccessor(AnnotationUseSiteTarget.PROPERTY_SETTER) && !propertyTypeIsValueClass + !isAnnotationType && it.needToCreateAccessor(AnnotationUseSiteTarget.PROPERTY_SETTER) } if (isMutable && setter != null) { @@ -651,8 +658,23 @@ internal fun SymbolLightClassBase.addPropertyBackingFields( memberProperties.forEach(::addPropertyBackingField) } +/** + * @param suppressJvmNameCheck **true** if [hasJvmNameAnnotation] should be omitted. + * E.g., if [JvmName] is checked manually later + */ context(KtAnalysisSession) -internal fun KtCallableSymbol.hasTypeForValueClassInSignature(ignoreReturnType: Boolean = false): Boolean { +internal fun KtCallableSymbol.hasTypeForValueClassInSignature( + ignoreReturnType: Boolean = false, + suppressJvmNameCheck: Boolean = false, +): Boolean { + // Declarations with JvmName can be accessible from Java + when { + suppressJvmNameCheck -> {} + hasJvmNameAnnotation() -> return false + this !is KtKotlinPropertySymbol -> {} + getter?.hasJvmNameAnnotation() == true || setter?.hasJvmNameAnnotation() == true -> return false + } + if (!ignoreReturnType) { val psiDeclaration = sourcePsiSafe() if (psiDeclaration?.typeReference != null && returnType.typeForValueClass) return true diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/ValueClassInParametersWithJvmName.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/ValueClassInParametersWithJvmName.java index 4c59bf19c19..dc799ee07b1 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByFqName/ValueClassInParametersWithJvmName.java +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/ValueClassInParametersWithJvmName.java @@ -11,5 +11,22 @@ public final class UTypeDeclarationClass /* one.UTypeDeclarationClass*/ { @org.jetbrains.annotations.NotNull() private java.lang.String setterAndGetter; + @kotlin.jvm.JvmName(name = "_methodWithJvmName") + public final void _methodWithJvmName(@org.jetbrains.annotations.NotNull() java.lang.String);// _methodWithJvmName(java.lang.String) + + @kotlin.jvm.JvmName(name = "get_getter") + @org.jetbrains.annotations.NotNull() + public final java.lang.String get_getter();// get_getter() + + @kotlin.jvm.JvmName(name = "get_setterAndGetter") + @org.jetbrains.annotations.NotNull() + public final java.lang.String get_setterAndGetter();// get_setterAndGetter() + + @kotlin.jvm.JvmName(name = "set_setter") + public final void set_setter(@org.jetbrains.annotations.NotNull() java.lang.String);// set_setter(java.lang.String) + + @kotlin.jvm.JvmName(name = "set_setterAndGetter") + public final void set_setterAndGetter(@org.jetbrains.annotations.NotNull() java.lang.String);// set_setterAndGetter(java.lang.String) + public UTypeDeclarationClass();// .ctor() } diff --git a/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/ValueClassInParametersWithJvmName.java b/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/ValueClassInParametersWithJvmName.java index 971972a096c..85dc2ee6b4d 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/ValueClassInParametersWithJvmName.java +++ b/compiler/testData/asJava/lightClasses/lightClassByFqName/facades/ValueClassInParametersWithJvmName.java @@ -11,6 +11,9 @@ public final class ValueClassInParametersWithJvmNameKt /* one.ValueClassInParame @org.jetbrains.annotations.NotNull() private static java.lang.String setterAndGetter; + @kotlin.jvm.JvmName(name = "_methodWithJvmName") + public static final void _methodWithJvmName(@org.jetbrains.annotations.NotNull() java.lang.String);// _methodWithJvmName(java.lang.String) + @kotlin.jvm.JvmName(name = "get_getter") @org.jetbrains.annotations.NotNull() public static final java.lang.String get_getter();// get_getter() @@ -19,6 +22,12 @@ public final class ValueClassInParametersWithJvmNameKt /* one.ValueClassInParame @org.jetbrains.annotations.NotNull() public static final java.lang.String get_setterAndGetter();// get_setterAndGetter() + @kotlin.jvm.JvmName(name = "set_setter") + public static final void set_setter(@org.jetbrains.annotations.NotNull() java.lang.String);// set_setter(java.lang.String) + + @kotlin.jvm.JvmName(name = "set_setterAndGetter") + public static final void set_setterAndGetter(@org.jetbrains.annotations.NotNull() java.lang.String);// set_setterAndGetter(java.lang.String) + @org.jetbrains.annotations.NotNull() public static final java.lang.String getNothing();// getNothing()