mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
[jps model] support loading project and module components in the new implementation (IJPL-409)
Data which is present in the workspace model is taken from it, other components are loaded from xml files as before. GitOrigin-RevId: 368e2b15aa055bc3489fb944c334379f10f2725e
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c6681283f6
commit
c0393d751a
@@ -25,11 +25,15 @@ public class JpsComponentLoader {
|
||||
protected final @Nullable Path myExternalConfigurationDirectory;
|
||||
private final JpsMacroExpander myMacroExpander;
|
||||
|
||||
public JpsComponentLoader(JpsMacroExpander macroExpander, @Nullable Path externalConfigurationDirectory) {
|
||||
public JpsComponentLoader(@NotNull JpsMacroExpander macroExpander, @Nullable Path externalConfigurationDirectory) {
|
||||
myMacroExpander = macroExpander;
|
||||
myExternalConfigurationDirectory = externalConfigurationDirectory;
|
||||
}
|
||||
|
||||
public @NotNull JpsMacroExpander getMacroExpander() {
|
||||
return myMacroExpander;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null if file doesn't exist
|
||||
*/
|
||||
@@ -37,10 +41,10 @@ public class JpsComponentLoader {
|
||||
return loadRootElement(file, myMacroExpander);
|
||||
}
|
||||
|
||||
protected <E extends JpsElement> void loadComponents(@NotNull Path dir,
|
||||
@NotNull Path defaultConfigFile,
|
||||
JpsElementExtensionSerializerBase<E> serializer,
|
||||
final E element) {
|
||||
public <E extends JpsElement> void loadComponents(@NotNull Path dir,
|
||||
@NotNull Path defaultConfigFile,
|
||||
JpsElementExtensionSerializerBase<E> serializer,
|
||||
E element) {
|
||||
String fileName = serializer.getConfigFileName();
|
||||
Path configFile = fileName == null ? defaultConfigFile : dir.resolve(fileName);
|
||||
Runnable timingLog = TimingLog.startActivity("loading: " + configFile.getFileName() + ":" + serializer.getComponentName());
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.jps.model.serialization;
|
||||
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -14,13 +16,12 @@ import org.jetbrains.jps.model.serialization.impl.JpsProjectSerializationDataExt
|
||||
import org.jetbrains.jps.model.serialization.runConfigurations.JpsRunConfigurationSerializer;
|
||||
import org.jetbrains.jps.util.JpsPathUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Contains helper methods which are used to load parts of the project configuration which aren't stored in the workspace model.
|
||||
@@ -136,9 +137,29 @@ public final class JpsProjectConfigurationLoading {
|
||||
String sdkName = rootManagerElement.getAttributeValue("project-jdk-name");
|
||||
String sdkTypeId = rootManagerElement.getAttributeValue("project-jdk-type");
|
||||
if (sdkName != null) {
|
||||
sdkTypeIdAndName = new Pair<>(sdkTypeId, sdkName);
|
||||
sdkTypeIdAndName = new Pair<>(Objects.requireNonNullElse(sdkTypeId, "JavaSDK"), sdkName);
|
||||
}
|
||||
}
|
||||
return sdkTypeIdAndName;
|
||||
}
|
||||
|
||||
public static JpsMacroExpander createModuleMacroExpander(final Map<String, String> pathVariables, @NotNull Path moduleFile) {
|
||||
JpsMacroExpander expander = new JpsMacroExpander(pathVariables);
|
||||
String moduleDirPath = PathMacroUtil.getModuleDir(moduleFile.toAbsolutePath().toString());
|
||||
if (moduleDirPath != null) {
|
||||
expander.addFileHierarchyReplacements(PathMacroUtil.MODULE_DIR_MACRO_NAME, new File(FileUtilRt.toSystemDependentName(moduleDirPath)));
|
||||
}
|
||||
return expander;
|
||||
}
|
||||
|
||||
public static @NotNull Set<String> readNamesOfUnloadedModules(@NotNull Path workspaceFile, @NotNull JpsComponentLoader componentLoader) {
|
||||
Set<String> unloadedModules = new HashSet<>();
|
||||
if (workspaceFile.toFile().exists()) {
|
||||
Element unloadedModulesList = JDomSerializationUtil.findComponent(componentLoader.loadRootElement(workspaceFile), "UnloadedModulesList");
|
||||
for (Element element : JDOMUtil.getChildren(unloadedModulesList, "module")) {
|
||||
unloadedModules.add(element.getAttributeValue("name"));
|
||||
}
|
||||
}
|
||||
return unloadedModules;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.jetbrains.jps.model.serialization.module.JpsModulePropertiesSerialize
|
||||
import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer;
|
||||
import org.jetbrains.jps.service.SharedThreadPool;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -248,13 +247,8 @@ public final class JpsProjectLoader {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<String> unloadedModules = new HashSet<>();
|
||||
if (!myLoadUnloadedModules && workspaceFile.toFile().exists()) {
|
||||
Element unloadedModulesList = JDomSerializationUtil.findComponent(myComponentLoader.loadRootElement(workspaceFile), "UnloadedModulesList");
|
||||
for (Element element : JDOMUtil.getChildren(unloadedModulesList, "module")) {
|
||||
unloadedModules.add(element.getAttributeValue("name"));
|
||||
}
|
||||
}
|
||||
Set<String> unloadedModules = !myLoadUnloadedModules ? JpsProjectConfigurationLoading.readNamesOfUnloadedModules(workspaceFile, myComponentLoader)
|
||||
: Collections.emptySet();
|
||||
|
||||
final Set<Path> foundFiles = CollectionFactory.createSmallMemoryFootprintSet();
|
||||
final List<Path> moduleFiles = new ArrayList<>();
|
||||
@@ -297,7 +291,7 @@ public final class JpsProjectLoader {
|
||||
|
||||
for (Path file : moduleFiles) {
|
||||
futureModuleFilesContents.add(CompletableFuture.supplyAsync(() -> {
|
||||
JpsMacroExpander expander = createModuleMacroExpander(pathVariables, file);
|
||||
JpsMacroExpander expander = JpsProjectConfigurationLoading.createModuleMacroExpander(pathVariables, file);
|
||||
|
||||
Element data = JpsComponentLoader.loadRootElement(file, expander);
|
||||
if (externalModuleDir != null) {
|
||||
@@ -409,7 +403,7 @@ public final class JpsProjectLoader {
|
||||
JpsModuleClasspathSerializer classpathSerializer = extension.getClasspathSerializer();
|
||||
if (classpathSerializer != null && classpathSerializer.getClasspathId().equals(classpath)) {
|
||||
String classpathDir = moduleRoot.getAttributeValue(CLASSPATH_DIR_ATTRIBUTE);
|
||||
final JpsMacroExpander expander = createModuleMacroExpander(pathVariables, file);
|
||||
final JpsMacroExpander expander = JpsProjectConfigurationLoading.createModuleMacroExpander(pathVariables, file);
|
||||
classpathSerializer.loadClasspath(module, classpathDir, baseModulePath, expander, paths, projectSdkType);
|
||||
}
|
||||
}
|
||||
@@ -434,15 +428,6 @@ public final class JpsProjectLoader {
|
||||
return FileUtilRt.getNameWithoutExtension(file.getFileName().toString());
|
||||
}
|
||||
|
||||
static JpsMacroExpander createModuleMacroExpander(final Map<String, String> pathVariables, @NotNull Path moduleFile) {
|
||||
JpsMacroExpander expander = new JpsMacroExpander(pathVariables);
|
||||
String moduleDirPath = PathMacroUtil.getModuleDir(moduleFile.toAbsolutePath().toString());
|
||||
if (moduleDirPath != null) {
|
||||
expander.addFileHierarchyReplacements(PathMacroUtil.MODULE_DIR_MACRO_NAME, new File(FileUtilRt.toSystemDependentName(moduleDirPath)));
|
||||
}
|
||||
return expander;
|
||||
}
|
||||
|
||||
private static <P extends JpsElement> JpsModule createModule(String name, Element moduleRoot, JpsModulePropertiesSerializer<P> loader) {
|
||||
String componentName = loader.getComponentName();
|
||||
Element component = componentName != null ? JDomSerializationUtil.findComponent(moduleRoot, componentName) : null;
|
||||
|
||||
@@ -27,7 +27,7 @@ public final class JpsSerializationManagerImpl extends JpsSerializationManager {
|
||||
boolean loadUnloadedModules) throws IOException {
|
||||
JpsSerializationViaWorkspaceModel serializationViaWorkspaceModel = JpsSerializationViaWorkspaceModel.getInstance();
|
||||
if (serializationViaWorkspaceModel != null) {
|
||||
return serializationViaWorkspaceModel.loadModel(projectPath, optionsPath, loadUnloadedModules);
|
||||
return serializationViaWorkspaceModel.loadModel(projectPath, externalConfigurationDirectory, optionsPath, loadUnloadedModules);
|
||||
}
|
||||
|
||||
JpsModel model = JpsElementFactory.getInstance().createModel();
|
||||
@@ -61,7 +61,7 @@ public final class JpsSerializationManagerImpl extends JpsSerializationManager {
|
||||
boolean loadUnloadedModules) throws IOException {
|
||||
JpsSerializationViaWorkspaceModel serializationViaWorkspaceModel = JpsSerializationViaWorkspaceModel.getInstance();
|
||||
if (serializationViaWorkspaceModel != null) {
|
||||
return serializationViaWorkspaceModel.loadProject(projectPath, pathVariables, loadUnloadedModules);
|
||||
return serializationViaWorkspaceModel.loadProject(projectPath, externalConfigurationDirectory, pathVariables, loadUnloadedModules);
|
||||
}
|
||||
|
||||
JpsModel model = JpsElementFactory.getInstance().createModel();
|
||||
|
||||
@@ -26,8 +26,10 @@ public interface JpsSerializationViaWorkspaceModel {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull JpsModel loadModel(@NotNull Path projectPath, @Nullable Path optionsPath, boolean loadUnloadedModules) throws IOException;
|
||||
@NotNull JpsModel loadModel(@NotNull Path projectPath,
|
||||
@Nullable Path externalConfigurationDirectory,
|
||||
@Nullable Path optionsPath, boolean loadUnloadedModules) throws IOException;
|
||||
|
||||
@NotNull JpsProject loadProject(@NotNull Path projectPath, @NotNull Map<String, String> pathVariables,
|
||||
@NotNull JpsProject loadProject(@NotNull Path projectPath, @Nullable Path externalConfigurationDirectory, @NotNull Map<String, String> pathVariables,
|
||||
boolean loadUnloadedModules) throws IOException;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ internal class JpsModelBridge(
|
||||
private val project: JpsProjectBridge = JpsProjectBridge(this, projectStorage, projectAdditionalData);
|
||||
private val global: JpsGlobalBridge = JpsGlobalBridge(this, globalStorage);
|
||||
|
||||
override fun getProject(): JpsProject = project
|
||||
override fun getProject(): JpsProjectBridge = project
|
||||
|
||||
override fun getGlobal(): JpsGlobal = global
|
||||
override fun getGlobal(): JpsGlobalBridge = global
|
||||
}
|
||||
@@ -33,7 +33,7 @@ internal class JpsProjectBridge(modelBridge: JpsModelBridge,
|
||||
}
|
||||
private val sdkReferencesTable = JpsSdkReferencesTableBridge(additionalData.projectSdkId, this)
|
||||
|
||||
override fun getModules(): List<JpsModule> = modules
|
||||
override fun getModules(): List<JpsModuleBridge> = modules
|
||||
|
||||
override fun <P : JpsElement?> getModules(type: JpsModuleType<P>): Iterable<JpsTypedModule<P>> {
|
||||
return modules.asSequence()
|
||||
|
||||
@@ -10,7 +10,10 @@ import org.jetbrains.jps.model.serialization.JpsMacroExpander
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
import kotlin.io.path.Path
|
||||
|
||||
internal class DirectJpsFileContentReader(private val macroExpander: JpsMacroExpander) : JpsFileContentReader {
|
||||
/**
|
||||
* Loads global settings used in the workspace model directly from XML configuration files.
|
||||
*/
|
||||
internal class GlobalDirectJpsFileContentReader(private val macroExpander: JpsMacroExpander) : JpsFileContentReader {
|
||||
private val componentLoader = JpsComponentLoader(macroExpander, null)
|
||||
|
||||
override fun loadComponent(fileUrl: String, componentName: String, customModuleFilePath: String?): Element? {
|
||||
@@ -2,70 +2,114 @@
|
||||
package com.intellij.platform.workspace.jps.bridge.impl.serialization
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.platform.workspace.jps.JpsProjectConfigLocation
|
||||
import com.intellij.platform.workspace.jps.JpsProjectFileEntitySource
|
||||
import com.intellij.platform.workspace.jps.UnloadedModulesNameHolder
|
||||
import com.intellij.platform.workspace.jps.bridge.impl.JpsModelBridge
|
||||
import com.intellij.platform.workspace.jps.bridge.impl.JpsProjectAdditionalData
|
||||
import com.intellij.platform.workspace.jps.bridge.impl.JpsProjectBridge
|
||||
import com.intellij.platform.workspace.jps.bridge.impl.library.sdk.JpsSdkLibraryBridge
|
||||
import com.intellij.platform.workspace.jps.serialization.impl.ErrorReporter
|
||||
import com.intellij.platform.workspace.jps.serialization.impl.JpsGlobalEntitiesSerializers
|
||||
import com.intellij.platform.workspace.jps.serialization.impl.JpsProjectEntitiesLoader
|
||||
import com.intellij.platform.workspace.jps.bridge.impl.module.JpsModuleBridge
|
||||
import com.intellij.platform.workspace.jps.entities.SdkId
|
||||
import com.intellij.platform.workspace.jps.entities.customImlData
|
||||
import com.intellij.platform.workspace.jps.entities.exModuleOptions
|
||||
import com.intellij.platform.workspace.jps.serialization.impl.*
|
||||
import com.intellij.platform.workspace.jps.serialization.impl.toConfigLocation
|
||||
import com.intellij.platform.workspace.storage.EntityStorage
|
||||
import com.intellij.platform.workspace.storage.MutableEntityStorage
|
||||
import com.intellij.platform.workspace.storage.impl.url.VirtualFileUrlManagerImpl
|
||||
import com.intellij.platform.workspace.storage.url.VirtualFileUrl
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.jps.model.JpsModel
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.jps.model.serialization.JpsGlobalLoader
|
||||
import org.jetbrains.jps.model.serialization.JpsGlobalSettingsLoading
|
||||
import org.jetbrains.jps.model.serialization.JpsMacroExpander
|
||||
import org.jetbrains.jps.model.serialization.*
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectConfigurationLoading.*
|
||||
import org.jetbrains.jps.model.serialization.impl.JpsModuleSerializationDataExtensionImpl
|
||||
import org.jetbrains.jps.model.serialization.impl.JpsSerializationViaWorkspaceModel
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.Path
|
||||
|
||||
internal class JpsSerializationViaWorkspaceModelImpl : JpsSerializationViaWorkspaceModel {
|
||||
override fun loadModel(projectPath: Path, optionsPath: Path?, loadUnloadedModules: Boolean): JpsModel {
|
||||
override fun loadModel(projectPath: Path, externalConfigurationDirectory: Path?, optionsPath: Path?, loadUnloadedModules: Boolean): JpsModel {
|
||||
val virtualFileUrlManager = VirtualFileUrlManagerImpl()
|
||||
val errorReporter = object : ErrorReporter {
|
||||
override fun reportError(message: String, file: VirtualFileUrl) {
|
||||
error(message)
|
||||
}
|
||||
}
|
||||
|
||||
val errorReporter = createErrorReporter()
|
||||
val globalStorage = MutableEntityStorage.create()
|
||||
val globalMacroExpander = if (optionsPath != null) {
|
||||
val (globalMacroExpander, pathVariables) = if (optionsPath != null) {
|
||||
loadGlobalStorage(optionsPath, virtualFileUrlManager, errorReporter, globalStorage)
|
||||
}
|
||||
else {
|
||||
null
|
||||
null to emptyMap()
|
||||
}
|
||||
|
||||
val (projectStorage, additionalData) = loadProjectStorage(projectPath, virtualFileUrlManager, errorReporter)
|
||||
val model = JpsModelBridge(projectStorage, globalStorage, additionalData)
|
||||
|
||||
|
||||
val model = loadProject(projectPath, externalConfigurationDirectory, virtualFileUrlManager, pathVariables, errorReporter, globalStorage,
|
||||
loadUnloadedModules)
|
||||
|
||||
if (optionsPath != null) {
|
||||
val globalLoader = JpsGlobalLoader(globalMacroExpander!!, model.global, arrayOf(JpsGlobalLoader.FILE_TYPES_SERIALIZER))
|
||||
globalLoader.load(optionsPath)
|
||||
}
|
||||
|
||||
return model
|
||||
}
|
||||
|
||||
private fun loadProjectStorage(projectPath: Path, virtualFileUrlManager: VirtualFileUrlManagerImpl, errorReporter: ErrorReporter): Pair<EntityStorage, JpsProjectAdditionalData> {
|
||||
private fun loadProject(
|
||||
projectPath: Path,
|
||||
externalConfigurationDirectory: Path?,
|
||||
virtualFileUrlManager: VirtualFileUrlManagerImpl,
|
||||
pathVariables: Map<String, String>,
|
||||
errorReporter: ErrorReporter,
|
||||
globalStorage: EntityStorage,
|
||||
loadUnloadedModules: Boolean,
|
||||
): JpsModelBridge {
|
||||
val configLocation = toConfigLocation(projectPath, virtualFileUrlManager)
|
||||
val externalStoragePath = Path("")//todo
|
||||
val context = SerializationContextImpl(virtualFileUrlManager)
|
||||
val contentReader = ProjectDirectJpsFileContentReader(configLocation.baseDirectoryUrl.toPath(), externalConfigurationDirectory, pathVariables)
|
||||
val (projectStorage, additionalData) = loadProjectStorage(virtualFileUrlManager, errorReporter, configLocation, contentReader, loadUnloadedModules)
|
||||
val model = JpsModelBridge(projectStorage, globalStorage, additionalData)
|
||||
|
||||
loadOtherProjectComponents(model.project, contentReader.projectComponentLoader, configLocation, externalConfigurationDirectory)
|
||||
loadOtherModuleComponents(model.project)
|
||||
return model
|
||||
}
|
||||
|
||||
private fun createErrorReporter() = object : ErrorReporter {
|
||||
override fun reportError(message: String, file: VirtualFileUrl) {
|
||||
throw CannotLoadJpsModelException(file.toPath().toFile(), message, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadProjectStorage(
|
||||
virtualFileUrlManager: VirtualFileUrlManagerImpl, errorReporter: ErrorReporter,
|
||||
configLocation: JpsProjectConfigLocation, fileContentReader: ProjectDirectJpsFileContentReader, loadUnloadedModules: Boolean,
|
||||
): Pair<EntityStorage, JpsProjectAdditionalData> {
|
||||
/* JpsProjectEntitiesLoader requires non-null value of externalStoragePath even if the external storage is not used, so use some
|
||||
artificial path if it isn't specified; externalStoragePath will be eliminated when IJPL-10518 is fixed
|
||||
*/
|
||||
val externalStoragePath = fileContentReader.externalConfigurationDirectory
|
||||
?: configLocation.baseDirectoryUrl.toPath().resolve("fake_external_build_system")
|
||||
|
||||
val context = SerializationContextImpl(virtualFileUrlManager, fileContentReader)
|
||||
val serializers = JpsProjectEntitiesLoader.createProjectSerializers(configLocation, externalStoragePath, context)
|
||||
val mainStorage = MutableEntityStorage.create()
|
||||
val orphanageStorage = MutableEntityStorage.create()
|
||||
val unloadedStorage = MutableEntityStorage.create()
|
||||
val unloadedModuleNames = UnloadedModulesNameHolder.DUMMY
|
||||
val unloadedModuleNames = if (loadUnloadedModules) UnloadedModulesNameHolder.DUMMY else JpsUnloadedModulesNameHolder(readNamesOfUnloadedModules(configLocation.workspaceFile, fileContentReader.projectComponentLoader))
|
||||
@Suppress("SSBasedInspection")
|
||||
runBlocking {
|
||||
serializers.loadAll(context.fileContentReader, mainStorage, orphanageStorage, unloadedStorage, unloadedModuleNames, errorReporter)
|
||||
}
|
||||
|
||||
return mainStorage to JpsProjectAdditionalData(TODO(), TODO())
|
||||
|
||||
val projectName = when (configLocation) {
|
||||
is JpsProjectConfigLocation.DirectoryBased -> getDirectoryBaseProjectName(configLocation.ideaFolder.toPath())
|
||||
is JpsProjectConfigLocation.FileBased -> FileUtil.getNameWithoutExtension(configLocation.iprFile.fileName)
|
||||
}
|
||||
val projectRootComponentFileElement = when (configLocation) {
|
||||
is JpsProjectConfigLocation.DirectoryBased -> fileContentReader.projectComponentLoader.loadRootElement(configLocation.ideaFolder.toPath().resolve("misc.xml"))
|
||||
is JpsProjectConfigLocation.FileBased -> fileContentReader.projectComponentLoader.loadRootElement(configLocation.iprFile.toPath())
|
||||
}
|
||||
val projectSdkId = readProjectSdkTypeAndName(projectRootComponentFileElement)?.let {
|
||||
SdkId(name = it.second, type = it.first)
|
||||
}
|
||||
return mainStorage to JpsProjectAdditionalData(projectName, projectSdkId)
|
||||
}
|
||||
|
||||
private fun loadGlobalStorage(
|
||||
@@ -73,9 +117,10 @@ internal class JpsSerializationViaWorkspaceModelImpl : JpsSerializationViaWorksp
|
||||
virtualFileUrlManager: VirtualFileUrlManagerImpl,
|
||||
errorReporter: ErrorReporter,
|
||||
globalStorage: MutableEntityStorage,
|
||||
): JpsMacroExpander {
|
||||
val macroExpander = JpsMacroExpander(JpsGlobalSettingsLoading.computeAllPathVariables(optionsPath))
|
||||
val reader = DirectJpsFileContentReader(macroExpander)
|
||||
): Pair<JpsMacroExpander, Map<String, String>> {
|
||||
val pathVariables = JpsGlobalSettingsLoading.computeAllPathVariables(optionsPath)
|
||||
val macroExpander = JpsMacroExpander(pathVariables)
|
||||
val reader = GlobalDirectJpsFileContentReader(macroExpander)
|
||||
val rootsTypes = JpsSdkLibraryBridge.serializers.map { it.typeId }
|
||||
val serializers = JpsGlobalEntitiesSerializers.createApplicationSerializers(virtualFileUrlManager, rootsTypes)
|
||||
for (serializer in serializers) {
|
||||
@@ -83,10 +128,79 @@ internal class JpsSerializationViaWorkspaceModelImpl : JpsSerializationViaWorksp
|
||||
serializer.checkAndAddToBuilder(globalStorage, globalStorage, loaded.data)
|
||||
loaded.exception?.let { throw it }
|
||||
}
|
||||
return macroExpander
|
||||
return macroExpander to pathVariables
|
||||
}
|
||||
|
||||
override fun loadProject(projectPath: Path, pathVariables: Map<String, String>, loadUnloadedModules: Boolean): JpsProject {
|
||||
TODO("not implemented")
|
||||
override fun loadProject(projectPath: Path, externalConfigurationDirectory: Path?, pathVariables: Map<String, String>, loadUnloadedModules: Boolean): JpsProject {
|
||||
val model = loadProject(projectPath, externalConfigurationDirectory, VirtualFileUrlManagerImpl(), pathVariables, createErrorReporter(),
|
||||
MutableEntityStorage.create(), loadUnloadedModules)
|
||||
return model.project
|
||||
}
|
||||
|
||||
private fun loadOtherProjectComponents(project: JpsProject, componentLoader: JpsComponentLoader, configLocation: JpsProjectConfigLocation, externalStoragePath: Path?) {
|
||||
setupSerializationExtension(project, configLocation.baseDirectoryUrl.toPath())
|
||||
when (configLocation) {
|
||||
is JpsProjectConfigLocation.DirectoryBased -> {
|
||||
val dotIdea = configLocation.ideaFolder.toPath()
|
||||
val defaultConfigFile = dotIdea.resolve("misc.xml")
|
||||
for (extension in JpsModelSerializerExtension.getExtensions()) {
|
||||
for (serializer in extension.projectExtensionSerializers) {
|
||||
componentLoader.loadComponents(dotIdea, defaultConfigFile, serializer, project)
|
||||
}
|
||||
}
|
||||
loadArtifactsFromDirectory(project, componentLoader, dotIdea, externalStoragePath)
|
||||
loadRunConfigurationsFromDirectory(project, componentLoader, dotIdea, configLocation.workspaceFile)
|
||||
}
|
||||
is JpsProjectConfigLocation.FileBased -> {
|
||||
val iprFile = configLocation.iprFile.toPath()
|
||||
val iprRoot = componentLoader.loadRootElement(iprFile)
|
||||
val iwsRoot = componentLoader.loadRootElement(configLocation.workspaceFile)
|
||||
loadProjectExtensionsFromIpr(project, iprRoot, iwsRoot)
|
||||
loadArtifactsFromIpr(project, iprRoot)
|
||||
loadRunConfigurationsFromIpr(project, iprRoot, iwsRoot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadOtherModuleComponents(project: JpsProjectBridge) {
|
||||
project.modules.forEach { module ->
|
||||
loadOtherModuleComponents(module)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadOtherModuleComponents(module: JpsModuleBridge) {
|
||||
val moduleEntity = module.entity
|
||||
val entitySource = moduleEntity.entitySource
|
||||
if (entitySource is JpsProjectFileEntitySource.FileInDirectory) {
|
||||
module.container.setChild(JpsModuleSerializationDataExtensionImpl.ROLE,
|
||||
JpsModuleSerializationDataExtensionImpl(entitySource.directory.toPath()))
|
||||
}
|
||||
|
||||
for (serializerExtension in JpsModelSerializerExtension.getExtensions()) {
|
||||
val rootElement = Element("module")
|
||||
//todo is it enough?
|
||||
moduleEntity.customImlData?.customModuleOptions?.forEach { (key, value) ->
|
||||
rootElement.setAttribute(key, value)
|
||||
}
|
||||
moduleEntity.exModuleOptions?.let { externalSystemOptions ->
|
||||
externalSystemOptions.externalSystem?.let {
|
||||
rootElement.setAttribute("external.system.id", it)
|
||||
rootElement.setAttribute("ExternalSystem", it)
|
||||
}
|
||||
}
|
||||
serializerExtension.loadModuleOptions(module, rootElement)
|
||||
}
|
||||
}
|
||||
|
||||
private val JpsProjectConfigLocation.workspaceFile: Path
|
||||
get() = when (this) {
|
||||
is JpsProjectConfigLocation.DirectoryBased -> ideaFolder.toPath().resolve("workspace.xml")
|
||||
is JpsProjectConfigLocation.FileBased -> iprFileParent.toPath().resolve("${iprFile.fileName.substringBeforeLast('.')}.iws")
|
||||
}
|
||||
}
|
||||
|
||||
private class JpsUnloadedModulesNameHolder(private val unloadedModuleNames: Set<String>) : UnloadedModulesNameHolder {
|
||||
override fun isUnloaded(name: String): Boolean = unloadedModuleNames.contains(name)
|
||||
|
||||
override fun hasUnloaded(): Boolean = unloadedModuleNames.isNotEmpty()
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.platform.workspace.jps.bridge.impl.serialization
|
||||
|
||||
import com.intellij.openapi.components.ExpandMacroToPathMap
|
||||
import com.intellij.platform.workspace.jps.serialization.impl.JpsFileContentReader
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.jps.model.serialization.JDomSerializationUtil
|
||||
import org.jetbrains.jps.model.serialization.JpsComponentLoader
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectConfigurationLoading
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectConfigurationLoading.createProjectMacroExpander
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.Path
|
||||
|
||||
/**
|
||||
* Loads data of module-level and project-level components directly from XML and iml configuration files.
|
||||
*/
|
||||
internal class ProjectDirectJpsFileContentReader(
|
||||
projectBaseDir: Path,
|
||||
val externalConfigurationDirectory: Path?,
|
||||
private val pathVariables: Map<String, String>
|
||||
) : JpsFileContentReader {
|
||||
|
||||
private val projectMacroExpander = createProjectMacroExpander(pathVariables, projectBaseDir)
|
||||
val projectComponentLoader = JpsComponentLoader(projectMacroExpander, externalConfigurationDirectory)
|
||||
|
||||
override fun loadComponent(fileUrl: String, componentName: String, customModuleFilePath: String?): Element? {
|
||||
if (fileUrl.endsWith(".iml")) {
|
||||
//todo support external storage
|
||||
val loader = getModuleLoader(fileUrl)
|
||||
return JDomSerializationUtil.findComponent(loader.loadRootElement(Path(JpsPathUtil.urlToPath(fileUrl))), componentName)
|
||||
}
|
||||
return loadProjectLevelComponent(fileUrl, componentName)
|
||||
}
|
||||
|
||||
private fun loadProjectLevelComponent(fileUrl: String, componentName: String): Element? {
|
||||
val rootElement = projectComponentLoader.loadRootElement(Path(JpsPathUtil.urlToPath(fileUrl))) ?: return null
|
||||
if (rootElement.name == JDomSerializationUtil.COMPONENT_ELEMENT && JDomSerializationUtil.isComponent(componentName, rootElement)) {
|
||||
return rootElement
|
||||
}
|
||||
return JDomSerializationUtil.findComponent(rootElement, componentName)
|
||||
}
|
||||
|
||||
override fun getExpandMacroMap(fileUrl: String): ExpandMacroToPathMap {
|
||||
if (fileUrl.endsWith(".iml")) {
|
||||
return getModuleLoader(fileUrl).macroExpander.expandMacroMap
|
||||
}
|
||||
return projectMacroExpander.expandMacroMap
|
||||
}
|
||||
|
||||
private fun getModuleLoader(imlFileUrl: String): JpsComponentLoader {
|
||||
val moduleFile = Path(JpsPathUtil.urlToPath(imlFileUrl))
|
||||
val macroExpander = JpsProjectConfigurationLoading.createModuleMacroExpander(pathVariables, moduleFile)
|
||||
//todo cache
|
||||
return JpsComponentLoader(macroExpander, null)
|
||||
}
|
||||
}
|
||||
@@ -7,23 +7,24 @@ import com.intellij.platform.workspace.jps.serialization.impl.*
|
||||
import com.intellij.platform.workspace.storage.url.VirtualFileUrlManager
|
||||
|
||||
internal class SerializationContextImpl(
|
||||
override val virtualFileUrlManager: VirtualFileUrlManager
|
||||
override val virtualFileUrlManager: VirtualFileUrlManager,
|
||||
override val fileContentReader: JpsFileContentReader,
|
||||
) : SerializationContext {
|
||||
|
||||
override val fileContentReader: JpsFileContentReader
|
||||
get() = TODO("not implemented")
|
||||
|
||||
override val isExternalStorageEnabled: Boolean
|
||||
get() = false //todo
|
||||
override val fileInDirectorySourceNames: FileInDirectorySourceNames
|
||||
get() = FileInDirectorySourceNames.empty()
|
||||
|
||||
override val isJavaPluginPresent: Boolean
|
||||
get() = true //todo?
|
||||
get() = true
|
||||
|
||||
override val customModuleComponentSerializers: List<CustomModuleComponentSerializer>
|
||||
get() = emptyList() //todo
|
||||
|
||||
override val customModuleRootsSerializers: List<CustomModuleRootsSerializer>
|
||||
get() = emptyList() //todo
|
||||
|
||||
override val customFacetRelatedEntitySerializers: List<CustomFacetRelatedEntitySerializer<*>>
|
||||
get() = listOf(DefaultFacetEntitySerializer()) //todo
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user