22package com.jetbrains.ls.imports.jps
33
44import com.intellij.openapi.application.PathManager
5+ import com.intellij.openapi.diagnostic.fileLogger
56import com.intellij.openapi.projectRoots.JavaSdk
7+ import com.intellij.openapi.projectRoots.impl.JavaHomeFinder
8+ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl
69import com.intellij.openapi.roots.OrderRootType
10+ import com.intellij.platform.eel.provider.getEelDescriptor
711import com.intellij.platform.workspace.jps.entities.*
812import com.intellij.platform.workspace.jps.entities.LibraryTableId.ProjectLibraryTableId
913import com.intellij.platform.workspace.storage.MutableEntityStorage
@@ -15,14 +19,17 @@ import com.jetbrains.ls.imports.api.WorkspaceEntitySource
1519import com.jetbrains.ls.imports.api.WorkspaceImportException
1620import com.jetbrains.ls.imports.api.WorkspaceImporter
1721import com.jetbrains.ls.imports.utils.toIntellijUri
22+ import org.jetbrains.jps.model.JpsElementFactory
23+ import org.jetbrains.jps.model.JpsModel
1824import org.jetbrains.jps.model.java.*
1925import org.jetbrains.jps.model.library.JpsLibraryType
2026import org.jetbrains.jps.model.library.JpsOrderRootType
2127import org.jetbrains.jps.model.module.JpsLibraryDependency
2228import org.jetbrains.jps.model.module.JpsModuleDependency
2329import org.jetbrains.jps.model.module.JpsModuleSourceDependency
2430import org.jetbrains.jps.model.module.JpsSdkDependency
25- import org.jetbrains.jps.model.serialization.JpsSerializationManager
31+ import org.jetbrains.jps.model.serialization.*
32+ import org.jetbrains.jps.model.serialization.impl.JpsPathVariablesConfigurationImpl
2633import org.jetbrains.kotlin.config.isHmpp
2734import org.jetbrains.kotlin.idea.facet.KotlinFacetType
2835import org.jetbrains.kotlin.idea.workspaceModel.KotlinSettingsEntity
@@ -33,15 +40,19 @@ import java.nio.file.Path
3340import kotlin.io.path.div
3441import kotlin.io.path.exists
3542
43+ private val LOG = fileLogger()
44+
3645object JpsWorkspaceImporter : WorkspaceImporter {
3746 override suspend fun importWorkspace (
3847 projectDirectory : Path ,
3948 virtualFileUrlManager : VirtualFileUrlManager ,
4049 onUnresolvedDependency : (String ) -> Unit ,
4150 ): MutableEntityStorage = try {
42- val optionsDirectory = Path .of(System .getProperty(
43- " idea.config.path.original" , PathManager .getConfigPath())) / PathManager .OPTIONS_DIRECTORY
44- val model = JpsSerializationManager .getInstance().loadModel(projectDirectory, null , optionsDirectory, true )
51+ val model = JpsElementFactory .getInstance().createModel()
52+ initGlobalJpsOptions(model)
53+ val pathVariables = JpsModelSerializationDataService .computeAllPathVariables(model.global)
54+ JpsProjectLoader .loadProject(model.getProject(), pathVariables, model.getGlobal().getPathMapper(), projectDirectory, true , null )
55+
4556 val storage = MutableEntityStorage .create()
4657 val entitySource = WorkspaceEntitySource (projectDirectory.toIntellijUri(virtualFileUrlManager))
4758 val libs = mutableSetOf<String >()
@@ -183,6 +194,13 @@ object JpsWorkspaceImporter : WorkspaceImporter {
183194 }
184195 storage addEntity entity
185196 }
197+ if (model.global.libraryCollection.libraries.isEmpty()) {
198+ detectJavaSdks(projectDirectory, sdks, virtualFileUrlManager, entitySource).forEach { builder ->
199+ val entity = storage addEntity builder
200+ // for KaLibrarySdkModuleImpl
201+ storage.mutableSdkMap.addMapping(entity, SdkBridgeImpl (builder))
202+ }
203+ }
186204 model.global.libraryCollection.libraries.forEach { library ->
187205 if (! sdks.contains(library.name)) return @forEach
188206 when (library.type) {
@@ -225,6 +243,50 @@ object JpsWorkspaceImporter : WorkspaceImporter {
225243 }
226244}
227245
246+ private fun detectJavaSdks (
247+ projectDirectory : Path ,
248+ sdks : Collection <String >,
249+ virtualFileUrlManager : VirtualFileUrlManager ,
250+ entitySource : WorkspaceEntitySource ,
251+ ): List <SdkEntity .Builder > {
252+ val detectedSdks = JavaHomeFinder .findJdks(projectDirectory.getEelDescriptor(), false )
253+ if (detectedSdks.isEmpty()) return emptyList()
254+ return sdks.map { sdkName ->
255+ val sdk = detectedSdks.find {
256+ val suggestedName = it.versionInfo?.suggestedName()
257+ suggestedName != null && sdkName.contains(suggestedName, ignoreCase = true )
258+ } ? : detectedSdks.maxBy { it.versionInfo?.version?.feature ? : 0 }
259+ LOG .info(" Detected SDK [$sdkName ]: ${sdk.path} " )
260+ SdkEntity (
261+ name = sdkName,
262+ type = JavaSdk .getInstance().name,
263+ roots = JavaSdkImpl .findClasses(Path .of(sdk.path), false ).map { (it.replace(" !/" , " !/modules/" )) }
264+ .map {
265+ SdkRoot (
266+ virtualFileUrlManager.getOrCreateFromUrl(it),
267+ SdkRootTypeId (OrderRootType .CLASSES .customName),
268+ )
269+ },
270+ additionalData = " " ,
271+ entitySource = entitySource
272+ )
273+ }
274+ }
275+
276+ private fun initGlobalJpsOptions (model : JpsModel ) {
277+ System .getProperty(" idea.config.path.original" )?.let {
278+ val optionsDir = Path .of(it) / PathManager .OPTIONS_DIRECTORY
279+ JpsGlobalSettingsLoading .loadGlobalSettings(model.global, optionsDir)
280+ return
281+ }
282+ val configuration = model.global.getContainer().setChild(
283+ JpsGlobalLoader .PATH_VARIABLES_ROLE , JpsPathVariablesConfigurationImpl ()
284+ )
285+ val mavenPath = JpsMavenSettings .getMavenRepositoryPath()
286+ configuration.addPathVariable(" MAVEN_REPOSITORY" , mavenPath)
287+ LOG .info(" Detected Maven repo: $mavenPath " )
288+ }
289+
228290private fun JpsLibraryType <* >.toSdkType (): String = when (this ) {
229291 is JpsJavaSdkType -> JavaSdk .getInstance().name
230292 else -> toString()
0 commit comments