Skip to content

Commit

Permalink
fix KSTypeNotPresentException for an existing nesting class (#2331)
Browse files Browse the repository at this point in the history
* fix KSTypeNotPresentException for an existing nesting class

* add tests

* renaming

* fix tests
  • Loading branch information
RishatShamsutdinov authored Feb 12, 2025
1 parent ba2eca8 commit 07747f6
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 1 deletion.
27 changes: 26 additions & 1 deletion api/src/main/kotlin/com/google/devtools/ksp/utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ class KSTypesNotPresentException(val ksTypes: List<KSType>, cause: Throwable) :

@KspExperimental
private fun KSType.asClass(proxyClass: Class<*>) = try {
Class.forName(this.declaration.qualifiedName!!.asString(), true, proxyClass.classLoader)
Class.forName(this.declaration.toJavaClassName(), true, proxyClass.classLoader)
} catch (e: Exception) {
throw KSTypeNotPresentException(this, e)
}
Expand All @@ -536,3 +536,28 @@ fun KSValueArgument.isDefault() = origin == Origin.SYNTHETIC

@KspExperimental
private fun Any.asArray(method: Method, proxyClass: Class<*>) = listOf(this).asArray(method, proxyClass)

private fun KSDeclaration.toJavaClassName(): String {
val nameDelimiter = '.'
val packageNameString = packageName.asString()
val qualifiedNameString = qualifiedName!!.asString()
val simpleNames = qualifiedNameString
.removePrefix("${packageNameString}$nameDelimiter")
.split(nameDelimiter)

return if (simpleNames.size > 1) {
buildString {
append(packageNameString)
append(nameDelimiter)

simpleNames.forEachIndexed { index, s ->
if (index > 0) {
append('$')
}
append(s)
}
}
} else {
qualifiedNameString
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ class KSPAATest : AbstractKSPAATest() {
runTest("../test-utils/testData/api/annotationWithArbitraryClassValue.kt")
}

@TestMetadata("annotationWithNestedClassValue.kt")
@Test
fun testAnnotationWithNestedClassValue() {
runTest("../test-utils/testData/api/annotationWithNestedClassValue.kt")
}

@TestMetadata("defaultKClassValue.kt")
@Test
fun testAnnotationValue_defaultKClassValue() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
*/

package com.google.devtools.ksp.processor

import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.getAnnotationsByType
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.KSAnnotated
import kotlin.reflect.KClass

@KspExperimental
class AnnotationNestedClassValueProcessor : AbstractTestProcessor() {
val result = mutableListOf<String>()

override fun toResult(): List<String> {
return result
}

override fun process(resolver: Resolver): List<KSAnnotated> {
val symbols = resolver.getSymbolsWithAnnotation(
"com.google.devtools.ksp.processor.NestedClassValueAnnotation"
)
symbols.flatMap {
it.getAnnotationsByType(NestedClassValueAnnotation::class)
}.forEach {
logAnnotationValues(it)
}
return emptyList()
}

private fun logAnnotationValues(classValueAnnotation: NestedClassValueAnnotation) {
result.add(classValueAnnotation.classValue.simpleName!!)
result.add(classValueAnnotation.classValues.joinToString { it.simpleName!! })
}
}

annotation class NestedClassValueAnnotation(
val classValue: KClass<*>,
val classValues: Array<KClass<*>>
)
36 changes: 36 additions & 0 deletions test-utils/testData/api/annotationWithNestedClassValue.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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: AnnotationNestedClassValueProcessor
// EXPECTED:
// Entry
// Entry
// END
// FILE: a.kt
package com.google.devtools.ksp.processor

import kotlin.reflect.KClass

annotation class NestedClassValueAnnotation(
val classValue: KClass<*>,
val classValues: Array<KClass<*>>
)

@NestedClassValueAnnotation(
classValue = java.util.Map.Entry::class,
classValues = [java.util.Map.Entry::class]
)
class ClassValueAnnotated

0 comments on commit 07747f6

Please sign in to comment.