Configuration: Check that project-level common arguments are not changed through platform-specific holders
This commit is contained in:
+1
-1
@@ -89,7 +89,7 @@ private fun Any.copyValueIfNeeded(): Any {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectFieldsToCopy(clazz: Class<*>, inheritedOnly: Boolean): List<Field> {
|
fun collectFieldsToCopy(clazz: Class<*>, inheritedOnly: Boolean): List<Field> {
|
||||||
val fromFields = ArrayList<Field>()
|
val fromFields = ArrayList<Field>()
|
||||||
|
|
||||||
var currentClass: Class<*>? = if (inheritedOnly) clazz.superclass else clazz
|
var currentClass: Class<*>? = if (inheritedOnly) clazz.superclass else clazz
|
||||||
|
|||||||
+28
-7
@@ -21,22 +21,43 @@ import com.intellij.openapi.components.StoragePathMacros.PROJECT_CONFIG_DIR
|
|||||||
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters
|
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters
|
||||||
import com.intellij.util.xmlb.XmlSerializer
|
import com.intellij.util.xmlb.XmlSerializer
|
||||||
import org.jdom.Element
|
import org.jdom.Element
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.*
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
|
||||||
import org.jetbrains.kotlin.config.SettingConstants
|
import org.jetbrains.kotlin.config.SettingConstants
|
||||||
|
|
||||||
abstract class BaseKotlinCompilerSettings<T : Any> protected constructor() : PersistentStateComponent<Element>, Cloneable {
|
abstract class BaseKotlinCompilerSettings<T : Any> protected constructor() : PersistentStateComponent<Element>, Cloneable {
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
var settings: T = createSettings()
|
private var _settings: T = createSettings()
|
||||||
private set
|
|
||||||
|
var settings: T
|
||||||
|
get() = copyBean(_settings)
|
||||||
|
set(value) {
|
||||||
|
validateNewSettings(value)
|
||||||
|
_settings = copyBean(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun update(changer: T.() -> Unit) {
|
||||||
|
settings = settings.apply { changer() }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun validateInheritedFieldsUnchanged(settings: T) {
|
||||||
|
val inheritedFields = collectFieldsToCopy(settings.javaClass, true)
|
||||||
|
val defaultInstance = createSettings()
|
||||||
|
val invalidFields = inheritedFields.filter { it.get(settings) != it.get(defaultInstance) }
|
||||||
|
if (invalidFields.isNotEmpty()) {
|
||||||
|
throw IllegalArgumentException("Following fields are expected to be left unchanged in ${settings.javaClass}: ${invalidFields.joinToString { it.name }}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun validateNewSettings(settings: T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract fun createSettings(): T
|
protected abstract fun createSettings(): T
|
||||||
|
|
||||||
override fun getState() = XmlSerializer.serialize(settings, SKIP_DEFAULT_VALUES)
|
override fun getState() = XmlSerializer.serialize(_settings, SKIP_DEFAULT_VALUES)
|
||||||
|
|
||||||
override fun loadState(state: Element) {
|
override fun loadState(state: Element) {
|
||||||
settings = XmlSerializer.deserialize(state, settings.javaClass) ?: createSettings()
|
_settings = XmlSerializer.deserialize(state, _settings.javaClass) ?: createSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun clone(): Any = super.clone()
|
public override fun clone(): Any = super.clone()
|
||||||
|
|||||||
+4
-3
@@ -48,9 +48,10 @@ class KotlinCommonCompilerArgumentsHolder : BaseKotlinCompilerSettings<CommonCom
|
|||||||
super.loadState(state)
|
super.loadState(state)
|
||||||
|
|
||||||
// To fix earlier configurations with incorrect combination of language and API version
|
// To fix earlier configurations with incorrect combination of language and API version
|
||||||
val settings = settings
|
update {
|
||||||
if (VersionComparatorUtil.compare(settings.languageVersion, settings.apiVersion) < 0) {
|
if (VersionComparatorUtil.compare(languageVersion, apiVersion) < 0) {
|
||||||
settings.apiVersion = settings.languageVersion
|
apiVersion = languageVersion
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -27,6 +27,8 @@ import org.jetbrains.kotlin.config.SettingConstants.KOTLIN_COMPILER_SETTINGS_SEC
|
|||||||
class KotlinCompilerSettings : BaseKotlinCompilerSettings<CompilerSettings>() {
|
class KotlinCompilerSettings : BaseKotlinCompilerSettings<CompilerSettings>() {
|
||||||
override fun createSettings() = CompilerSettings()
|
override fun createSettings() = CompilerSettings()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getInstance(project: Project) = ServiceManager.getService(project, KotlinCompilerSettings::class.java)!!
|
fun getInstance(project: Project) = ServiceManager.getService(project, KotlinCompilerSettings::class.java)!!
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion {
|
|||||||
// Preserve inferred version in facet/project settings
|
// Preserve inferred version in facet/project settings
|
||||||
val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this)
|
val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this)
|
||||||
if (facetSettings.useProjectSettings) {
|
if (facetSettings.useProjectSettings) {
|
||||||
with(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) {
|
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
|
||||||
if (languageVersion == null) {
|
if (languageVersion == null) {
|
||||||
languageVersion = languageLevel.versionString
|
languageVersion = languageLevel.versionString
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -28,6 +28,10 @@ import org.jetbrains.kotlin.idea.compiler.configuration.BaseKotlinCompilerSettin
|
|||||||
class Kotlin2JsCompilerArgumentsHolder : BaseKotlinCompilerSettings<K2JSCompilerArguments>() {
|
class Kotlin2JsCompilerArgumentsHolder : BaseKotlinCompilerSettings<K2JSCompilerArguments>() {
|
||||||
override fun createSettings() = K2JSCompilerArguments.createDefaultInstance()
|
override fun createSettings() = K2JSCompilerArguments.createDefaultInstance()
|
||||||
|
|
||||||
|
override fun validateNewSettings(settings: K2JSCompilerArguments) {
|
||||||
|
validateInheritedFieldsUnchanged(settings)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getInstance(project: Project) = ServiceManager.getService(project, Kotlin2JsCompilerArgumentsHolder::class.java)!!
|
fun getInstance(project: Project) = ServiceManager.getService(project, Kotlin2JsCompilerArgumentsHolder::class.java)!!
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -29,6 +29,10 @@ import org.jetbrains.kotlin.idea.compiler.configuration.BaseKotlinCompilerSettin
|
|||||||
class Kotlin2JvmCompilerArgumentsHolder : BaseKotlinCompilerSettings<K2JVMCompilerArguments>() {
|
class Kotlin2JvmCompilerArgumentsHolder : BaseKotlinCompilerSettings<K2JVMCompilerArguments>() {
|
||||||
override fun createSettings() = K2JVMCompilerArguments.createDefaultInstance()
|
override fun createSettings() = K2JVMCompilerArguments.createDefaultInstance()
|
||||||
|
|
||||||
|
override fun validateNewSettings(settings: K2JVMCompilerArguments) {
|
||||||
|
validateInheritedFieldsUnchanged(settings)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getInstance(project: Project) = ServiceManager.getService(project, Kotlin2JvmCompilerArgumentsHolder::class.java)!!
|
fun getInstance(project: Project) = ServiceManager.getService(project, Kotlin2JvmCompilerArgumentsHolder::class.java)!!
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -402,6 +402,13 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
|
|||||||
|
|
||||||
k2jvmCompilerArguments.jvmTarget = getSelectedJvmVersion();
|
k2jvmCompilerArguments.jvmTarget = getSelectedJvmVersion();
|
||||||
|
|
||||||
|
if (isProjectSettings) {
|
||||||
|
KotlinCommonCompilerArgumentsHolder.Companion.getInstance(project).setSettings(commonCompilerArguments);
|
||||||
|
Kotlin2JvmCompilerArgumentsHolder.Companion.getInstance(project).setSettings(k2jvmCompilerArguments);
|
||||||
|
Kotlin2JsCompilerArgumentsHolder.Companion.getInstance(project).setSettings(k2jsCompilerArguments);
|
||||||
|
KotlinCompilerSettings.Companion.getInstance(project).setSettings(compilerSettings);
|
||||||
|
}
|
||||||
|
|
||||||
BuildManager.getInstance().clearState(project);
|
BuildManager.getInstance().clearState(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,9 +66,9 @@ class KotlinFacetEditorGeneralTab(
|
|||||||
else {
|
else {
|
||||||
editableCommonArguments = configuration!!.settings.compilerArguments!!
|
editableCommonArguments = configuration!!.settings.compilerArguments!!
|
||||||
editableJvmArguments = editableCommonArguments as? K2JVMCompilerArguments
|
editableJvmArguments = editableCommonArguments as? K2JVMCompilerArguments
|
||||||
?: copyBean(Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings)
|
?: Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings
|
||||||
editableJsArguments = editableCommonArguments as? K2JSCompilerArguments
|
editableJsArguments = editableCommonArguments as? K2JSCompilerArguments
|
||||||
?: copyBean(Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings)
|
?: Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings
|
||||||
editableCompilerSettings = configuration.settings.compilerSettings!!
|
editableCompilerSettings = configuration.settings.compilerSettings!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,10 +127,10 @@ class KotlinFacetEditorGeneralTab(
|
|||||||
compilerConfigurable.setTargetPlatform(chosenPlatform)
|
compilerConfigurable.setTargetPlatform(chosenPlatform)
|
||||||
compilerConfigurable.setEnabled(!useProjectSettings)
|
compilerConfigurable.setEnabled(!useProjectSettings)
|
||||||
if (useProjectSettings) {
|
if (useProjectSettings) {
|
||||||
compilerConfigurable.commonCompilerArguments = copyBean(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings)
|
compilerConfigurable.commonCompilerArguments = KotlinCommonCompilerArgumentsHolder.getInstance(project).settings
|
||||||
compilerConfigurable.k2jvmCompilerArguments = copyBean(Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings)
|
compilerConfigurable.k2jvmCompilerArguments = Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings
|
||||||
compilerConfigurable.k2jsCompilerArguments = copyBean(Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings)
|
compilerConfigurable.k2jsCompilerArguments = Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings
|
||||||
compilerConfigurable.compilerSettings = copyBean(KotlinCompilerSettings.getInstance(project).settings)
|
compilerConfigurable.compilerSettings = KotlinCompilerSettings.getInstance(project).settings
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
compilerConfigurable.commonCompilerArguments = editableCommonArguments
|
compilerConfigurable.commonCompilerArguments = editableCommonArguments
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ fun KotlinFacetSettings.initializeIfNeeded(
|
|||||||
val project = module.project
|
val project = module.project
|
||||||
|
|
||||||
if (compilerSettings == null) {
|
if (compilerSettings == null) {
|
||||||
compilerSettings = copyBean(KotlinCompilerSettings.getInstance(project).settings)
|
compilerSettings = KotlinCompilerSettings.getInstance(project).settings
|
||||||
}
|
}
|
||||||
|
|
||||||
val commonArguments = KotlinCommonCompilerArgumentsHolder.getInstance(module.project).settings
|
val commonArguments = KotlinCommonCompilerArgumentsHolder.getInstance(module.project).settings
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ sealed class ChangeCoroutineSupportFix(
|
|||||||
if (!checkUpdateRuntime(project, LanguageFeature.Coroutines.sinceApiVersion)) return
|
if (!checkUpdateRuntime(project, LanguageFeature.Coroutines.sinceApiVersion)) return
|
||||||
}
|
}
|
||||||
|
|
||||||
with(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) {
|
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
|
||||||
coroutinesEnable = coroutineSupport == LanguageFeature.State.ENABLED
|
coroutinesEnable = coroutineSupport == LanguageFeature.State.ENABLED
|
||||||
coroutinesWarn = coroutineSupport == LanguageFeature.State.ENABLED_WITH_WARNING
|
coroutinesWarn = coroutineSupport == LanguageFeature.State.ENABLED_WITH_WARNING
|
||||||
coroutinesError = coroutineSupport == LanguageFeature.State.ENABLED_WITH_ERROR ||
|
coroutinesError = coroutineSupport == LanguageFeature.State.ENABLED_WITH_ERROR ||
|
||||||
|
|||||||
@@ -123,10 +123,10 @@ sealed class EnableUnsupportedFeatureFix(
|
|||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
val targetVersion = feature.sinceVersion!!
|
val targetVersion = feature.sinceVersion!!
|
||||||
|
|
||||||
with(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) {
|
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
|
||||||
val parsedApiVersion = ApiVersion.parse(apiVersion)
|
val parsedApiVersion = ApiVersion.parse(apiVersion)
|
||||||
if (parsedApiVersion != null && feature.sinceApiVersion > parsedApiVersion) {
|
if (parsedApiVersion != null && feature.sinceApiVersion > parsedApiVersion) {
|
||||||
if (!checkUpdateRuntime(project, feature.sinceApiVersion)) return
|
if (!checkUpdateRuntime(project, feature.sinceApiVersion)) return@update
|
||||||
apiVersion = feature.sinceApiVersion.versionString
|
apiVersion = feature.sinceApiVersion.versionString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun resetProjectSettings(version: LanguageVersion) {
|
private fun resetProjectSettings(version: LanguageVersion) {
|
||||||
with(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) {
|
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
|
||||||
languageVersion = version.versionString
|
languageVersion = version.versionString
|
||||||
apiVersion = version.versionString
|
apiVersion = version.versionString
|
||||||
coroutinesEnable = false
|
coroutinesEnable = false
|
||||||
|
|||||||
Reference in New Issue
Block a user