Skip to content

Commit 278cc71

Browse files
committed
Kotlin Facet: Reuse configuration serialization in JPS (previous implementation is not usable after configuration refactoring)
1 parent 641a9a7 commit 278cc71

File tree

3 files changed

+139
-106
lines changed

3 files changed

+139
-106
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright 2010-2017 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.kotlin.config
18+
19+
import com.intellij.util.xmlb.SkipDefaultsSerializationFilter
20+
import com.intellij.util.xmlb.XmlSerializer
21+
import org.jdom.DataConversionException
22+
import org.jdom.Element
23+
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
24+
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
25+
26+
private fun Element.getOption(name: String) = getChildren("option").firstOrNull { it.getAttribute("name").value == name }
27+
28+
private fun Element.getOptionValue(name: String) = getOption(name)?.getAttribute("value")?.value
29+
30+
private fun Element.getOptionBody(name: String) = getOption(name)?.children?.firstOrNull()
31+
32+
private fun readV1Config(element: Element): KotlinFacetSettings {
33+
return KotlinFacetSettings().apply {
34+
val useProjectSettings = element.getOptionValue("useProjectSettings")?.toBoolean()
35+
36+
val targetPlatformName = element.getOptionBody("versionInfo")?.getOptionValue("targetPlatformName")
37+
val targetPlatform = TargetPlatformKind.ALL_PLATFORMS.firstOrNull { it.description == targetPlatformName }
38+
?: TargetPlatformKind.Jvm[JvmTarget.DEFAULT]
39+
40+
val compilerInfoElement = element.getOptionBody("compilerInfo")
41+
42+
val compilerSettings = CompilerSettings().apply {
43+
compilerInfoElement?.getOptionBody("compilerSettings")?.let { compilerSettingsElement ->
44+
XmlSerializer.deserializeInto(this, compilerSettingsElement)
45+
}
46+
}
47+
48+
val commonArgumentsElement = compilerInfoElement?.getOptionBody("_commonCompilerArguments")
49+
val jvmArgumentsElement = compilerInfoElement?.getOptionBody("k2jvmCompilerArguments")
50+
val jsArgumentsElement = compilerInfoElement?.getOptionBody("k2jsCompilerArguments")
51+
52+
val compilerArguments = targetPlatform.createCompilerArguments()
53+
54+
commonArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) }
55+
when (compilerArguments) {
56+
is K2JVMCompilerArguments -> jvmArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) }
57+
is K2JSCompilerArguments -> jsArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) }
58+
}
59+
60+
if (useProjectSettings != null) {
61+
this.useProjectSettings = useProjectSettings
62+
}
63+
else {
64+
// Migration problem workaround for pre-1.1-beta releases (mainly 1.0.6) -> 1.1-rc+
65+
// Problematic cases: 1.1-beta/1.1-beta2 -> 1.1-rc+ (useProjectSettings gets reset to false)
66+
// This heuristic detects old enough configurations:
67+
if (jvmArgumentsElement == null) {
68+
this.useProjectSettings = false
69+
}
70+
}
71+
72+
this.compilerSettings = compilerSettings
73+
this.compilerArguments = compilerArguments
74+
}
75+
}
76+
77+
private fun readV2Config(element: Element): KotlinFacetSettings {
78+
return KotlinFacetSettings().apply {
79+
element.getAttributeValue("useProjectSettings")?.let { useProjectSettings = it.toBoolean() }
80+
val platformName = element.getAttributeValue("platform")
81+
val platformKind = TargetPlatformKind.ALL_PLATFORMS.firstOrNull { it.description == platformName } ?: TargetPlatformKind.DEFAULT_PLATFORM
82+
element.getChild("compilerSettings")?.let {
83+
compilerSettings = CompilerSettings()
84+
XmlSerializer.deserializeInto(compilerSettings!!, it)
85+
}
86+
element.getChild("compilerArguments")?.let {
87+
compilerArguments = platformKind.createCompilerArguments()
88+
XmlSerializer.deserializeInto(compilerArguments!!, it)
89+
}
90+
}
91+
}
92+
93+
fun deserializeFacetSettings(element: Element): KotlinFacetSettings {
94+
val version =
95+
try {
96+
element.getAttribute("version")?.intValue
97+
}
98+
catch(e: DataConversionException) {
99+
null
100+
} ?: KotlinFacetSettings.DEFAULT_VERSION
101+
return when (version) {
102+
1 -> readV1Config(element)
103+
2 -> readV2Config(element)
104+
else -> KotlinFacetSettings() // Reset facet configuration if versions don't match
105+
}
106+
}
107+
108+
fun KotlinFacetSettings.serializeFacetSettings(element: Element) {
109+
val filter = SkipDefaultsSerializationFilter()
110+
111+
element.setAttribute("version", KotlinFacetSettings.CURRENT_VERSION.toString())
112+
targetPlatformKind?.let {
113+
element.setAttribute("platform", it.description)
114+
}
115+
if (!useProjectSettings) {
116+
element.setAttribute("useProjectSettings", useProjectSettings.toString())
117+
}
118+
compilerSettings?.let {
119+
Element("compilerSettings").apply {
120+
XmlSerializer.serializeInto(it, this, filter)
121+
element.addContent(this)
122+
}
123+
}
124+
compilerArguments?.let {
125+
Element("compilerArguments").apply {
126+
XmlSerializer.serializeInto(it, this, filter)
127+
element.addContent(this)
128+
}
129+
}
130+
}

idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetConfiguration.kt

Lines changed: 5 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -20,120 +20,23 @@ import com.intellij.facet.FacetConfiguration
2020
import com.intellij.facet.ui.FacetEditorContext
2121
import com.intellij.facet.ui.FacetEditorTab
2222
import com.intellij.facet.ui.FacetValidatorsManager
23-
import com.intellij.util.xmlb.SkipDefaultsSerializationFilter
24-
import com.intellij.util.xmlb.XmlSerializer
25-
import org.jdom.DataConversionException
2623
import org.jdom.Element
27-
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
28-
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
29-
import org.jetbrains.kotlin.config.*
24+
import org.jetbrains.kotlin.config.KotlinFacetSettings
25+
import org.jetbrains.kotlin.config.deserializeFacetSettings
26+
import org.jetbrains.kotlin.config.serializeFacetSettings
3027

3128
class KotlinFacetConfiguration : FacetConfiguration {
3229
var settings = KotlinFacetSettings()
3330
private set
3431

35-
private fun Element.getOption(name: String) = getChildren("option").firstOrNull { it.getAttribute("name").value == name }
36-
37-
private fun Element.getOptionValue(name: String) = getOption(name)?.getAttribute("value")?.value
38-
39-
private fun Element.getOptionBody(name: String) = getOption(name)?.children?.firstOrNull()
40-
41-
private fun readV1Config(element: Element) {
42-
val useProjectSettings = element.getOptionValue("useProjectSettings")?.toBoolean()
43-
44-
val targetPlatformName = element.getOptionBody("versionInfo")?.getOptionValue("targetPlatformName")
45-
val targetPlatform = TargetPlatformKind.ALL_PLATFORMS.firstOrNull { it.description == targetPlatformName }
46-
?: TargetPlatformKind.Jvm.get(JvmTarget.DEFAULT)
47-
48-
val compilerInfoElement = element.getOptionBody("compilerInfo")
49-
50-
val compilerSettings = CompilerSettings().apply {
51-
compilerInfoElement?.getOptionBody("compilerSettings")?.let { compilerSettingsElement ->
52-
XmlSerializer.deserializeInto(this, compilerSettingsElement)
53-
}
54-
}
55-
56-
val commonArgumentsElement = compilerInfoElement?.getOptionBody("_commonCompilerArguments")
57-
val jvmArgumentsElement = compilerInfoElement?.getOptionBody("k2jvmCompilerArguments")
58-
val jsArgumentsElement = compilerInfoElement?.getOptionBody("k2jsCompilerArguments")
59-
60-
val compilerArguments = targetPlatform.createCompilerArguments()
61-
62-
commonArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) }
63-
when (compilerArguments) {
64-
is K2JVMCompilerArguments -> jvmArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) }
65-
is K2JSCompilerArguments -> jsArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) }
66-
}
67-
68-
if (useProjectSettings != null) {
69-
settings.useProjectSettings = useProjectSettings
70-
}
71-
else {
72-
// Migration problem workaround for pre-1.1-beta releases (mainly 1.0.6) -> 1.1-rc+
73-
// Problematic cases: 1.1-beta/1.1-beta2 -> 1.1-rc+ (useProjectSettings gets reset to false)
74-
// This heuristic detects old enough configurations:
75-
if (jvmArgumentsElement == null) {
76-
settings.useProjectSettings = false
77-
}
78-
}
79-
80-
settings.compilerSettings = compilerSettings
81-
settings.compilerArguments = compilerArguments
82-
}
83-
84-
private fun readV2Config(element: Element) {
85-
element.getAttributeValue("useProjectSettings")?.let { settings.useProjectSettings = it.toBoolean() }
86-
val platformName = element.getAttributeValue("platform")
87-
val platformKind = TargetPlatformKind.ALL_PLATFORMS.firstOrNull { it.description == platformName } ?: TargetPlatformKind.DEFAULT_PLATFORM
88-
element.getChild("compilerSettings")?.let {
89-
settings.compilerSettings = CompilerSettings()
90-
XmlSerializer.deserializeInto(settings.compilerSettings!!, it)
91-
}
92-
element.getChild("compilerArguments")?.let {
93-
settings.compilerArguments = platformKind.createCompilerArguments()
94-
XmlSerializer.deserializeInto(settings.compilerArguments!!, it)
95-
}
96-
}
97-
9832
@Suppress("OverridingDeprecatedMember")
9933
override fun readExternal(element: Element) {
100-
val version =
101-
try {
102-
element.getAttribute("version")?.intValue
103-
}
104-
catch(e: DataConversionException) {
105-
null
106-
} ?: KotlinFacetSettings.DEFAULT_VERSION
107-
when (version) {
108-
1 -> readV1Config(element)
109-
2 -> readV2Config(element)
110-
else -> settings = KotlinFacetSettings() // Reset facet configuration if versions don't match
111-
}
34+
settings = deserializeFacetSettings(element)
11235
}
11336

