Skip to content

Commit ca7b06c

Browse files
committed
Reuse Kotlin indexes in incremental providers
Also simplify finding Java sources.
1 parent a046228 commit ca7b06c

6 files changed

+140
-216
lines changed

kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinSymbolProcessing.kt

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ import com.intellij.openapi.roots.PackageIndex
5050
import com.intellij.openapi.util.Disposer
5151
import com.intellij.openapi.vfs.StandardFileSystems
5252
import com.intellij.openapi.vfs.VirtualFile
53-
import com.intellij.openapi.vfs.VirtualFileManager
5453
import com.intellij.psi.PsiFileSystemItem
5554
import com.intellij.psi.PsiJavaFile
5655
import com.intellij.psi.PsiManager
@@ -125,7 +124,6 @@ import org.jetbrains.kotlin.platform.konan.NativePlatforms
125124
import org.jetbrains.kotlin.platform.wasm.WasmPlatforms
126125
import org.jetbrains.kotlin.psi.KtFile
127126
import java.io.File
128-
import java.nio.file.Files
129127
import java.nio.file.Path
130128

131129
class KotlinSymbolProcessing(
@@ -356,11 +354,10 @@ class KotlinSymbolProcessing(
356354
compilerConfiguration: CompilerConfiguration
357355
): List<KSFile> {
358356
val project = kotlinCoreProjectEnvironment.project
359-
val psiManager = PsiManager.getInstance(project)
360357
val ktFiles = createSourceFilesFromSourceRoots(
361358
compilerConfiguration, project, compilerConfiguration.kotlinSourceRoots
362359
).toSet().toList()
363-
val psiFiles = getPsiFilesFromPaths<PsiFileSystemItem>(
360+
val allJavaFiles = getPsiFilesFromPaths<PsiJavaFile>(
364361
project,
365362
getSourceFilePaths(compilerConfiguration, includeDirectoryRoot = true)
366363
)
@@ -378,21 +375,47 @@ class KotlinSymbolProcessing(
378375
).update(ktFiles)
379376

380377
// Update Java providers for newly generated source files.
381-
reinitJavaFileManager(kotlinCoreProjectEnvironment, modules, psiFiles)
382-
383-
val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
384-
val javaFiles = if (kspConfig is KSPJvmConfig) {
385-
val javaRoots = kspConfig.javaSourceRoots + kspConfig.javaOutputDir
386-
// Get non-symbolic paths first
387-
javaRoots.sortedBy { Files.isSymbolicLink(it.toPath()) }
388-
.flatMap { root -> root.walk().filter { it.isFile && it.extension == "java" }.toList() }
389-
// This time is for .java files
390-
.sortedBy { Files.isSymbolicLink(it.toPath()) }
391-
.distinctBy { it.canonicalPath }
392-
.mapNotNull { localFileSystem.findFileByPath(it.path)?.let { psiManager.findFile(it) } as? PsiJavaFile }
393-
} else {
394-
emptyList()
395-
}
378+
reinitJavaFileManager(kotlinCoreProjectEnvironment, modules, allJavaFiles)
379+
380+
return ktFiles.map { analyze { KSFileImpl.getCached(it.getFileSymbol()) } } +
381+
allJavaFiles.map { KSFileJavaImpl.getCached(it) }
382+
}
383+
384+
private fun prepareNewKSFiles(
385+
kotlinCoreProjectEnvironment: KotlinCoreProjectEnvironment,
386+
modules: List<KtModule>,
387+
compilerConfiguration: CompilerConfiguration,
388+
newKotlinFiles: List<File>,
389+
newJavaFiles: List<File>,
390+
): List<KSFile> {
391+
val project = kotlinCoreProjectEnvironment.project
392+
val ktFiles = getPsiFilesFromPaths<KtFile>(
393+
project,
394+
newKotlinFiles.map { it.toPath() }.toSet()
395+
)
396+
val javaFiles = getPsiFilesFromPaths<PsiJavaFile>(
397+
project,
398+
newJavaFiles.map { it.toPath() }.toSet()
399+
)
400+
val allJavaFiles = getPsiFilesFromPaths<PsiJavaFile>(
401+
project,
402+
getSourceFilePaths(compilerConfiguration, includeDirectoryRoot = true)
403+
)
404+
405+
// Update Kotlin providers for newly generated source files.
406+
(
407+
project.getService(
408+
KotlinDeclarationProviderFactory::class.java
409+
) as IncrementalKotlinDeclarationProviderFactory
410+
).update(ktFiles)
411+
(
412+
project.getService(
413+
KotlinPackageProviderFactory::class.java
414+
) as IncrementalKotlinPackageProviderFactory
415+
).update(ktFiles)
416+
417+
// Update Java providers for newly generated source files.
418+
reinitJavaFileManager(kotlinCoreProjectEnvironment, modules, allJavaFiles)
396419

397420
return ktFiles.map { analyze { KSFileImpl.getCached(it.getFileSymbol()) } } +
398421
javaFiles.map { KSFileJavaImpl.getCached(it) }
@@ -533,7 +556,7 @@ class KotlinSymbolProcessing(
533556
}
534557

535558
// Drop caches
536-
KotlinGlobalModificationService.getInstance(project).publishGlobalModuleStateModification()
559+
KotlinGlobalModificationService.getInstance(project).publishGlobalSourceModuleStateModification()
537560
KtAnalysisSessionProvider.getInstance(project).clearCaches()
538561
psiManager.dropResolveCaches()
539562
psiManager.dropPsiCaches()
@@ -542,10 +565,26 @@ class KotlinSymbolProcessing(
542565

543566
val newFilePaths = codeGenerator.generatedFile.filter { it.extension == "kt" || it.extension == "java" }
544567
.map { it.canonicalPath }.toSet()
545-
allDirtyKSFiles = prepareAllKSFiles(kotlinCoreProjectEnvironment, modules, compilerConfiguration).filter {
546-
it.filePath !in allCleanFilePaths
547-
}
548-
newKSFiles = allDirtyKSFiles.filter { it.filePath in newFilePaths }
568+
newKSFiles = prepareNewKSFiles(
569+
kotlinCoreProjectEnvironment,
570+
modules,
571+
compilerConfiguration,
572+
newFilePaths.filter { it.endsWith(".kt") }.map { File(it) }.toList(),
573+
newFilePaths.filter { it.endsWith(".java") }.map { File(it) }.toList(),
574+
)
575+
// Now that caches are dropped, KtSymbols and KS* are invalid. They need to be re-created from PSI.
576+
allDirtyKSFiles = allDirtyKSFiles.map {
577+
when (it) {
578+
is KSFileImpl -> {
579+
val ktFile = it.ktFileSymbol.psi!! as KtFile
580+
analyze { KSFileImpl.getCached(ktFile.getFileSymbol()) }
581+
}
582+
is KSFileJavaImpl -> {
583+
KSFileJavaImpl.getCached(it.psi)
584+
}
585+
else -> throw IllegalArgumentException("Unknown KSFile implementation: $it")
586+
}
587+
} + newKSFiles
549588
incrementalContext.registerGeneratedFiles(newKSFiles)
550589
codeGenerator.closeFiles()
551590
}
@@ -612,7 +651,7 @@ class DirectoriesScope(
612651
private fun reinitJavaFileManager(
613652
environment: KotlinCoreProjectEnvironment,
614653
modules: List<KtModule>,
615-
sourceFiles: List<PsiFileSystemItem>,
654+
sourceFiles: List<PsiJavaFile>,
616655
) {
617656
val project = environment.project
618657
val javaFileManager = project.getService(JavaFileManager::class.java) as KotlinCliJavaFileManagerImpl

kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/standalone/IncrementalKotlinDeclarationProvider.kt

Lines changed: 0 additions & 107 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.google.devtools.ksp.standalone
2+
3+
import com.intellij.openapi.project.Project
4+
import com.intellij.psi.search.GlobalSearchScope
5+
import org.jetbrains.kotlin.analysis.project.structure.KtModule
6+
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider
7+
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory
8+
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticDeclarationProviderFactory
9+
import org.jetbrains.kotlin.analysis.providers.impl.declarationProviders.CompositeKotlinDeclarationProvider
10+
import org.jetbrains.kotlin.name.Name
11+
import org.jetbrains.kotlin.psi.KtClassOrObject
12+
import org.jetbrains.kotlin.psi.KtFile
13+
import org.jetbrains.kotlin.psi.KtTypeAlias
14+
15+
class IncrementalKotlinDeclarationProviderFactory(
16+
private val project: Project,
17+
) : KotlinDeclarationProviderFactory() {
18+
private val staticFactories: MutableList<KotlinStaticDeclarationProviderFactory> = mutableListOf()
19+
20+
override fun createDeclarationProvider(
21+
scope: GlobalSearchScope,
22+
contextualModule: KtModule?
23+
): KotlinDeclarationProvider {
24+
val providers = staticFactories.map { it.createDeclarationProvider(scope, contextualModule) }
25+
return CompositeKotlinDeclarationProvider.create(providers)
26+
}
27+
28+
fun update(files: Collection<KtFile>) {
29+
val staticFactory = KotlinStaticDeclarationProviderFactory(project, files)
30+
staticFactories.add(staticFactory)
31+
}
32+
33+
fun getDirectInheritorCandidates(baseClassName: Name): Set<KtClassOrObject> =
34+
staticFactories.flatMapTo(mutableSetOf()) {
35+
it.getDirectInheritorCandidates(baseClassName)
36+
}
37+
38+
fun getInheritableTypeAliases(aliasedName: Name): Set<KtTypeAlias> =
39+
staticFactories.flatMapTo(mutableSetOf()) {
40+
it.getInheritableTypeAliases(aliasedName)
41+
}
42+
}

kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/standalone/IncrementalKotlinPackageProvider.kt

Lines changed: 0 additions & 73 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.google.devtools.ksp.standalone
2+
3+
import com.intellij.openapi.project.Project
4+
import com.intellij.psi.search.GlobalSearchScope
5+
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProvider
6+
import org.jetbrains.kotlin.analysis.providers.KotlinPackageProviderFactory
7+
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticPackageProviderFactory
8+
import org.jetbrains.kotlin.analysis.providers.impl.packageProviders.CompositeKotlinPackageProvider
9+
import org.jetbrains.kotlin.psi.KtFile
10+
11+
class IncrementalKotlinPackageProviderFactory(
12+
private val project: Project,
13+
) : KotlinPackageProviderFactory() {
14+
private val staticFactories: MutableList<KotlinStaticPackageProviderFactory> = mutableListOf()
15+
16+
override fun createPackageProvider(searchScope: GlobalSearchScope): KotlinPackageProvider {
17+
val providers = staticFactories.map { it.createPackageProvider(searchScope) }
18+
return CompositeKotlinPackageProvider.create(providers)
19+
}
20+
21+
fun update(files: Collection<KtFile>) {
22+
val staticFactory = KotlinStaticPackageProviderFactory(project, files)
23+
staticFactories.add(staticFactory)
24+
}
25+
}

0 commit comments

Comments
 (0)