From ebf987b06af7c9d0fca78823c6120bf36348c5c8 Mon Sep 17 00:00:00 2001 From: Ting-Yuan Huang Date: Fri, 30 Aug 2024 15:01:31 -0700 Subject: [PATCH] Mangle jvm names for inline class (cherry picked from commit 207b8496c53b13b1c68c86610e3bd6ee87e92861) --- .../devtools/ksp/impl/ResolverAAImpl.kt | 12 +++- .../devtools/ksp/impl/symbol/kotlin/util.kt | 56 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt index 66f24b5c9e..7e435a2b66 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt @@ -510,10 +510,14 @@ class ResolverAAImpl( } else { "set" } + val inlineSuffix = when (accessor) { + is KSPropertyAccessorImpl -> accessor.ktPropertyAccessorSymbol.inlineSuffix + else -> "" + } val mangledName = if (accessor.modifiers.contains(Modifier.INTERNAL)) { "\$${ktModule.name}" } else "" - return "${prefix}${accessor.receiver.simpleName.asString().capitalize()}$mangledName" + return "${prefix}${accessor.receiver.simpleName.asString().capitalize()}$inlineSuffix$mangledName" } // TODO: handle library symbols @@ -525,10 +529,14 @@ class ResolverAAImpl( }?.let { return it.name } + val inlineSuffix = when (declaration) { + is KSFunctionDeclarationImpl -> declaration.ktFunctionSymbol.inlineSuffix + else -> "" + } val mangledName = if (declaration.modifiers.contains(Modifier.INTERNAL)) { "\$${ktModule.name}" } else "" - return declaration.simpleName.asString() + mangledName + return declaration.simpleName.asString() + inlineSuffix + mangledName } override fun getKSNameFromString(name: String): KSName { diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt index 9661b3b28a..57dab5301c 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt @@ -55,6 +55,9 @@ import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.markers.KaDeclarationContainerSymbol import org.jetbrains.kotlin.analysis.api.types.* import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap +import org.jetbrains.kotlin.codegen.state.InfoForMangling +import org.jetbrains.kotlin.codegen.state.collectFunctionSignatureForManglingSuffix +import org.jetbrains.kotlin.codegen.state.md5base64 import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.getTargetType import org.jetbrains.kotlin.fir.expressions.FirAnnotation @@ -923,3 +926,56 @@ fun T.tryResolveToTypePhase(): T { (this as? KaFirSymbol<*>)?.firSymbol?.lazyResolveToPhase(FirResolvePhase.TYPES) return this } + +private val KaType.upperBoundIfFlexible: KaType + get() = (this as? KaFlexibleType)?.upperBound ?: this + +private fun KaType.requiresMangling(): Boolean = (symbol as? KaNamedClassSymbol)?.isInline ?: false + +private fun KaType.asInfoForMangling(): InfoForMangling? { + val upperBound = upperBoundIfFlexible + val fqName = upperBound.symbol?.classId?.asSingleFqName()?.toUnsafe() ?: return null + val isValue = upperBound.requiresMangling() + val isNullable = upperBound.nullability.isNullable + return InfoForMangling(fqName = fqName, isValue = isValue, isNullable = isNullable) +} + +private fun mangleInlineSuffix( + parameters: List, + returnType: KaType?, + shouldMangleReturnType: Boolean +): String { + val signature = collectFunctionSignatureForManglingSuffix( + false, + parameters.any { it.requiresMangling() }, + parameters.map { it.asInfoForMangling() }, + if (shouldMangleReturnType) returnType?.asInfoForMangling() else null + ) ?: return "" + return "-${md5base64(signature)}" +} + +private val KaSymbol.isKotlin: Boolean + get() = when (origin) { + KaSymbolOrigin.SOURCE, KaSymbolOrigin.LIBRARY -> true + else -> false + } + +internal val KaFunctionSymbol.inlineSuffix: String + get() = mangleInlineSuffix( + valueParameters.map { it.returnType }, + returnType, + analyze { + returnType.requiresMangling() && isKotlin && this@inlineSuffix.containingSymbol is KaClassSymbol + } + ) + +internal val KaPropertyAccessorSymbol.inlineSuffix: String + get() = when (this) { + is KaPropertyGetterSymbol -> + mangleInlineSuffix( + emptyList(), + returnType, + returnType.requiresMangling() && isKotlin + ) + is KaPropertySetterSymbol -> mangleInlineSuffix(listOf(parameter.returnType), null, false) + }