AA: consider directories with class files when creating a lib module
This commit is contained in:
committed by
Ilya Kirillov
parent
552bfc9e39
commit
ac46ce908f
+17
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.impl.base.util
|
||||
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
|
||||
@@ -22,8 +23,23 @@ object LibraryUtils {
|
||||
jar: Path,
|
||||
jarFileSystem: CoreJarFileSystem = CoreJarFileSystem(),
|
||||
): Collection<VirtualFile> {
|
||||
val root = jarFileSystem.refreshAndFindFileByPath(jar.toAbsolutePath().toString() + JAR_SEPARATOR)!!
|
||||
return jarFileSystem.refreshAndFindFileByPath(jar.toAbsolutePath().toString() + JAR_SEPARATOR)
|
||||
?.let { getAllVirtualFilesFromRoot(it) } ?: emptySet()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all [VirtualFile]s inside the given [dir] (of [Path])
|
||||
*/
|
||||
fun getAllVirtualFilesFromDirectory(
|
||||
dir: Path,
|
||||
): Collection<VirtualFile> {
|
||||
val fs = StandardFileSystems.local()
|
||||
return fs.findFileByPath(dir.toAbsolutePath().toString())?.let { getAllVirtualFilesFromRoot(it) } ?: return emptySet()
|
||||
}
|
||||
|
||||
private fun getAllVirtualFilesFromRoot(
|
||||
root: VirtualFile
|
||||
): Collection<VirtualFile> {
|
||||
val files = mutableSetOf<VirtualFile>()
|
||||
VfsUtilCore.iterateChildrenRecursively(
|
||||
root,
|
||||
|
||||
+27
-12
@@ -55,38 +55,53 @@ internal class KtSourceModuleByCompilerConfiguration(
|
||||
jarFileSystem: CoreJarFileSystem,
|
||||
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtSourceModule {
|
||||
override val directRegularDependencies: List<KtModule> by lazy {
|
||||
(compilerConfig.jvmModularRoots + compilerConfig.jvmClasspathRoots).map {
|
||||
KtLibraryModuleByCompilerConfiguration(compilerConfig, project, it.toPath(), jarFileSystem)
|
||||
val libraryRoots = compilerConfig.jvmModularRoots + compilerConfig.jvmClasspathRoots
|
||||
val libraryRootsByType = libraryRoots.groupBy { it.isDirectory }
|
||||
buildList {
|
||||
libraryRootsByType[true]?.let { directories ->
|
||||
directories.forEach {
|
||||
// E.g., project/app/build/intermediates/javac/debug/classes
|
||||
val root = it.toPath()
|
||||
val virtualFilesProvider = { LibraryUtils.getAllVirtualFilesFromDirectory(root) }
|
||||
add(KtLibraryModuleByCompilerConfiguration(compilerConfig, project, virtualFilesProvider, root))
|
||||
}
|
||||
}
|
||||
libraryRootsByType[false]?.let { jars ->
|
||||
jars.forEach {
|
||||
// E.g., project/libs/libA/a.jar
|
||||
val root = it.toPath()
|
||||
val virtualFilesProvider = { LibraryUtils.getAllVirtualFilesFromJar(root, jarFileSystem) }
|
||||
add(KtLibraryModuleByCompilerConfiguration(compilerConfig, project, virtualFilesProvider, root))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val contentScope: GlobalSearchScope =
|
||||
override val contentScope: GlobalSearchScope by lazy {
|
||||
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles)
|
||||
}
|
||||
}
|
||||
|
||||
internal class KtLibraryModuleByCompilerConfiguration(
|
||||
compilerConfig: CompilerConfiguration,
|
||||
project: Project,
|
||||
private val jar: Path,
|
||||
jarFileSystem: CoreJarFileSystem,
|
||||
virtualFilesProvider: () -> Collection<VirtualFile>,
|
||||
private val root: Path,
|
||||
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtLibraryModule {
|
||||
override val directRegularDependencies: List<KtModule> get() = emptyList()
|
||||
|
||||
internal val virtualFiles: Collection<VirtualFile> by lazy {
|
||||
LibraryUtils.getAllVirtualFilesFromJar(jar, jarFileSystem)
|
||||
}
|
||||
|
||||
override val libraryName: String
|
||||
get() = moduleName
|
||||
|
||||
override val librarySources: KtLibrarySourceModule?
|
||||
get() = null
|
||||
|
||||
override val contentScope: GlobalSearchScope =
|
||||
GlobalSearchScope.filesScope(project, virtualFiles)
|
||||
override val contentScope: GlobalSearchScope by lazy {
|
||||
GlobalSearchScope.filesScope(project, virtualFilesProvider())
|
||||
}
|
||||
|
||||
private val binaryRoots by lazy {
|
||||
listOf(jar)
|
||||
listOf(root)
|
||||
}
|
||||
|
||||
override fun getBinaryRoots(): Collection<Path> = binaryRoots
|
||||
|
||||
+5
-6
@@ -28,7 +28,7 @@ internal class ProjectStructureProviderByCompilerConfiguration(
|
||||
val path = Paths.get(srcRoot)
|
||||
if (Files.isDirectory(path)) {
|
||||
// E.g., project/app/src
|
||||
Files.walk(Paths.get(srcRoot))
|
||||
Files.walk(path)
|
||||
.filter(Files::isRegularFile)
|
||||
.forEach { add(it.toString()) }
|
||||
} else {
|
||||
@@ -42,13 +42,12 @@ internal class ProjectStructureProviderByCompilerConfiguration(
|
||||
private val sourceModule = KtSourceModuleByCompilerConfiguration(compilerConfig, project, ktFiles, jarFileSystem)
|
||||
|
||||
override fun getKtModuleForKtElement(element: PsiElement): KtModule {
|
||||
val containingFilePath = element.containingFile.virtualFile.path
|
||||
return if (containingFilePath in sourceFiles) {
|
||||
val containingFile = element.containingFile.virtualFile
|
||||
return if (containingFile.path in sourceFiles) {
|
||||
sourceModule
|
||||
} else {
|
||||
sourceModule.directRegularDependencies.find { libModule ->
|
||||
(libModule as KtLibraryModuleByCompilerConfiguration).virtualFiles.any { it.path == containingFilePath }
|
||||
} ?: error("Can't find module for $containingFilePath")
|
||||
sourceModule.directRegularDependencies.find { libModule -> containingFile in libModule.contentScope }
|
||||
?: error("Can't find module for ${containingFile.path}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user