Skip to content

Commit 34b2f43

Browse files
committed
Use reflection for access
1 parent 189b0bf commit 34b2f43

File tree

2 files changed

+60
-21
lines changed

2 files changed

+60
-21
lines changed

src/main/kotlin/io/bazel/kotlin/plugin/jdeps/JdepsGenExtension.kt

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -175,23 +175,21 @@ class JdepsGenExtension(
175175

176176
// Finally, collect types that depend on the type of the ResultingDescriptor and note that
177177
// these descriptors may be composed of multiple classes that we need to extract types from
178-
if (resultingDescriptor is DeclarationDescriptor) {
179-
val containingDeclaration = resultingDescriptor.containingDeclaration
180-
if (containingDeclaration is ClassDescriptor) {
181-
collectTypeReferences(containingDeclaration.defaultType)
182-
}
178+
val containingDeclaration = resultingDescriptor.containingDeclaration
179+
if (containingDeclaration is ClassDescriptor) {
180+
collectTypeReferences(containingDeclaration.defaultType)
181+
}
183182

184-
if (resultingDescriptor is PropertyDescriptor) {
185-
(
186-
resultingDescriptor.getter
187-
?.correspondingProperty as? SyntheticJavaPropertyDescriptor
188-
)?.let { syntheticJavaPropertyDescriptor ->
189-
collectTypeReferences(syntheticJavaPropertyDescriptor.type, isExplicit = false)
183+
if (resultingDescriptor is PropertyDescriptor) {
184+
(
185+
resultingDescriptor.getter
186+
?.correspondingProperty as? SyntheticJavaPropertyDescriptor
187+
)?.let { syntheticJavaPropertyDescriptor ->
188+
collectTypeReferences(syntheticJavaPropertyDescriptor.type, isExplicit = false)
190189

191-
val functionDescriptor = syntheticJavaPropertyDescriptor.getMethod
192-
functionDescriptor.dispatchReceiverParameter?.type?.let { dispatchReceiverType ->
193-
collectTypeReferences(dispatchReceiverType, isExplicit = false)
194-
}
190+
val functionDescriptor = syntheticJavaPropertyDescriptor.getMethod
191+
functionDescriptor.dispatchReceiverParameter?.type?.let { dispatchReceiverType ->
192+
collectTypeReferences(dispatchReceiverType, isExplicit = false)
195193
}
196194
}
197195
}

src/main/kotlin/io/bazel/kotlin/plugin/jdeps/k2/JdepsK2Utils.kt

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,43 @@
11
package io.bazel.kotlin.plugin.jdeps.k2
22

3+
import io.bazel.kotlin.plugin.jdeps.k2.RefCache.jbseClass
4+
import io.bazel.kotlin.plugin.jdeps.k2.RefCache.jbseGetJavaClassMethod
5+
import io.bazel.kotlin.plugin.jdeps.k2.RefCache.vbseClass
6+
import io.bazel.kotlin.plugin.jdeps.k2.RefCache.vbseGetVirtualFileMethod
37
import org.jetbrains.kotlin.descriptors.SourceElement
4-
import org.jetbrains.kotlin.fir.java.VirtualFileBasedSourceElement
58
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
69
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
710
import org.jetbrains.kotlin.name.ClassId
811
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
912

13+
private object RefCache {
14+
15+
val vbseClass: Class<*>? by lazy {
16+
runCatching {
17+
Class.forName("org.jetbrains.kotlin.fir.java.VirtualFileBasedSourceElement")
18+
}.getOrNull()
19+
}
20+
21+
val vbseGetVirtualFileMethod by lazy {
22+
vbseClass?.runCatching {
23+
getMethod("getVirtualFile")
24+
}?.getOrNull()
25+
}
26+
27+
val jbseClass: Class<*>? by lazy {
28+
runCatching {
29+
Class.forName("org.jetbrains.kotlin.fir.descriptors.impl.JavaBinarySourceElement")
30+
}.getOrNull()
31+
}
32+
33+
val jbseGetJavaClassMethod by lazy {
34+
jbseClass?.runCatching {
35+
getMethod("getJavaClass")
36+
}?.getOrNull()
37+
}
38+
}
39+
40+
1041
/**
1142
* Returns whether class is coming from JVM runtime env. There is no need to track these classes.
1243
*
@@ -25,11 +56,21 @@ internal fun DeserializedContainerSource.classId(): ClassId? =
2556
}
2657

2758
internal fun SourceElement.binaryClass(): String? =
28-
when (this) {
29-
is KotlinJvmBinarySourceElement -> binaryClass.location
30-
is JvmPackagePartSource -> this.knownJvmBinaryClass?.location
31-
is VirtualFileBasedSourceElement -> this.virtualFile.path
32-
else -> null
59+
if (this is KotlinJvmBinarySourceElement) {
60+
binaryClass.location
61+
} else if (this is JvmPackagePartSource) {
62+
this.knownJvmBinaryClass?.location
63+
} else if (vbseClass != null && vbseClass!!.isInstance(this)) {
64+
// 1. Try VirtualFileBasedSourceElement (Kotlin 2.1.20+)
65+
val virtualFile = vbseGetVirtualFileMethod?.invoke(this)
66+
virtualFile?.javaClass?.getMethod("getPath")?.invoke(virtualFile) as? String
67+
} else if (jbseClass != null && jbseClass!!.isInstance(this)) {
68+
// 2. If that fails, try the old class name: JavaBinarySourceElement
69+
val jClass = jbseGetJavaClassMethod?.invoke(this)
70+
val virtualFile = jClass?.javaClass?.getMethod("getVirtualFile")?.invoke(jClass)
71+
virtualFile?.javaClass?.getMethod("getPath")?.invoke(virtualFile) as? String
72+
} else {
73+
null
3374
}
3475

3576
internal fun DeserializedContainerSource.binaryClass(): String? =

0 commit comments

Comments
 (0)