Refactor AnalysisFlags and their support in IDE

* Support flags with any value (not just Boolean)
* Support all flags by parsing arguments in KotlinFacetSettings, instead
  of manually listing known flags

 #KT-19210 Fixed
This commit is contained in:
Alexander Udalov
2017-07-24 20:49:00 +03:00
parent 845de7aa4d
commit 2f99f6ad34
18 changed files with 99 additions and 80 deletions
@@ -19,30 +19,34 @@ package org.jetbrains.kotlin.config
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class AnalysisFlag internal constructor(private val name: String) {
override fun equals(other: Any?): Boolean = other is AnalysisFlag && other.name == name
class AnalysisFlag<out T> internal constructor(
private val name: String,
val defaultValue: T
) {
override fun equals(other: Any?): Boolean = other is AnalysisFlag<*> && other.name == name
override fun hashCode(): Int = name.hashCode()
override fun toString(): String = name
companion object
}
private class Flag<out T>(name: String, defaultValue: T) : ReadOnlyProperty<Any?, AnalysisFlag<T>> {
private val flag = AnalysisFlag(name, defaultValue)
private operator fun @Suppress("unused") AnalysisFlag.Companion.provideDelegate(instance: Any?, property: KProperty<*>) =
object : ReadOnlyProperty<Any?, AnalysisFlag> {
private val flag = AnalysisFlag(property.name)
override fun getValue(thisRef: Any?, property: KProperty<*>): AnalysisFlag<T> = flag
override fun getValue(thisRef: Any?, property: KProperty<*>): AnalysisFlag = flag
object Boolean {
operator fun provideDelegate(instance: Any?, property: KProperty<*>) = Flag(property.name, false)
}
}
object AnalysisFlags {
@JvmStatic
val skipMetadataVersionCheck by AnalysisFlag
companion object Flags {
@JvmStatic
val skipMetadataVersionCheck by Flag.Boolean
@JvmStatic
val multiPlatformDoNotCheckImpl by AnalysisFlag
@JvmStatic
val multiPlatformDoNotCheckImpl by Flag.Boolean
@JvmStatic
val loadJsr305Annotations by AnalysisFlag
@JvmStatic
val loadJsr305Annotations by Flag.Boolean
}
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.config
import org.jetbrains.kotlin.config.LanguageVersion.KOTLIN_1_1
import org.jetbrains.kotlin.config.LanguageVersion.KOTLIN_1_2
import org.jetbrains.kotlin.utils.DescriptionAware
import java.util.*
enum class LanguageFeature(
val sinceVersion: LanguageVersion?,
@@ -115,7 +116,7 @@ interface LanguageVersionSettings {
fun supportsFeature(feature: LanguageFeature): Boolean =
getFeatureSupport(feature).let { it == LanguageFeature.State.ENABLED || it == LanguageFeature.State.ENABLED_WITH_WARNING }
fun isFlagEnabled(flag: AnalysisFlag): Boolean
fun <T> getFlag(flag: AnalysisFlag<T>): T
val apiVersion: ApiVersion
@@ -126,20 +127,14 @@ interface LanguageVersionSettings {
class LanguageVersionSettingsImpl @JvmOverloads constructor(
override val languageVersion: LanguageVersion,
override val apiVersion: ApiVersion,
private val specificFeatures: Map<LanguageFeature, LanguageFeature.State> = emptyMap()
analysisFlags: Map<AnalysisFlag<*>, Any?> = emptyMap(),
specificFeatures: Map<LanguageFeature, LanguageFeature.State> = emptyMap()
) : LanguageVersionSettings {
private val enabledFlags = hashSetOf<AnalysisFlag>()
private val analysisFlags: Map<AnalysisFlag<*>, *> = Collections.unmodifiableMap(analysisFlags)
private val specificFeatures: Map<LanguageFeature, LanguageFeature.State> = Collections.unmodifiableMap(specificFeatures)
override fun isFlagEnabled(flag: AnalysisFlag): Boolean = flag in enabledFlags
fun switchFlag(flag: AnalysisFlag, enable: Boolean) {
if (enable) {
enabledFlags.add(flag)
}
else {
enabledFlags.remove(flag)
}
}
@Suppress("UNCHECKED_CAST")
override fun <T> getFlag(flag: AnalysisFlag<T>): T = analysisFlags[flag] as T? ?: flag.defaultValue
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State {
specificFeatures[feature]?.let { return it }