Skip to content

Commit a4cd5d6

Browse files
committed
Use class descriptor for enum entries in java files
This PR fixes a bug in KSClassDeclarationJavaImpl where it would return properties for its enum constants instead of returning class declarations. Unfortunately, PsiEnumConstant does not have an API to resolve it as a class. So instead, this PR delegates to the descriptor implementation for these fields. Fixes: google#234 Test: classKinds
1 parent 494f7e9 commit a4cd5d6

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

compiler-plugin/src/main/kotlin/com/google/devtools/ksp/symbol/impl/java/KSClassDeclarationJavaImpl.kt

+21-3
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ import com.intellij.psi.PsiClass
2222
import com.intellij.psi.PsiJavaFile
2323
import org.jetbrains.kotlin.descriptors.ClassDescriptor
2424
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
25-
import org.jetbrains.kotlin.descriptors.Visibilities
2625
import com.google.devtools.ksp.processing.impl.ResolverImpl
2726
import com.google.devtools.ksp.symbol.*
2827
import com.google.devtools.ksp.symbol.impl.*
28+
import com.google.devtools.ksp.symbol.impl.binary.KSClassDeclarationDescriptorImpl
2929
import com.google.devtools.ksp.symbol.impl.kotlin.KSExpectActualNoImpl
3030
import com.google.devtools.ksp.symbol.impl.kotlin.KSNameImpl
3131
import com.google.devtools.ksp.symbol.impl.kotlin.getKSTypeCached
3232
import com.google.devtools.ksp.symbol.impl.replaceTypeArguments
3333
import com.google.devtools.ksp.symbol.impl.toKSFunctionDeclaration
34+
import com.intellij.psi.PsiClassType
35+
import com.intellij.psi.PsiEnumConstant
3436
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
3537
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
3638
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
@@ -59,6 +61,7 @@ class KSClassDeclarationJavaImpl private constructor(val psi: PsiClass) : KSClas
5961
psi.isAnnotationType -> ClassKind.ANNOTATION_CLASS
6062
psi.isInterface -> ClassKind.INTERFACE
6163
psi.isEnum -> ClassKind.ENUM_CLASS
64+
psi is PsiEnumConstant -> ClassKind.ENUM_ENTRY
6265
else -> ClassKind.CLASS
6366
}
6467
}
@@ -96,8 +99,23 @@ class KSClassDeclarationJavaImpl private constructor(val psi: PsiClass) : KSClas
9699
}
97100

98101
override val declarations: List<KSDeclaration> by lazy {
99-
(psi.fields.map { KSPropertyDeclarationJavaImpl.getCached(it) } +
100-
psi.innerClasses.map { KSClassDeclarationJavaImpl.getCached(it) } +
102+
// field declarations might be enum entries so we need to check their type before wrapping
103+
// them as property declarations
104+
val fieldDeclarations = psi.fields.map { field ->
105+
if (field is PsiEnumConstant) {
106+
// PsiEnumConstant does not have a PsiClass that would let us create a
107+
// KSClassDeclarationJavaImpl instance. Instead, we'll fallback to the descriptor
108+
// implementation.
109+
val descriptor = ResolverImpl.instance.resolveJavaDeclaration(field)
110+
// if we can resolve it to a class descriptor, use that instead
111+
if (descriptor is ClassDescriptor) {
112+
return@map KSClassDeclarationDescriptorImpl.getCached(descriptor)
113+
}
114+
}
115+
KSPropertyDeclarationJavaImpl.getCached(field)
116+
}
117+
(fieldDeclarations +
118+
psi.innerClasses.map { getCached(it) } +
101119
psi.constructors.map { KSFunctionDeclarationJavaImpl.getCached(it) } +
102120
psi.methods.map { KSFunctionDeclarationJavaImpl.getCached(it) })
103121
.distinct()

compiler-plugin/testData/api/classKinds.kt

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// EXPECTED:
2121
// JA: ANNOTATION_CLASS
2222
// JC: CLASS
23+
// JE.ENTRY: ENUM_ENTRY
2324
// JE: ENUM_CLASS
2425
// JI: INTERFACE
2526
// KA: ANNOTATION_CLASS
@@ -49,4 +50,6 @@ enum class KE {
4950
class JC {}
5051
interface JI {}
5152
@interface JA {}
52-
enum JE {}
53+
enum JE {
54+
ENTRY
55+
}

0 commit comments

Comments
 (0)