Skip to content

Commit 83a3e34

Browse files
RishatShamsutdinovKSP Auto Pick
authored and
KSP Auto Pick
committed
fix KSTypeNotPresentException for an existing nesting class (#2331)
* fix KSTypeNotPresentException for an existing nesting class * add tests * renaming * fix tests (cherry picked from commit 07747f6)
1 parent 9bf2757 commit 83a3e34

File tree

4 files changed

+123
-1
lines changed

4 files changed

+123
-1
lines changed

api/src/main/kotlin/com/google/devtools/ksp/utils.kt

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ class KSTypesNotPresentException(val ksTypes: List<KSType>, cause: Throwable) :
520520

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

537537
@KspExperimental
538538
private fun Any.asArray(method: Method, proxyClass: Class<*>) = listOf(this).asArray(method, proxyClass)
539+
540+
private fun KSDeclaration.toJavaClassName(): String {
541+
val nameDelimiter = '.'
542+
val packageNameString = packageName.asString()
543+
val qualifiedNameString = qualifiedName!!.asString()
544+
val simpleNames = qualifiedNameString
545+
.removePrefix("${packageNameString}$nameDelimiter")
546+
.split(nameDelimiter)
547+
548+
return if (simpleNames.size > 1) {
549+
buildString {
550+
append(packageNameString)
551+
append(nameDelimiter)
552+
553+
simpleNames.forEachIndexed { index, s ->
554+
if (index > 0) {
555+
append('$')
556+
}
557+
append(s)
558+
}
559+
}
560+
} else {
561+
qualifiedNameString
562+
}
563+
}

kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPAATest.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ class KSPAATest : AbstractKSPAATest() {
9494
runTest("../test-utils/testData/api/annotationWithArbitraryClassValue.kt")
9595
}
9696

97+
@TestMetadata("annotationWithNestedClassValue.kt")
98+
@Test
99+
fun testAnnotationWithNestedClassValue() {
100+
runTest("../test-utils/testData/api/annotationWithNestedClassValue.kt")
101+
}
102+
97103
@TestMetadata("defaultKClassValue.kt")
98104
@Test
99105
fun testAnnotationValue_defaultKClassValue() {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2020 Google LLC
3+
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.google.devtools.ksp.processor
19+
20+
import com.google.devtools.ksp.KspExperimental
21+
import com.google.devtools.ksp.getAnnotationsByType
22+
import com.google.devtools.ksp.processing.Resolver
23+
import com.google.devtools.ksp.symbol.KSAnnotated
24+
import kotlin.reflect.KClass
25+
26+
@KspExperimental
27+
class AnnotationNestedClassValueProcessor : AbstractTestProcessor() {
28+
val result = mutableListOf<String>()
29+
30+
override fun toResult(): List<String> {
31+
return result
32+
}
33+
34+
override fun process(resolver: Resolver): List<KSAnnotated> {
35+
val symbols = resolver.getSymbolsWithAnnotation(
36+
"com.google.devtools.ksp.processor.NestedClassValueAnnotation"
37+
)
38+
symbols.flatMap {
39+
it.getAnnotationsByType(NestedClassValueAnnotation::class)
40+
}.forEach {
41+
logAnnotationValues(it)
42+
}
43+
return emptyList()
44+
}
45+
46+
private fun logAnnotationValues(classValueAnnotation: NestedClassValueAnnotation) {
47+
result.add(classValueAnnotation.classValue.simpleName!!)
48+
result.add(classValueAnnotation.classValues.joinToString { it.simpleName!! })
49+
}
50+
}
51+
52+
annotation class NestedClassValueAnnotation(
53+
val classValue: KClass<*>,
54+
val classValues: Array<KClass<*>>
55+
)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2020 Google LLC
3+
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
// TEST PROCESSOR: AnnotationNestedClassValueProcessor
18+
// EXPECTED:
19+
// Entry
20+
// Entry
21+
// END
22+
// FILE: a.kt
23+
package com.google.devtools.ksp.processor
24+
25+
import kotlin.reflect.KClass
26+
27+
annotation class NestedClassValueAnnotation(
28+
val classValue: KClass<*>,
29+
val classValues: Array<KClass<*>>
30+
)
31+
32+
@NestedClassValueAnnotation(
33+
classValue = java.util.Map.Entry::class,
34+
classValues = [java.util.Map.Entry::class]
35+
)
36+
class ClassValueAnnotated

0 commit comments

Comments
 (0)