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
|
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.VfsUtilCore
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
|
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
|
||||||
@@ -22,8 +23,23 @@ object LibraryUtils {
|
|||||||
jar: Path,
|
jar: Path,
|
||||||
jarFileSystem: CoreJarFileSystem = CoreJarFileSystem(),
|
jarFileSystem: CoreJarFileSystem = CoreJarFileSystem(),
|
||||||
): Collection<VirtualFile> {
|
): 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>()
|
val files = mutableSetOf<VirtualFile>()
|
||||||
VfsUtilCore.iterateChildrenRecursively(
|
VfsUtilCore.iterateChildrenRecursively(
|
||||||
root,
|
root,
|
||||||
|
|||||||
+27
-12
@@ -55,38 +55,53 @@ internal class KtSourceModuleByCompilerConfiguration(
|
|||||||
jarFileSystem: CoreJarFileSystem,
|
jarFileSystem: CoreJarFileSystem,
|
||||||
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtSourceModule {
|
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtSourceModule {
|
||||||
override val directRegularDependencies: List<KtModule> by lazy {
|
override val directRegularDependencies: List<KtModule> by lazy {
|
||||||
(compilerConfig.jvmModularRoots + compilerConfig.jvmClasspathRoots).map {
|
val libraryRoots = compilerConfig.jvmModularRoots + compilerConfig.jvmClasspathRoots
|
||||||
KtLibraryModuleByCompilerConfiguration(compilerConfig, project, it.toPath(), jarFileSystem)
|
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)
|
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class KtLibraryModuleByCompilerConfiguration(
|
internal class KtLibraryModuleByCompilerConfiguration(
|
||||||
compilerConfig: CompilerConfiguration,
|
compilerConfig: CompilerConfiguration,
|
||||||
project: Project,
|
project: Project,
|
||||||
private val jar: Path,
|
virtualFilesProvider: () -> Collection<VirtualFile>,
|
||||||
jarFileSystem: CoreJarFileSystem,
|
private val root: Path,
|
||||||
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtLibraryModule {
|
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtLibraryModule {
|
||||||
override val directRegularDependencies: List<KtModule> get() = emptyList()
|
override val directRegularDependencies: List<KtModule> get() = emptyList()
|
||||||
|
|
||||||
internal val virtualFiles: Collection<VirtualFile> by lazy {
|
|
||||||
LibraryUtils.getAllVirtualFilesFromJar(jar, jarFileSystem)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val libraryName: String
|
override val libraryName: String
|
||||||
get() = moduleName
|
get() = moduleName
|
||||||
|
|
||||||
override val librarySources: KtLibrarySourceModule?
|
override val librarySources: KtLibrarySourceModule?
|
||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
override val contentScope: GlobalSearchScope =
|
override val contentScope: GlobalSearchScope by lazy {
|
||||||
GlobalSearchScope.filesScope(project, virtualFiles)
|
GlobalSearchScope.filesScope(project, virtualFilesProvider())
|
||||||
|
}
|
||||||
|
|
||||||
private val binaryRoots by lazy {
|
private val binaryRoots by lazy {
|
||||||
listOf(jar)
|
listOf(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBinaryRoots(): Collection<Path> = binaryRoots
|
override fun getBinaryRoots(): Collection<Path> = binaryRoots
|
||||||
|
|||||||
+5
-6
@@ -28,7 +28,7 @@ internal class ProjectStructureProviderByCompilerConfiguration(
|
|||||||
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
|
||||||
Files.walk(Paths.get(srcRoot))
|
Files.walk(path)
|
||||||
.filter(Files::isRegularFile)
|
.filter(Files::isRegularFile)
|
||||||
.forEach { add(it.toString()) }
|
.forEach { add(it.toString()) }
|
||||||
} else {
|
} else {
|
||||||
@@ -42,13 +42,12 @@ internal class ProjectStructureProviderByCompilerConfiguration(
|
|||||||
private val sourceModule = KtSourceModuleByCompilerConfiguration(compilerConfig, project, ktFiles, jarFileSystem)
|
private val sourceModule = KtSourceModuleByCompilerConfiguration(compilerConfig, project, ktFiles, jarFileSystem)
|
||||||
|
|
||||||
override fun getKtModuleForKtElement(element: PsiElement): KtModule {
|
override fun getKtModuleForKtElement(element: PsiElement): KtModule {
|
||||||
val containingFilePath = element.containingFile.virtualFile.path
|
val containingFile = element.containingFile.virtualFile
|
||||||
return if (containingFilePath in sourceFiles) {
|
return if (containingFile.path in sourceFiles) {
|
||||||
sourceModule
|
sourceModule
|
||||||
} else {
|
} else {
|
||||||
sourceModule.directRegularDependencies.find { libModule ->
|
sourceModule.directRegularDependencies.find { libModule -> containingFile in libModule.contentScope }
|
||||||
(libModule as KtLibraryModuleByCompilerConfiguration).virtualFiles.any { it.path == containingFilePath }
|
?: error("Can't find module for ${containingFile.path}")
|
||||||
} ?: error("Can't find module for $containingFilePath")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user