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 6e6f18e846..0d74954682 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 @@ -59,8 +59,11 @@ 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.analysis.checkers.getContainingClassSymbol +import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.getTargetType +import org.jetbrains.kotlin.fir.declarations.utils.moduleName import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirArrayLiteral import org.jetbrains.kotlin.fir.expressions.FirExpression @@ -990,6 +993,7 @@ internal fun KaCallableSymbol.explictJvmName(): String? { }?.arguments?.single()?.expression?.toValue() as? String } +@OptIn(SymbolInternals::class) internal val KaDeclarationSymbol.internalSuffix: String get() = analyze { if (visibility != KaSymbolVisibility.INTERNAL) @@ -1011,7 +1015,14 @@ internal val KaDeclarationSymbol.internalSuffix: String fun String.toSuffix(): String = "\$$this" when (val module = containingModule) { is KaSourceModule -> module.name.toSuffix() - is KaLibraryModule -> module.libraryName.toSuffix() + is KaLibraryModule -> { + // Read module name from metadata. + // FIXME: need an API in AA. + val firSymbol = (this@internalSuffix as? KaFirSymbol<*>)?.firSymbol + val firClassSymbol = firSymbol?.getContainingClassSymbol() + val moduleName = (firClassSymbol?.fir as? FirRegularClass)?.moduleName + (moduleName ?: module.libraryName.toSuffix()).toSuffix() + } else -> "" } } diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/AbstractKSPAATest.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/AbstractKSPAATest.kt index 13ba744c49..158258cf71 100644 --- a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/AbstractKSPAATest.kt +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/AbstractKSPAATest.kt @@ -56,7 +56,13 @@ abstract class AbstractKSPAATest : AbstractKSPTest(FrontendKinds.FIR) { } } - private fun compileKotlin(dependencies: List, sourcesPath: String, javaSourcePath: String, outDir: File) { + private fun compileKotlin( + dependencies: List, + sourcesPath: String, + javaSourcePath: String, + outDir: File, + moduleName: String + ) { val classpath = mutableListOf() classpath.addAll(dependencies.map { it.canonicalPath }) if (File(sourcesPath).isDirectory) { @@ -69,6 +75,7 @@ abstract class AbstractKSPAATest : AbstractKSPTest(FrontendKinds.FIR) { javaSourcePath, "-d", outDir.absolutePath, "-no-stdlib", + "-module-name", moduleName, "-classpath", classpath.joinToString(File.pathSeparator) ) runJvmCompiler(args) @@ -86,7 +93,7 @@ abstract class AbstractKSPAATest : AbstractKSPTest(FrontendKinds.FIR) { module.writeKtFiles() val javaFiles = module.writeJavaFiles() val dependencies = module.allDependencies.map { outDirForModule(it.moduleName) } - compileKotlin(dependencies, module.kotlinSrc.path, module.javaDir.path, module.outDir) + compileKotlin(dependencies, module.kotlinSrc.path, module.javaDir.path, module.outDir, module.name) val classpath = (dependencies + KtTestUtil.getAnnotationsJar() + module.outDir) .joinToString(File.pathSeparator) { it.absolutePath } val options = listOf( diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt index aecf4979dd..e17e61fbae 100644 --- a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt @@ -413,11 +413,10 @@ class KSPAATest : AbstractKSPAATest() { runTest("../test-utils/testData/api/makeNullable.kt") } - @Disabled @TestMetadata("mangledNames.kt") @Test fun testMangledNames() { - runTest("../test-utils/testData/api/mangledNames.kt") + runTest("../kotlin-analysis-api/testData/mangledNames.kt") } @TestMetadata("multipleModules.kt") diff --git a/kotlin-analysis-api/testData/mangledNames.kt b/kotlin-analysis-api/testData/mangledNames.kt new file mode 100644 index 0000000000..04721222c8 --- /dev/null +++ b/kotlin-analysis-api/testData/mangledNames.kt @@ -0,0 +1,197 @@ +/* + * Copyright 2020 Google LLC + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// WITH_RUNTIME +// TEST PROCESSOR: MangledNamesProcessor +// EXPECTED: +// JavaEnum -> declarations +// JavaEnum.VAL1 -> declarations +// JavaEnum.VAL2 -> declarations +// valueOf -> valueOf +// values -> values +// JavaInput -> declarations +// -> +// getX -> getX +// getY -> getY +// javaFunction -> javaFunction +// setY -> setY +// staticJavaFunction -> staticJavaFunction +// mainPackage.AbstractKotlinClass -> declarations +// get-abstractVal -> getAbstractVal +// get-abstractVar -> getAbstractVar +// set-abstractVar -> setAbstractVar +// get-internalAbstractVal -> getInternalAbstractVal$mainModule +// set-internalAbstractVal -> setInternalAbstractVal$mainModule +// get-internalAbstractVar -> getInternalAbstractVar$mainModule +// set-internalAbstractVar -> setInternalAbstractVar$mainModule +// mainPackage.Anno -> declarations +// get-a -> a +// mainPackage.Foo -> declarations +// hasJvmName -> explicitJvmName +// get-inlineProp -> getInlineProp-HRn7Rpw +// set-inlineProp -> setInlineProp-E03SJzc +// inlineReceivingFun -> inlineReceivingFun-E03SJzc +// inlineReturningFun -> inlineReturningFun-HRn7Rpw +// get-internalInlineProp -> getInternalInlineProp-HRn7Rpw$mainModule +// set-internalInlineProp -> setInternalInlineProp-E03SJzc$mainModule +// internalInlineReceivingFun -> internalInlineReceivingFun-E03SJzc$mainModule +// internalInlineReturningFun -> internalInlineReturningFun-HRn7Rpw$mainModule +// get-internalProp -> getInternalProp$mainModule +// set-internalProp -> setInternalProp$mainModule +// get-jvmNameProp -> explicitGetterName +// set-jvmNameProp -> explicitSetterName +// normalFun -> normalFun +// get-normalProp -> getNormalProp +// set-normalProp -> setNormalProp +// mainPackage.MyInterface -> declarations +// get-x -> getX +// get-y -> getY +// set-y -> setY +// fileLevelInlineReceivingFun -> fileLevelInlineReceivingFun-E03SJzc +// fileLevelInlineReturningFun -> fileLevelInlineReturningFun +// fileLevelInternalFun -> fileLevelInternalFun +// fileLevelInternalInlineReceivingFun -> fileLevelInternalInlineReceivingFun-E03SJzc +// fileLevelInternalInlineReturningFun -> fileLevelInternalInlineReturningFun +// libPackage.Foo -> declarations +// -> +// hasJvmName -> explicitJvmName +// get-inlineProp -> getInlineProp-b_MPbnQ +// set-inlineProp -> setInlineProp-mQ73O9w +// inlineReceivingFun -> inlineReceivingFun-mQ73O9w +// inlineReturningFun -> inlineReturningFun-b_MPbnQ +// get-internalInlineProp -> getInternalInlineProp-b_MPbnQ$lib +// set-internalInlineProp -> setInternalInlineProp-mQ73O9w$lib +// internalInlineReceivingFun -> internalInlineReceivingFun-mQ73O9w$lib +// internalInlineReturningFun -> internalInlineReturningFun-b_MPbnQ$lib +// get-internalProp -> getInternalProp$lib +// set-internalProp -> setInternalProp$lib +// get-jvmNameProp -> explicitGetterName +// set-jvmNameProp -> explicitSetterName +// normalFun -> normalFun +// get-normalProp -> getNormalProp +// set-normalProp -> setNormalProp +// libPackage.AbstractKotlinClass -> declarations +// get-abstractVal -> getAbstractVal +// get-abstractVar -> getAbstractVar +// set-abstractVar -> setAbstractVar +// get-internalAbstractVal -> getInternalAbstractVal$lib +// set-internalAbstractVal -> setInternalAbstractVal$lib +// get-internalAbstractVar -> getInternalAbstractVar$lib +// set-internalAbstractVar -> setInternalAbstractVar$lib +// libPackage.MyInterface -> declarations +// get-x -> getX +// get-y -> getY +// set-y -> setY +// END +// MODULE: lib +// FILE: input.kt +/** + * control group + */ +package libPackage; +inline class Inline1(val value:String) +class Foo { + var normalProp:String = TODO() + var inlineProp: Inline1 = TODO() + internal var internalProp: String = TODO() + internal var internalInlineProp: Inline1 = TODO() + @get:JvmName("explicitGetterName") + @set:JvmName("explicitSetterName") + var jvmNameProp:String + fun normalFun() {} + @JvmName("explicitJvmName") + fun hasJvmName() {} + fun inlineReceivingFun(value: Inline1) {} + fun inlineReturningFun(): Inline1 = TODO() + internal fun internalInlineReceivingFun(value: Inline1) {} + internal fun internalInlineReturningFun(): Inline1 = TODO() +} + +abstract class AbstractKotlinClass { + abstract var abstractVar:String + abstract val abstractVal:String + internal abstract var internalAbstractVar:String + internal abstract var internalAbstractVal:String +} + +interface MyInterface { + val x:Int + var y:Int +} +// MODULE: mainModule(lib) +// FILE: input.kt +package mainPackage; +inline class Inline1(val value:String) +class Foo { + var normalProp:String = TODO() + var inlineProp: Inline1 = TODO() + internal var internalProp: String = TODO() + internal var internalInlineProp: Inline1 = TODO() + @get:JvmName("explicitGetterName") + @set:JvmName("explicitSetterName") + var jvmNameProp:String + fun normalFun() {} + @JvmName("explicitJvmName") + fun hasJvmName() {} + fun inlineReceivingFun(value: Inline1) {} + fun inlineReturningFun(): Inline1 = TODO() + internal fun internalInlineReceivingFun(value: Inline1) {} + internal fun internalInlineReturningFun(): Inline1 = TODO() +} + +annotation class Anno(val a: String) +abstract class AbstractKotlinClass { + abstract var abstractVar:String + abstract val abstractVal:String + internal abstract var internalAbstractVar:String + internal abstract var internalAbstractVal:String +} + +internal fun fileLevelInternalFun(): Unit = TODO() +fun fileLevelInlineReceivingFun(inline1: Inline1): Unit = TODO() +fun fileLevelInlineReturningFun(): Inline1 = TODO() +fun fileLevelInternalInlineReceivingFun(inline1: Inline1): Unit = TODO() +fun fileLevelInternalInlineReturningFun(): Inline1 = TODO() + +interface MyInterface { + val x:Int + var y:Int +} + +// FILE: JavaInput.java +import mainPackage.MyInterface; + +class JavaInput implements MyInterface { + String javaField; + String javaFunction() {} + static String staticJavaField; + static void staticJavaFunction() {} + public int getX() { + return 1; + } + public int getY() { + return 1; + } + public void setY(int value) { + } +} + +// FILE: JavaEnum.java +public enum JavaEnum { + VAL1, + VAL2; +}