AA: add JDK_HOME as dependent SDK module
This commit is contained in:
committed by
Ilya Kirillov
parent
af32a65c78
commit
3f05ba04a9
+45
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.analysis.api.impl.base.util
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -13,7 +14,9 @@ import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.util.io.URLUtil.JAR_SEPARATOR
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.Properties
|
||||
|
||||
object LibraryUtils {
|
||||
/**
|
||||
@@ -83,4 +86,46 @@ object LibraryUtils {
|
||||
)
|
||||
return files
|
||||
}
|
||||
|
||||
// Copied (and adjusted) from JavaSdkImpl#readModulesFromReleaseFile
|
||||
private fun readModulesFromReleaseFile(jrtBaseDir: Path): List<String?>? {
|
||||
Files.newInputStream(jrtBaseDir.resolve("release")).use { stream ->
|
||||
val p = Properties()
|
||||
p.load(stream)
|
||||
val modules = p.getProperty("MODULES")
|
||||
if (modules != null) {
|
||||
return StringUtil.split(StringUtil.unquoteString(modules), " ")
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// Copied from JdkUtil#isModularRuntime
|
||||
private fun isModularRuntime(homePath: Path): Boolean {
|
||||
return Files.isRegularFile(homePath.resolve("lib/jrt-fs.jar")) || isExplodedModularRuntime(homePath)
|
||||
}
|
||||
|
||||
// Copied from JdkUtil#isExplodedModularRuntime
|
||||
private fun isExplodedModularRuntime(homePath: Path): Boolean {
|
||||
return Files.isDirectory(homePath.resolve("modules/java.base"))
|
||||
}
|
||||
|
||||
// Copied (and adjusted) from JavaSdkImpl#findClasses
|
||||
// Currently, handle modular runtime only
|
||||
fun findClassesFromJdkHome(jdkHome: Path): List<String> {
|
||||
val result = mutableListOf<String>()
|
||||
|
||||
if (isModularRuntime(jdkHome)) {
|
||||
val jrtBaseUrl: String = StandardFileSystems.JRT_PROTOCOL_PREFIX + jdkHome.toString() + JAR_SEPARATOR
|
||||
val modules = readModulesFromReleaseFile(jdkHome)
|
||||
if (modules != null) {
|
||||
for (module in modules) {
|
||||
result.add(jrtBaseUrl + module)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.sort()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
+8
-7
@@ -13,22 +13,23 @@ import com.intellij.openapi.vfs.VirtualFileSystem
|
||||
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.util.io.URLUtil
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
public interface AbstractDeclarationFromLibraryModuleProvider {
|
||||
public interface AbstractDeclarationFromBinaryModuleProvider {
|
||||
public val scope: GlobalSearchScope
|
||||
public val jarFileSystem: CoreJarFileSystem
|
||||
|
||||
public fun virtualFilesFromModule(
|
||||
libraryModule: KtLibraryModule,
|
||||
binaryModule: KtBinaryModule,
|
||||
fqName: FqName,
|
||||
isPackageName: Boolean,
|
||||
): Collection<VirtualFile> {
|
||||
val fqNameString = fqName.asString()
|
||||
val fs = StandardFileSystems.local()
|
||||
return libraryModule.getBinaryRoots().flatMap r@{ rootPath ->
|
||||
return binaryModule.getBinaryRoots().flatMap r@{ rootPath ->
|
||||
val root = findRoot(rootPath, fs) ?: return@r emptySet()
|
||||
val files = mutableSetOf<VirtualFile>()
|
||||
VfsUtilCore.iterateChildrenRecursively(
|
||||
@@ -68,10 +69,10 @@ public interface AbstractDeclarationFromLibraryModuleProvider {
|
||||
rootPath: Path,
|
||||
fs: VirtualFileSystem,
|
||||
): VirtualFile? {
|
||||
return if (rootPath.toFile().isDirectory) {
|
||||
fs.findFileByPath(rootPath.toAbsolutePath().toString())
|
||||
} else {
|
||||
return if (Files.isRegularFile(rootPath) && ".jar" in rootPath.toString()) {
|
||||
jarFileSystem.refreshAndFindFileByPath(rootPath.toAbsolutePath().toString() + URLUtil.JAR_SEPARATOR)
|
||||
} else {
|
||||
fs.findFileByPath(rootPath.toAbsolutePath().toString())
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@ class KtStaticModuleProvider(
|
||||
}.ktModule
|
||||
}
|
||||
|
||||
override fun getKtLibraryModules(): Collection<KtLibraryModule> {
|
||||
return testProjectStructure.allKtModules().filterIsInstance<KtLibraryModule>()
|
||||
override fun getKtBinaryModules(): Collection<KtBinaryModule> {
|
||||
return testProjectStructure.allKtModules().filterIsInstance<KtBinaryModule>()
|
||||
}
|
||||
|
||||
override fun getStdlibWithBuiltinsModule(module: KtModule): KtLibraryModule {
|
||||
|
||||
+31
-5
@@ -6,12 +6,13 @@
|
||||
package org.jetbrains.kotlin.analysis.project.structure.impl
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.ProjectScope
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibrarySourceModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||
import com.intellij.util.io.URLUtil
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.util.LibraryUtils
|
||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
internal abstract class BaseKtModuleByCompilerConfiguration(
|
||||
private val compilerConfig: CompilerConfiguration,
|
||||
@@ -51,7 +53,7 @@ internal class KtSourceModuleByCompilerConfiguration(
|
||||
project: Project,
|
||||
ktFiles: List<KtFile>,
|
||||
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtSourceModule {
|
||||
override val directRegularDependencies: List<KtLibraryModule> by lazy {
|
||||
override val directRegularDependencies: List<KtBinaryModule> by lazy {
|
||||
val libraryRoots = compilerConfig.jvmModularRoots + compilerConfig.jvmClasspathRoots
|
||||
val libraryRootsByType = libraryRoots.groupBy { it.isDirectory }
|
||||
buildList {
|
||||
@@ -69,6 +71,15 @@ internal class KtSourceModuleByCompilerConfiguration(
|
||||
add(KtLibraryModuleByCompilerConfiguration(compilerConfig, project, root))
|
||||
}
|
||||
}
|
||||
compilerConfig.get(JVMConfigurationKeys.JDK_HOME)?.let { jdkHome ->
|
||||
val vfm = VirtualFileManager.getInstance()
|
||||
val jdkHomePath = jdkHome.toPath()
|
||||
val jdkHomeVirtualFile = vfm.findFileByNioPath(jdkHomePath)
|
||||
val binaryRoots = LibraryUtils.findClassesFromJdkHome(jdkHomePath).map {
|
||||
Paths.get(URLUtil.extractPath(it))
|
||||
}
|
||||
add(KtSdkModuleByCompilerConfiguration(compilerConfig, project, "JDK", jdkHomeVirtualFile, binaryRoots))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,3 +109,18 @@ internal class KtLibraryModuleByCompilerConfiguration(
|
||||
|
||||
override fun getBinaryRoots(): Collection<Path> = binaryRoots
|
||||
}
|
||||
|
||||
internal class KtSdkModuleByCompilerConfiguration(
|
||||
compilerConfig: CompilerConfiguration,
|
||||
project: Project,
|
||||
override val sdkName: String,
|
||||
sdkHome: VirtualFile?,
|
||||
private val binaryRoots: Collection<Path>
|
||||
) : BaseKtModuleByCompilerConfiguration(compilerConfig, project), KtSdkModule {
|
||||
override val directRegularDependencies: List<KtModule> get() = emptyList()
|
||||
|
||||
override val contentScope: GlobalSearchScope =
|
||||
GlobalSearchScope.fileScope(project, sdkHome)
|
||||
|
||||
override fun getBinaryRoots(): Collection<Path> = binaryRoots
|
||||
}
|
||||
|
||||
+4
-3
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.project.structure.impl
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
|
||||
@@ -20,7 +21,7 @@ internal class KtModuleProviderByCompilerConfiguration(
|
||||
) : ProjectStructureProvider() {
|
||||
private val sourceModule = KtSourceModuleByCompilerConfiguration(compilerConfig, project, ktFiles)
|
||||
|
||||
private val libraryModules: Collection<KtLibraryModule> by lazy {
|
||||
private val binaryModules: Collection<KtBinaryModule> by lazy {
|
||||
sourceModule.directRegularDependencies
|
||||
}
|
||||
|
||||
@@ -34,8 +35,8 @@ internal class KtModuleProviderByCompilerConfiguration(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getKtLibraryModules(): Collection<KtLibraryModule> {
|
||||
return libraryModules
|
||||
override fun getKtBinaryModules(): Collection<KtBinaryModule> {
|
||||
return binaryModules
|
||||
}
|
||||
|
||||
override fun getStdlibWithBuiltinsModule(module: KtModule): KtLibraryModule? {
|
||||
|
||||
+2
-2
@@ -15,10 +15,10 @@ public abstract class ProjectStructureProvider {
|
||||
public abstract fun getKtModuleForKtElement(element: PsiElement): KtModule
|
||||
|
||||
/**
|
||||
* Returns all [KtLibraryModule]s in this project.
|
||||
* Returns all dependent [KtBinaryModule]s in this project.
|
||||
*/
|
||||
// TODO: We rather need a session or facade that maintains this information.
|
||||
public abstract fun getKtLibraryModules(): Collection<KtLibraryModule>
|
||||
public abstract fun getKtBinaryModules(): Collection<KtBinaryModule>
|
||||
|
||||
public abstract fun getStdlibWithBuiltinsModule(module: KtModule): KtLibraryModule?
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user