[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
|
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 com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
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.KtSourceModuleImpl
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.impl.collectSourceFilePaths
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreProjectEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreProjectEnvironment
|
||||||
import org.jetbrains.kotlin.config.ApiVersion
|
import org.jetbrains.kotlin.config.ApiVersion
|
||||||
import org.jetbrains.kotlin.config.LanguageVersion
|
import org.jetbrains.kotlin.config.LanguageVersion
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
|
import java.nio.file.Path
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.InvocationKind
|
import kotlin.contracts.InvocationKind
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
import kotlin.io.path.isDirectory
|
||||||
|
|
||||||
@KtModuleBuilderDsl
|
@KtModuleBuilderDsl
|
||||||
public class KtSourceModuleBuilder(
|
public class KtSourceModuleBuilder(
|
||||||
@@ -25,19 +29,22 @@ public class KtSourceModuleBuilder(
|
|||||||
public lateinit var moduleName: String
|
public lateinit var moduleName: String
|
||||||
public var languageVersionSettings: LanguageVersionSettings =
|
public var languageVersionSettings: LanguageVersionSettings =
|
||||||
LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST)
|
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) {
|
public fun addSourceRoot(path: Path) {
|
||||||
sourceRoots.add(file)
|
sourceRoots.add(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun addSourceRoots(files: Collection<PsiFileSystemItem>) {
|
public fun addSourceRoots(paths: Collection<Path>) {
|
||||||
sourceRoots.addAll(files)
|
sourceRoots.addAll(paths)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun build(): KtSourceModule {
|
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(
|
return KtSourceModuleImpl(
|
||||||
directRegularDependencies,
|
directRegularDependencies,
|
||||||
directDependsOnDependencies,
|
directDependsOnDependencies,
|
||||||
@@ -47,9 +54,26 @@ public class KtSourceModuleBuilder(
|
|||||||
kotlinCoreProjectEnvironment.project,
|
kotlinCoreProjectEnvironment.project,
|
||||||
moduleName,
|
moduleName,
|
||||||
languageVersionSettings,
|
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)
|
@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.analysis.project.structure.builder.*
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreProjectEnvironment
|
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.javaSourceRoots
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||||
@@ -67,7 +66,7 @@ internal fun getSourceFilePaths(
|
|||||||
val path = Paths.get(srcRoot)
|
val path = Paths.get(srcRoot)
|
||||||
if (Files.isDirectory(path)) {
|
if (Files.isDirectory(path)) {
|
||||||
// E.g., project/app/src
|
// E.g., project/app/src
|
||||||
collectSourceFilePaths(path, this)
|
addAll(collectSourceFilePaths(path))
|
||||||
if (includeDirectoryRoot) {
|
if (includeDirectoryRoot) {
|
||||||
add(path)
|
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
|
* 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.
|
* collect all `.kt`, `.kts`, and `.java` files under that folder.
|
||||||
*
|
*
|
||||||
* Note that this util gracefully skips [IOException] during file tree traversal.
|
* Note that this util gracefully skips [IOException] during file tree traversal.
|
||||||
*/
|
*/
|
||||||
private fun collectSourceFilePaths(
|
internal fun collectSourceFilePaths(root: Path): List<Path> {
|
||||||
root: Path,
|
|
||||||
result: MutableSet<Path>
|
|
||||||
) {
|
|
||||||
// NB: [Files#walk] throws an exception if there is an issue during IO.
|
// 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.
|
// With [Files#walkFileTree] with a custom visitor, we can take control of exception handling.
|
||||||
|
val result = mutableListOf<Path>()
|
||||||
Files.walkFileTree(
|
Files.walkFileTree(
|
||||||
root,
|
root,
|
||||||
object : SimpleFileVisitor<Path>() {
|
object : SimpleFileVisitor<Path>() {
|
||||||
@@ -125,6 +122,7 @@ private fun collectSourceFilePaths(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <reified T : PsiFileSystemItem> getPsiFilesFromPaths(
|
internal inline fun <reified T : PsiFileSystemItem> getPsiFilesFromPaths(
|
||||||
@@ -197,13 +195,7 @@ internal fun buildKtModuleProviderByCompilerConfiguration(
|
|||||||
|
|
||||||
addModuleDependencies(moduleName)
|
addModuleDependencies(moduleName)
|
||||||
|
|
||||||
contentScope = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(kotlinCoreProjectEnvironment.project, ordinaryFiles)
|
addSourceRoots(compilerConfig.javaSourceRoots.map { Paths.get(it) })
|
||||||
addSourceRoots(
|
|
||||||
getPsiFilesFromPaths(
|
|
||||||
kotlinCoreProjectEnvironment,
|
|
||||||
getSourceFilePaths(compilerConfig, includeDirectoryRoot = true)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}.apply(::addModule)
|
}.apply(::addModule)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user