2
2
package com.jetbrains.ls.imports.jps
3
3
4
4
import com.intellij.openapi.application.PathManager
5
+ import com.intellij.openapi.diagnostic.fileLogger
5
6
import com.intellij.openapi.projectRoots.JavaSdk
7
+ import com.intellij.openapi.projectRoots.impl.JavaHomeFinder
8
+ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl
6
9
import com.intellij.openapi.roots.OrderRootType
10
+ import com.intellij.platform.eel.provider.getEelDescriptor
7
11
import com.intellij.platform.workspace.jps.entities.*
8
12
import com.intellij.platform.workspace.jps.entities.LibraryTableId.ProjectLibraryTableId
9
13
import com.intellij.platform.workspace.storage.MutableEntityStorage
@@ -15,14 +19,17 @@ import com.jetbrains.ls.imports.api.WorkspaceEntitySource
15
19
import com.jetbrains.ls.imports.api.WorkspaceImportException
16
20
import com.jetbrains.ls.imports.api.WorkspaceImporter
17
21
import com.jetbrains.ls.imports.utils.toIntellijUri
22
+ import org.jetbrains.jps.model.JpsElementFactory
23
+ import org.jetbrains.jps.model.JpsModel
18
24
import org.jetbrains.jps.model.java.*
19
25
import org.jetbrains.jps.model.library.JpsLibraryType
20
26
import org.jetbrains.jps.model.library.JpsOrderRootType
21
27
import org.jetbrains.jps.model.module.JpsLibraryDependency
22
28
import org.jetbrains.jps.model.module.JpsModuleDependency
23
29
import org.jetbrains.jps.model.module.JpsModuleSourceDependency
24
30
import 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
26
33
import org.jetbrains.kotlin.config.isHmpp
27
34
import org.jetbrains.kotlin.idea.facet.KotlinFacetType
28
35
import org.jetbrains.kotlin.idea.workspaceModel.KotlinSettingsEntity
@@ -33,15 +40,19 @@ import java.nio.file.Path
33
40
import kotlin.io.path.div
34
41
import kotlin.io.path.exists
35
42
43
+ private val LOG = fileLogger()
44
+
36
45
object JpsWorkspaceImporter : WorkspaceImporter {
37
46
override suspend fun importWorkspace (
38
47
projectDirectory : Path ,
39
48
virtualFileUrlManager : VirtualFileUrlManager ,
40
49
onUnresolvedDependency : (String ) -> Unit ,
41
50
): 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
+
45
56
val storage = MutableEntityStorage .create()
46
57
val entitySource = WorkspaceEntitySource (projectDirectory.toIntellijUri(virtualFileUrlManager))
47
58
val libs = mutableSetOf<String >()
@@ -183,6 +194,13 @@ object JpsWorkspaceImporter : WorkspaceImporter {
183
194
}
184
195
storage addEntity entity
185
196
}
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
+ }
186
204
model.global.libraryCollection.libraries.forEach { library ->
187
205
if (! sdks.contains(library.name)) return @forEach
188
206
when (library.type) {
@@ -225,6 +243,50 @@ object JpsWorkspaceImporter : WorkspaceImporter {
225
243
}
226
244
}
227
245
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
+
228
290
private fun JpsLibraryType <* >.toSdkType (): String = when (this ) {
229
291
is JpsJavaSdkType -> JavaSdk .getInstance().name
230
292
else -> toString()
0 commit comments