From 266295558f2616f7270dec0983549c60bbe85d2b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 21 Nov 2017 14:35:32 +0100 Subject: [PATCH] make ExternalCompilerConfiguration available for JPS --- .../ExternalCompilerConfigurationStorage.kt | 2 +- .../jps/model/serialization/JpsLoaderBase.java | 2 +- .../model/serialization/JpsProjectLoader.java | 17 +++++++++++++++++ .../src/ProjectStateStorageManager.kt | 5 +++-- .../src/StateStorageManagerImpl.kt | 2 +- .../configurationStore/ExternalSystemStorage.kt | 11 ++++------- .../src/com/intellij/openapi/util/JDOMUtil.java | 6 ++++++ 7 files changed, 33 insertions(+), 12 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/ExternalCompilerConfigurationStorage.kt b/java/compiler/impl/src/com/intellij/compiler/ExternalCompilerConfigurationStorage.kt index 14f7feab2f0c..c7e85cefed90 100644 --- a/java/compiler/impl/src/com/intellij/compiler/ExternalCompilerConfigurationStorage.kt +++ b/java/compiler/impl/src/com/intellij/compiler/ExternalCompilerConfigurationStorage.kt @@ -16,7 +16,7 @@ import org.jdom.Element import org.jetbrains.jps.model.serialization.java.compiler.JpsJavaCompilerConfigurationSerializer import java.util.* -@State(name = "ExternalCompilerConfigurationStorage", storages = arrayOf(Storage("compiler.xml")), externalStorageOnly = true) +@State(name = "ExternalCompilerConfiguration", storages = arrayOf(Storage("compiler.xml")), externalStorageOnly = true) internal class ExternalCompilerConfigurationStorage(private val project: Project) : PersistentStateComponent, ProjectModelElement { var loadedState: Map? = null private set diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLoaderBase.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLoaderBase.java index ebe2263a932c..cd25611379f5 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLoaderBase.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLoaderBase.java @@ -54,7 +54,7 @@ public abstract class JpsLoaderBase { } @Nullable - private Element loadComponentData(@NotNull JpsElementExtensionSerializerBase serializer, Path configFile) { + protected Element loadComponentData(@NotNull JpsElementExtensionSerializerBase serializer, @NotNull Path configFile) { return JDomSerializationUtil.findComponent(loadRootElement(configFile), serializer.getComponentName()); } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java index 73ae4db6bab1..0e83777310ca 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java @@ -116,6 +116,23 @@ public class JpsProjectLoader extends JpsLoaderBase { return super.loadRootElement(file); } + @Nullable + @Override + protected Element loadComponentData(@NotNull JpsElementExtensionSerializerBase serializer, @NotNull Path configFile) { + Path externalConfigDir = resolveExternalProjectConfig("project"); + Element data = super.loadComponentData(serializer, configFile); + if (externalConfigDir != null && serializer.getComponentName().equals("CompilerConfiguration")) { + Element externalData = JDomSerializationUtil.findComponent(loadRootElement(externalConfigDir.resolve(configFile.getFileName())), "External" + serializer.getComponentName()); + if (data == null) { + return externalData; + } + else if (externalData != null) { + return JDOMUtil.deepMerge(data, externalData); + } + } + return data; + } + private void loadFromDirectory(@NotNull Path dir) { myProject.setName(getDirectoryBaseProjectName(dir)); Path defaultConfigFile = dir.resolve("misc.xml"); diff --git a/platform/configuration-store-impl/src/ProjectStateStorageManager.kt b/platform/configuration-store-impl/src/ProjectStateStorageManager.kt index 4d5990c3a65f..eea855e932f8 100644 --- a/platform/configuration-store-impl/src/ProjectStateStorageManager.kt +++ b/platform/configuration-store-impl/src/ProjectStateStorageManager.kt @@ -26,9 +26,10 @@ import org.jdom.Element // extended in upsource open class ProjectStateStorageManager(macroSubstitutor: TrackingPathMacroSubstitutor, private val project: ProjectImpl, - useVirtualFileTracker: Boolean = true) : StateStorageManagerImpl("project", macroSubstitutor, if (useVirtualFileTracker) project else null) { + useVirtualFileTracker: Boolean = true) : StateStorageManagerImpl(ROOT_TAG_NAME, macroSubstitutor, if (useVirtualFileTracker) project else null) { companion object { - internal val VERSION_OPTION = "version" + internal const val VERSION_OPTION = "version" + const val ROOT_TAG_NAME = "project" } override fun normalizeFileSpec(fileSpec: String) = removeMacroIfStartsWith(super.normalizeFileSpec(fileSpec), PROJECT_CONFIG_DIR) diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index 3cc27b26aab7..0bf60ea7dba4 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -243,7 +243,7 @@ open class StateStorageManagerImpl(private val rootTagName: String, @Suppress("DEPRECATION") stateSplitter: Class, exclusive: Boolean = false): StateStorage { if (storageClass != StateStorage::class.java) { - val constructor = storageClass.constructors.first() + val constructor = storageClass.constructors.first { it.parameterCount <= 3 } constructor.isAccessible = true if (constructor.parameterCount == 2) { return constructor.newInstance(componentManager!!, this) as StateStorage diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorage.kt b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorage.kt index 24e40a1a3f52..bc8b1860a3aa 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorage.kt +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/configurationStore/ExternalSystemStorage.kt @@ -1,10 +1,7 @@ // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.externalSystem.configurationStore -import com.intellij.configurationStore.StateMap -import com.intellij.configurationStore.StateStorageManager -import com.intellij.configurationStore.StreamProviderFactory -import com.intellij.configurationStore.XmlElementStorage +import com.intellij.configurationStore.* import com.intellij.openapi.components.RoamingType import com.intellij.openapi.components.StateSplitterEx import com.intellij.openapi.components.StoragePathMacros @@ -25,8 +22,7 @@ internal class ExternalModuleStorage(private val module: Module, storageManager: } } -// for libraries only for now - we use null rootElementName because the only component is expected (libraryTable) -internal open class ExternalProjectStorage(fileSpec: String, project: Project, storageManager: StateStorageManager) : XmlElementStorage(fileSpec, null, storageManager.macroSubstitutor, RoamingType.DISABLED) { +internal open class ExternalProjectStorage @JvmOverloads constructor(fileSpec: String, project: Project, storageManager: StateStorageManager, rootElementName: String? = ProjectStateStorageManager.ROOT_TAG_NAME /* several components per file */) : XmlElementStorage(fileSpec, rootElementName, storageManager.macroSubstitutor, RoamingType.DISABLED) { protected val manager = StreamProviderFactory.EP_NAME.getExtensions(project).first { it is ExternalSystemStreamProviderFactory } as ExternalSystemStreamProviderFactory override final fun loadLocalData() = manager.fileStorage.read(fileSpec) @@ -38,7 +34,8 @@ internal open class ExternalProjectStorage(fileSpec: String, project: Project, s } } -internal class ExternalProjectFilteringStorage(fileSpec: String, project: Project, storageManager: StateStorageManager) : ExternalProjectStorage(fileSpec, project, storageManager) { +// for libraries only for now - we use null rootElementName because the only component is expected (libraryTable) +internal class ExternalProjectFilteringStorage(fileSpec: String, project: Project, storageManager: StateStorageManager) : ExternalProjectStorage(fileSpec, project, storageManager, null /* the only component per file */) { override fun createSaveSession(states: StateMap) = object : XmlElementStorageSaveSession(states, this) { override fun saveLocally(element: Element?) { if (element == null || !element.children.any { it.isMarkedAsExternal() }) { diff --git a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java index 293c7dffa734..58a24b64ddf8 100644 --- a/platform/util/src/com/intellij/openapi/util/JDOMUtil.java +++ b/platform/util/src/com/intellij/openapi/util/JDOMUtil.java @@ -728,6 +728,12 @@ public class JDOMUtil { iterator.remove(); Element existingChild = to.getChild(child.getName()); + if (existingChild != null && isEmpty(existingChild)) { + // replace empty tag + to.removeChild(child.getName()); + existingChild = null; + } + // if no children (e.g. ``), it means that element should be added as list item if (existingChild == null || existingChild.getChildren().isEmpty() || !isAttributesEqual(existingChild.getAttributes(), child.getAttributes(), false)) { to.addContent(child);