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>()
|
||||
|
||||
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.XmlSerializer
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.*
|
||||
import org.jetbrains.kotlin.config.SettingConstants
|
||||
|
||||
abstract class BaseKotlinCompilerSettings<T : Any> protected constructor() : PersistentStateComponent<Element>, Cloneable {
|
||||
@Suppress("LeakingThis")
|
||||
var settings: T = createSettings()
|
||||
private set
|
||||
private var _settings: T = createSettings()
|
||||
|
||||
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
|
||||
|
||||
override fun getState() = XmlSerializer.serialize(settings, SKIP_DEFAULT_VALUES)
|
||||
override fun getState() = XmlSerializer.serialize(_settings, SKIP_DEFAULT_VALUES)
|
||||
|
||||
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()
|
||||
|
||||
+4
-3
@@ -48,9 +48,10 @@ class KotlinCommonCompilerArgumentsHolder : BaseKotlinCompilerSettings<CommonCom
|
||||
super.loadState(state)
|
||||
|
||||
// To fix earlier configurations with incorrect combination of language and API version
|
||||
val settings = settings
|
||||
if (VersionComparatorUtil.compare(settings.languageVersion, settings.apiVersion) < 0) {
|
||||
settings.apiVersion = settings.languageVersion
|
||||
update {
|
||||
if (VersionComparatorUtil.compare(languageVersion, apiVersion) < 0) {
|
||||
apiVersion = languageVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -27,6 +27,8 @@ import org.jetbrains.kotlin.config.SettingConstants.KOTLIN_COMPILER_SETTINGS_SEC
|
||||
class KotlinCompilerSettings : BaseKotlinCompilerSettings<CompilerSettings>() {
|
||||
override fun createSettings() = CompilerSettings()
|
||||
|
||||
|
||||
|
||||
companion object {
|
||||
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
|
||||
val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this)
|
||||
if (facetSettings.useProjectSettings) {
|
||||
with(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) {
|
||||
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
|
||||
if (languageVersion == null) {
|
||||
languageVersion = languageLevel.versionString
|
||||
}
|
||||
|
||||
+4
@@ -28,6 +28,10 @@ import org.jetbrains.kotlin.idea.compiler.configuration.BaseKotlinCompilerSettin
|
||||
class Kotlin2JsCompilerArgumentsHolder : BaseKotlinCompilerSettings<K2JSCompilerArguments>() {
|
||||
override fun createSettings() = K2JSCompilerArguments.createDefaultInstance()
|
||||
|
||||
override fun validateNewSettings(settings: K2JSCompilerArguments) {
|
||||
validateInheritedFieldsUnchanged(settings)
|
||||
}
|
||||
|
||||
companion object {
|
||||
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>() {
|
||||
override fun createSettings() = K2JVMCompilerArguments.createDefaultInstance()
|
||||
|
||||
override fun validateNewSettings(settings: K2JVMCompilerArguments) {
|
||||
validateInheritedFieldsUnchanged(settings)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getInstance(project: Project) = ServiceManager.getService(project, Kotlin2JvmCompilerArgumentsHolder::class.java)!!
|
||||
}
|
||||
|
||||
+7
@@ -402,6 +402,13 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable, Co
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,9 +66,9 @@ class KotlinFacetEditorGeneralTab(
|
||||
else {
|
||||
editableCommonArguments = configuration!!.settings.compilerArguments!!
|
||||
editableJvmArguments = editableCommonArguments as? K2JVMCompilerArguments
|
||||
?: copyBean(Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings)
|
||||
?: Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings
|
||||
editableJsArguments = editableCommonArguments as? K2JSCompilerArguments
|
||||
?: copyBean(Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings)
|
||||
?: Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings
|
||||
editableCompilerSettings = configuration.settings.compilerSettings!!
|
||||
}
|
||||
|
||||
@@ -127,10 +127,10 @@ class KotlinFacetEditorGeneralTab(
|
||||
compilerConfigurable.setTargetPlatform(chosenPlatform)
|
||||
compilerConfigurable.setEnabled(!useProjectSettings)
|
||||
if (useProjectSettings) {
|
||||
compilerConfigurable.commonCompilerArguments = copyBean(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings)
|
||||
compilerConfigurable.k2jvmCompilerArguments = copyBean(Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings)
|
||||
compilerConfigurable.k2jsCompilerArguments = copyBean(Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings)
|
||||
compilerConfigurable.compilerSettings = copyBean(KotlinCompilerSettings.getInstance(project).settings)
|
||||
compilerConfigurable.commonCompilerArguments = KotlinCommonCompilerArgumentsHolder.getInstance(project).settings
|
||||
compilerConfigurable.k2jvmCompilerArguments = Kotlin2JvmCompilerArgumentsHolder.getInstance(project).settings
|
||||
compilerConfigurable.k2jsCompilerArguments = Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings
|
||||
compilerConfigurable.compilerSettings = KotlinCompilerSettings.getInstance(project).settings
|
||||
}
|
||||
else {
|
||||
compilerConfigurable.commonCompilerArguments = editableCommonArguments
|
||||
|
||||
@@ -58,7 +58,7 @@ fun KotlinFacetSettings.initializeIfNeeded(
|
||||
val project = module.project
|
||||
|
||||
if (compilerSettings == null) {
|
||||
compilerSettings = copyBean(KotlinCompilerSettings.getInstance(project).settings)
|
||||
compilerSettings = KotlinCompilerSettings.getInstance(project).settings
|
||||
}
|
||||
|
||||
val commonArguments = KotlinCommonCompilerArgumentsHolder.getInstance(module.project).settings
|
||||
|
||||
@@ -94,7 +94,7 @@ sealed class ChangeCoroutineSupportFix(
|
||||
if (!checkUpdateRuntime(project, LanguageFeature.Coroutines.sinceApiVersion)) return
|
||||
}
|
||||
|
||||
with(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) {
|
||||
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
|
||||
coroutinesEnable = coroutineSupport == LanguageFeature.State.ENABLED
|
||||
coroutinesWarn = coroutineSupport == LanguageFeature.State.ENABLED_WITH_WARNING
|
||||
coroutinesError = coroutineSupport == LanguageFeature.State.ENABLED_WITH_ERROR ||
|
||||
|
||||
@@ -123,10 +123,10 @@ sealed class EnableUnsupportedFeatureFix(
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val targetVersion = feature.sinceVersion!!
|
||||
|
||||
with(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) {
|
||||
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
|
||||
val parsedApiVersion = ApiVersion.parse(apiVersion)
|
||||
if (parsedApiVersion != null && feature.sinceApiVersion > parsedApiVersion) {
|
||||
if (!checkUpdateRuntime(project, feature.sinceApiVersion)) return
|
||||
if (!checkUpdateRuntime(project, feature.sinceApiVersion)) return@update
|
||||
apiVersion = feature.sinceApiVersion.versionString
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ class LanguageFeatureQuickFixTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||
}
|
||||
|
||||
private fun resetProjectSettings(version: LanguageVersion) {
|
||||
with(KotlinCommonCompilerArgumentsHolder.getInstance(project).settings) {
|
||||
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
|
||||
languageVersion = version.versionString
|
||||
apiVersion = version.versionString
|
||||
coroutinesEnable = false
|
||||
|
||||
Reference in New Issue
Block a user