[SLC] generate light classes for functions with JvmName and value class as parameter

Such functions/accessors have not-mangled names, so they can be called
from Java

^KT-63087 Fixed
This commit is contained in:
Dmitrii Gridin
2024-01-03 17:55:55 +01:00
committed by Space Team
parent e0f524b6b3
commit c6004874c1
4 changed files with 72 additions and 22 deletions
@@ -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)
@@ -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<KtCallableDeclaration>()
if (psiDeclaration?.typeReference != null && returnType.typeForValueClass) return true
@@ -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()
}
@@ -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()