diff --git a/api/api.base b/api/api.base index 9884b77105..f68e76589d 100644 --- a/api/api.base +++ b/api/api.base @@ -168,6 +168,7 @@ package com.google.devtools.ksp.processing { method @com.google.devtools.ksp.KspExperimental public boolean isJavaRawType(@NonNull com.google.devtools.ksp.symbol.KSType type); method @Nullable @com.google.devtools.ksp.KspExperimental public com.google.devtools.ksp.symbol.KSName mapJavaNameToKotlin(@NonNull com.google.devtools.ksp.symbol.KSName javaName); method @Nullable @com.google.devtools.ksp.KspExperimental public com.google.devtools.ksp.symbol.KSName mapKotlinNameToJava(@NonNull com.google.devtools.ksp.symbol.KSName kotlinName); + method @Nullable @com.google.devtools.ksp.KspExperimental public String mapToJvmClassName(@NonNull com.google.devtools.ksp.symbol.KSClassDeclaration declaration); method @Nullable @com.google.devtools.ksp.KspExperimental public String mapToJvmSignature(@NonNull com.google.devtools.ksp.symbol.KSDeclaration declaration); method public boolean overrides(@NonNull com.google.devtools.ksp.symbol.KSDeclaration overrider, @NonNull com.google.devtools.ksp.symbol.KSDeclaration overridee); method public boolean overrides(@NonNull com.google.devtools.ksp.symbol.KSDeclaration overrider, @NonNull com.google.devtools.ksp.symbol.KSDeclaration overridee, @NonNull com.google.devtools.ksp.symbol.KSClassDeclaration containingClass); diff --git a/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt b/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt index 642b5c9009..66aa221782 100644 --- a/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt +++ b/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt @@ -115,6 +115,13 @@ interface Resolver { @KspExperimental fun mapToJvmSignature(declaration: KSDeclaration): String? + /** + * Returns the [binary class name](https://asm.ow2.io/javadoc/org/objectweb/asm/Type.html#getClassName()) in JVM + * for the given [KSClassDeclaration]. + */ + @KspExperimental + fun mapToJvmClassName(declaration: KSClassDeclaration): String? + /** * @param overrider the candidate overriding declaration being checked. * @param overridee the candidate overridden declaration being checked. diff --git a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt index 7c1fade23d..bd68d6fefb 100644 --- a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt +++ b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt @@ -367,6 +367,13 @@ class ResolverImpl( else -> null } + @KspExperimental + override fun mapToJvmClassName(declaration: KSClassDeclaration): String? { + val descriptor = resolveClassDeclaration(declaration) ?: return null + + return typeMapper.mapType(descriptor).className + } + override fun overrides(overrider: KSDeclaration, overridee: KSDeclaration): Boolean { fun resolveForOverride(declaration: KSDeclaration): DeclarationDescriptor? { return when (declaration) { diff --git a/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/test/KSPCompilerPluginTest.kt b/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/test/KSPCompilerPluginTest.kt index e970b5d731..7ef5ad4f4b 100644 --- a/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/test/KSPCompilerPluginTest.kt +++ b/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/test/KSPCompilerPluginTest.kt @@ -339,6 +339,12 @@ class KSPCompilerPluginTest : AbstractKSPCompilerPluginTest() { runTest("../test-utils/testData/api/javaWildcards2.kt") } + @TestMetadata("jvmClassNameMapper.kt") + @Test + fun testJvmClassNameMapper() { + runTest("../test-utils/testData/api/jvmClassNameMapper.kt") + } + @TestMetadata("lateinitProperties.kt") @Test fun testLateinitProperties() { 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 687b2242f9..21409cd43a 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 @@ -259,6 +259,10 @@ class ResolverAAImpl( TODO("Not yet implemented") } + override fun mapToJvmClassName(declaration: KSClassDeclaration): String? { + TODO("Not yet implemented") + } + override fun overrides(overrider: KSDeclaration, overridee: KSDeclaration): Boolean { TODO("Not yet implemented") } diff --git a/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/MapJvmClassNameProcessor.kt b/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/MapJvmClassNameProcessor.kt new file mode 100644 index 0000000000..c2b0b6ccef --- /dev/null +++ b/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/MapJvmClassNameProcessor.kt @@ -0,0 +1,54 @@ +/* + * 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. + */ + +package com.google.devtools.ksp.processor + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getClassDeclarationByName +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.symbol.KSAnnotated + +@KspExperimental +class MapJvmClassNameProcessor : AbstractTestProcessor() { + private val result = mutableListOf() + + override fun toResult(): List { + return result + } + + override fun process(resolver: Resolver): List { + listOf( + "Cls1", + "Cls1.Cls2", + "Cls1.Cls3", + "Cls1.Cls4", + "JavaInterfaceWithVoid", + "JavaClass1", + "JavaClass1.JavaClass2", + "JavaClass1.JavaClass3", + "JavaClass1.JavaClass4", + "JavaClass5", + "JavaAnno", + ) + .map { className -> + resolver.getClassDeclarationByName(className)!! + }.forEach { subject -> + result.add(resolver.mapToJvmClassName(subject)!!) + } + return emptyList() + } +} diff --git a/test-utils/testData/api/jvmClassNameMapper.kt b/test-utils/testData/api/jvmClassNameMapper.kt new file mode 100644 index 0000000000..0ffd4aba8b --- /dev/null +++ b/test-utils/testData/api/jvmClassNameMapper.kt @@ -0,0 +1,55 @@ +/* + * 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. + */ + +// TEST PROCESSOR: MapJvmClassNameProcessor +// EXPECTED: +// Cls1 +// Cls1$Cls2 +// Cls1$Cls3 +// Cls1$Cls4 +// JavaInterfaceWithVoid +// JavaClass1 +// JavaClass1$JavaClass2 +// JavaClass1$JavaClass3 +// JavaClass1$JavaClass4 +// JavaClass5 +// JavaAnno +// END + +// FILE: Cls1.kt +class Cls1 { + class Cls2 + + open class Cls3 + + inner class Cls4 +} + +// FILE: JavaInterfaceWithVoid.java +interface JavaInterfaceWithVoid {} + +// FILE: JavaClass1.java +class JavaClass1 { + static final class JavaClass2 {} + static class JavaClass3 {} + class JavaClass4 {} +} + +class JavaClass5 {} + +// FILE: JavaAnno.java +@interface JavaAnno {}