11437
@Suppress("OverridingDeprecatedMember")
11538
override fun writeExternal(element: Element) {
116-
val filter = SkipDefaultsSerializationFilter()
117-
118-
element.setAttribute("version", KotlinFacetSettings.CURRENT_VERSION.toString())
119-
settings.targetPlatformKind?.let {
120-
element.setAttribute("platform", it.description)
121-
}
122-
if (!settings.useProjectSettings) {
123-
element.setAttribute("useProjectSettings", settings.useProjectSettings.toString())
124-
}
125-
settings.compilerSettings?.let {
126-
Element("compilerSettings").apply {
127-
XmlSerializer.serializeInto(it, this, filter)
128-
element.addContent(this)
129-
}
130-
}
131-
settings.compilerArguments?.let {
132-
Element("compilerArguments").apply {
133-
XmlSerializer.serializeInto(it, this, filter)
134-
element.addContent(this)
135-
}
136-
}
39+
settings.serializeFacetSettings(element)
13740
}
13841

13942
override fun createEditorTabs(

jps-plugin/src/org/jetbrains/kotlin/jps/model/JpsKotlinFacetConfigurationSerializer.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616

1717
package org.jetbrains.kotlin.jps.model
1818

19-
import com.intellij.util.xmlb.XmlSerializer
2019
import org.jdom.Element
2120
import org.jetbrains.jps.model.JpsElement
2221
import org.jetbrains.jps.model.module.JpsModule
2322
import org.jetbrains.jps.model.serialization.facet.JpsFacetConfigurationSerializer
24-
import org.jetbrains.kotlin.config.KotlinFacetSettings
23+
import org.jetbrains.kotlin.config.deserializeFacetSettings
24+
import org.jetbrains.kotlin.config.serializeFacetSettings
2525

2626
object JpsKotlinFacetConfigurationSerializer : JpsFacetConfigurationSerializer<JpsKotlinFacetModuleExtension>(
2727
JpsKotlinFacetModuleExtension.KIND,
@@ -34,14 +34,14 @@ object JpsKotlinFacetConfigurationSerializer : JpsFacetConfigurationSerializer<J
3434
parent: JpsElement?,
3535
module: JpsModule
3636
): JpsKotlinFacetModuleExtension {
37-
return JpsKotlinFacetModuleExtension(XmlSerializer.deserialize(facetConfigurationElement, KotlinFacetSettings::class.java)!!)
37+
return JpsKotlinFacetModuleExtension(deserializeFacetSettings(facetConfigurationElement))
3838
}
3939

4040
override fun saveExtension(
4141
extension: JpsKotlinFacetModuleExtension?,
4242
facetConfigurationTag: Element,
4343
module: JpsModule
4444
) {
45-
XmlSerializer.serializeInto((extension as JpsKotlinFacetModuleExtension).settings, facetConfigurationTag)
45+
(extension as JpsKotlinFacetModuleExtension).settings.serializeFacetSettings(facetConfigurationTag)
4646
}
4747
}

0 commit comments

Comments
 (0)