Skip to content

Commit ae68d36

Browse files
Kotlin: read KDoc sections via Kotlin PSI, not com.intellij.psi navigation
The previous two commits removed the `ProcessCanceledException` and `PsiTreeUtil` references from KDoc-section parsing, but the internal extractor build then failed on `unresolved reference 'PsiElement'`: the hand-written tree walk named `com.intellij.psi.PsiElement` (and its `firstChild`/`nextSibling`). The root cause is that the LighterAST/K2 comment extractor is compiled against a curated classpath that deliberately excludes `com.intellij.psi.*`. It exposes only the `com.intellij.lang` LighterAST API (`LighterASTNode`, `FlyweightCapableTreeStructure`) plus the Kotlin PSI classes (`org.jetbrains.kotlin.psi.*`, `...kdoc.psi.*`). That is why `KtPsiFactory`, `KtFile`, `KDoc` and `getAllSections` all resolve while any `com.intellij.psi` reference does not. The full standalone builds bundle the whole classpath, so they never caught this. Locate the parsed KDoc through the Kotlin PSI API instead: the KDoc attaches to the throwaway `val __codeql_kdoc__` as its `docComment`, so `ktFile.declarations.firstOrNull()?.docComment` retrieves it using only `org.jetbrains.kotlin.psi` types (`KtCommonFile.getDeclarations`, `KtDeclaration.getDocComment`). No `com.intellij.psi` symbol remains in the file's code. Behaviour is unchanged: the parsed input is a single KDoc comment followed by one declaration, so its `docComment` is exactly the KDoc the old descendant search returned. No expected-output changes. Verified the standalone extractor builds for 1.9.0-Beta and 2.4.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 0abbd89 commit ae68d36

1 file changed

Lines changed: 9 additions & 23 deletions

File tree

java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_0-Beta/CommentExtractorLighterAST.kt

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,36 +52,22 @@ class CommentExtractorLighterAST(
5252
}
5353
}
5454

55-
// Depth-first search for the first KDoc descendant of `element`. We navigate
56-
// the PSI tree by hand rather than using `com.intellij.psi.util.PsiTreeUtil`,
57-
// because that utility class is not present on every supported compiler's
58-
// embeddable classpath (the reduced classpath used by some builds strips it),
59-
// whereas the core `PsiElement` navigation API is always available.
60-
private fun findKDocDescendant(
61-
element: com.intellij.psi.PsiElement
62-
): org.jetbrains.kotlin.kdoc.psi.api.KDoc? {
63-
if (element is org.jetbrains.kotlin.kdoc.psi.api.KDoc) {
64-
return element
65-
}
66-
var child = element.firstChild
67-
while (child != null) {
68-
findKDocDescendant(child)?.let {
69-
return it
70-
}
71-
child = child.nextSibling
72-
}
73-
return null
74-
}
75-
7655
private fun parseKDocSections(
7756
commentText: String
7857
): List<org.jetbrains.kotlin.kdoc.psi.impl.KDocSection>? {
7958
val factory = ktPsiFactory ?: return null
8059
return try {
8160
// A KDoc is only recognised as a doc comment when it precedes a
82-
// declaration, so we append a throwaway declaration before parsing.
61+
// declaration, so we append a throwaway declaration before parsing; the
62+
// KDoc then attaches to that declaration as its `docComment`. We read it
63+
// via the `org.jetbrains.kotlin.psi` API (`KtFile.declarations` and
64+
// `KtDeclaration.docComment`) rather than a generic PSI-tree walk, because
65+
// the LighterAST/K2 extractor is compiled against a curated classpath that
66+
// exposes the Kotlin PSI classes but not `com.intellij.psi.*` (only the
67+
// `com.intellij.lang` LighterAST API). Referencing `com.intellij.psi`
68+
// types here breaks that build.
8369
val ktFile = factory.createFile("$commentText\nval __codeql_kdoc__ = 0")
84-
findKDocDescendant(ktFile)?.getAllSections()
70+
ktFile.declarations.firstOrNull()?.docComment?.getAllSections()
8571
} catch (e: Exception) {
8672
// Never swallow IntelliJ's ProcessCanceledException: it is a control-flow
8773
// exception that must propagate for cancellation to work. We match it by

0 commit comments

Comments
 (0)