make ExternalCompilerConfiguration available for JPS

This commit is contained in:
Vladimir Krivosheev
2017-11-21 15:15:56 +01:00
parent 8155eeb35e
commit 266295558f
7 changed files with 33 additions and 12 deletions
@@ -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<Element>, ProjectModelElement {
var loadedState: Map<String, String>? = null
private set
@@ -54,7 +54,7 @@ public abstract class JpsLoaderBase {
}
@Nullable
private <E extends JpsElement> Element loadComponentData(@NotNull JpsElementExtensionSerializerBase<E> serializer, Path configFile) {
protected <E extends JpsElement> Element loadComponentData(@NotNull JpsElementExtensionSerializerBase<E> serializer, @NotNull Path configFile) {
return JDomSerializationUtil.findComponent(loadRootElement(configFile), serializer.getComponentName());
}
@@ -116,6 +116,23 @@ public class JpsProjectLoader extends JpsLoaderBase {
return super.loadRootElement(file);
}
@Nullable
@Override
protected <E extends JpsElement> Element loadComponentData(@NotNull JpsElementExtensionSerializerBase<E> 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");
@@ -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)
@@ -243,7 +243,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
@Suppress("DEPRECATION") stateSplitter: Class<out StateSplitter>,
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
@@ -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<ExternalProjectStorage>(states, this) {
override fun saveLocally(element: Element?) {
if (element == null || !element.children.any { it.isMarkedAsExternal() }) {
@@ -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. `<module fileurl="value" />`), 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);