[Analysis API Standalone] simplify adding source binary roots for KtSourceModuleBuilder
- allow providing source files instead of PsiFile - automatically provide GlobalSearchScope for created `KtSourceModule` ^KT-60884
This commit is contained in:
committed by
Space Team
parent
67f4ebc022
commit
180434951b
+32
-8
@@ -5,18 +5,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.project.structure.builder
|
||||
|
||||
import com.intellij.psi.PsiFileSystemItem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.impl.KtSourceModuleImpl
|
||||
import org.jetbrains.kotlin.analysis.project.structure.impl.collectSourceFilePaths
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreProjectEnvironment
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import java.nio.file.Path
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.io.path.isDirectory
|
||||
|
||||
@KtModuleBuilderDsl
|
||||
public class KtSourceModuleBuilder(
|
||||
@@ -25,19 +29,22 @@ public class KtSourceModuleBuilder(
|
||||
public lateinit var moduleName: String
|
||||
public var languageVersionSettings: LanguageVersionSettings =
|
||||
LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST)
|
||||
public lateinit var contentScope: GlobalSearchScope
|
||||
|
||||
private val sourceRoots: MutableList<PsiFileSystemItem> = mutableListOf()
|
||||
private val sourceRoots: MutableList<Path> = mutableListOf()
|
||||
|
||||
public fun addSourceRoot(file: PsiFileSystemItem) {
|
||||
sourceRoots.add(file)
|
||||
public fun addSourceRoot(path: Path) {
|
||||
sourceRoots.add(path)
|
||||
}
|
||||
|
||||
public fun addSourceRoots(files: Collection<PsiFileSystemItem>) {
|
||||
sourceRoots.addAll(files)
|
||||
public fun addSourceRoots(paths: Collection<Path>) {
|
||||
sourceRoots.addAll(paths)
|
||||
}
|
||||
|
||||
override fun build(): KtSourceModule {
|
||||
val virtualFiles = collectVirtualFilesByRoots()
|
||||
val psiManager = PsiManager.getInstance(kotlinCoreProjectEnvironment.project)
|
||||
val psiFiles = virtualFiles.mapNotNull { psiManager.findFile(it) }
|
||||
val contentScope = GlobalSearchScope.filesScope(kotlinCoreProjectEnvironment.project, virtualFiles)
|
||||
return KtSourceModuleImpl(
|
||||
directRegularDependencies,
|
||||
directDependsOnDependencies,
|
||||
@@ -47,9 +54,26 @@ public class KtSourceModuleBuilder(
|
||||
kotlinCoreProjectEnvironment.project,
|
||||
moduleName,
|
||||
languageVersionSettings,
|
||||
sourceRoots,
|
||||
psiFiles,
|
||||
)
|
||||
}
|
||||
|
||||
private fun collectVirtualFilesByRoots(): List<VirtualFile> {
|
||||
val localFileSystem = kotlinCoreProjectEnvironment.environment.localFileSystem
|
||||
return buildList {
|
||||
for (root in sourceRoots) {
|
||||
val files = if (root.isDirectory()) {
|
||||
collectSourceFilePaths(root)
|
||||
} else {
|
||||
listOf(root)
|
||||
}
|
||||
for (file in files) {
|
||||
val virtualFile = localFileSystem.findFileByIoFile(file.toFile()) ?: continue
|
||||
add(virtualFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
|
||||
+6
-14
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtSta
|
||||
import org.jetbrains.kotlin.analysis.project.structure.builder.*
|
||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreProjectEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.cli.jvm.config.javaSourceRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||
@@ -67,7 +66,7 @@ internal fun getSourceFilePaths(
|
||||
val path = Paths.get(srcRoot)
|
||||
if (Files.isDirectory(path)) {
|
||||
// E.g., project/app/src
|
||||
collectSourceFilePaths(path, this)
|
||||
addAll(collectSourceFilePaths(path))
|
||||
if (includeDirectoryRoot) {
|
||||
add(path)
|
||||
}
|
||||
@@ -80,19 +79,17 @@ internal fun getSourceFilePaths(
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect source file path from the given [root] store them in [result].
|
||||
* Collect source file path from the given [root]
|
||||
*
|
||||
* E.g., for `project/app/src` as a [root], this will walk the file tree and
|
||||
* collect all `.kt`, `.kts`, and `.java` files under that folder.
|
||||
*
|
||||
* Note that this util gracefully skips [IOException] during file tree traversal.
|
||||
*/
|
||||
private fun collectSourceFilePaths(
|
||||
root: Path,
|
||||
result: MutableSet<Path>
|
||||
) {
|
||||
internal fun collectSourceFilePaths(root: Path): List<Path> {
|
||||
// NB: [Files#walk] throws an exception if there is an issue during IO.
|
||||
// With [Files#walkFileTree] with a custom visitor, we can take control of exception handling.
|
||||
val result = mutableListOf<Path>()
|
||||
Files.walkFileTree(
|
||||
root,
|
||||
object : SimpleFileVisitor<Path>() {
|
||||
@@ -125,6 +122,7 @@ private fun collectSourceFilePaths(
|
||||
}
|
||||
}
|
||||
)
|
||||
return result
|
||||
}
|
||||
|
||||
internal inline fun <reified T : PsiFileSystemItem> getPsiFilesFromPaths(
|
||||
@@ -197,13 +195,7 @@ internal fun buildKtModuleProviderByCompilerConfiguration(
|
||||
|
||||
addModuleDependencies(moduleName)
|
||||
|
||||
contentScope = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(kotlinCoreProjectEnvironment.project, ordinaryFiles)
|
||||
addSourceRoots(
|
||||
getPsiFilesFromPaths(
|
||||
kotlinCoreProjectEnvironment,
|
||||
getSourceFilePaths(compilerConfig, includeDirectoryRoot = true)
|
||||
)
|
||||
)
|
||||
addSourceRoots(compilerConfig.javaSourceRoots.map { Paths.get(it) })
|
||||
}.apply(::addModule)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user