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:
+15
@@ -16,6 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public abstract class CommonCompilerArguments extends CommonToolArguments {
|
||||
public static final long serialVersionUID = 0L;
|
||||
|
||||
@@ -89,6 +96,14 @@ public abstract class CommonCompilerArguments extends CommonToolArguments {
|
||||
public static final String ERROR = "error";
|
||||
public static final String ENABLE = "enable";
|
||||
|
||||
@NotNull
|
||||
public Map<AnalysisFlag<?>, Object> configureAnalysisFlags() {
|
||||
Map<AnalysisFlag<?>, Object> result = new HashMap<>();
|
||||
result.put(AnalysisFlag.getSkipMetadataVersionCheck(), skipMetadataVersionCheck);
|
||||
result.put(AnalysisFlag.getMultiPlatformDoNotCheckImpl(), noCheckImpl);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Used only for serialize and deserialize settings. Don't use in other places!
|
||||
public static final class DummyImpl extends CommonCompilerArguments {}
|
||||
}
|
||||
|
||||
+13
@@ -16,8 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag;
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
public static final long serialVersionUID = 0L;
|
||||
|
||||
@@ -162,4 +167,12 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
|
||||
|
||||
// Paths to output directories for friend modules.
|
||||
public String[] friendPaths;
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Map<AnalysisFlag<?>, Object> configureAnalysisFlags() {
|
||||
Map<AnalysisFlag<?>, Object> result = super.configureAnalysisFlags();
|
||||
result.put(AnalysisFlag.getLoadJsr305Annotations(), loadJsr305annotations);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,15 +189,12 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> extends CLI
|
||||
extraLanguageFeatures.put(LanguageFeature.Coroutines, coroutinesState);
|
||||
}
|
||||
|
||||
LanguageVersionSettingsImpl settings =
|
||||
new LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion), extraLanguageFeatures);
|
||||
settings.switchFlag(AnalysisFlags.getSkipMetadataVersionCheck(), arguments.skipMetadataVersionCheck);
|
||||
settings.switchFlag(AnalysisFlags.getMultiPlatformDoNotCheckImpl(), arguments.noCheckImpl);
|
||||
configureAnalysisFlags(settings, arguments);
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, settings);
|
||||
}
|
||||
|
||||
protected void configureAnalysisFlags(@NotNull LanguageVersionSettingsImpl settings, @NotNull A arguments) {
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, new LanguageVersionSettingsImpl(
|
||||
languageVersion,
|
||||
ApiVersion.createByLanguageVersion(apiVersion),
|
||||
arguments.configureAnalysisFlags(),
|
||||
extraLanguageFeatures
|
||||
));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -303,10 +303,6 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun configureAnalysisFlags(settings: LanguageVersionSettingsImpl, arguments: K2JVMCompilerArguments) {
|
||||
settings.switchFlag(AnalysisFlags.loadJsr305Annotations, arguments.loadJsr305annotations)
|
||||
}
|
||||
|
||||
override fun createArguments(): K2JVMCompilerArguments = K2JVMCompilerArguments().apply {
|
||||
if (System.getenv("KOTLIN_REPORT_PERF") != null) {
|
||||
reportPerf = true
|
||||
|
||||
@@ -54,9 +54,9 @@ open class KotlinJvmReplService(
|
||||
addJvmClasspathRoots(PathUtil.getKotlinPathsForCompiler().let { listOf(it.stdlibPath, it.reflectPath, it.scriptRuntimePath) })
|
||||
addJvmClasspathRoots(templateClasspath)
|
||||
put(CommonConfigurationKeys.MODULE_NAME, "kotlin-script")
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE).apply {
|
||||
switchFlag(AnalysisFlags.skipMetadataVersionCheck, true)
|
||||
}
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, mapOf(AnalysisFlag.skipMetadataVersionCheck to true)
|
||||
)
|
||||
}
|
||||
|
||||
protected fun makeScriptDefinition(templateClasspath: List<File>, templateClassName: String): KotlinScriptDefinition? {
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.frontend.java.di
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.builtins.JvmBuiltInsPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
@@ -103,7 +103,7 @@ fun createContainerForLazyResolveWithJava(
|
||||
|
||||
useInstance(languageVersionSettings)
|
||||
|
||||
if (languageVersionSettings.isFlagEnabled(AnalysisFlags.loadJsr305Annotations)) {
|
||||
if (languageVersionSettings.getFlag(AnalysisFlag.loadJsr305Annotations)) {
|
||||
useImpl<AnnotationTypeQualifierResolverImpl>()
|
||||
}
|
||||
else {
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
|
||||
@@ -24,5 +24,5 @@ import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfigu
|
||||
class CompilerDeserializationConfiguration(languageVersionSettings: LanguageVersionSettings) : DeserializationConfiguration {
|
||||
override val typeAliasesAllowed = languageVersionSettings.supportsFeature(LanguageFeature.TypeAliases)
|
||||
|
||||
override val skipMetadataVersionCheck = languageVersionSettings.isFlagEnabled(AnalysisFlags.skipMetadataVersionCheck)
|
||||
override val skipMetadataVersionCheck = languageVersionSettings.getFlag(AnalysisFlag.skipMetadataVersionCheck)
|
||||
}
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -61,7 +61,7 @@ object HeaderImplDeclarationChecker : DeclarationChecker {
|
||||
|
||||
if (descriptor !is MemberDescriptor) return
|
||||
|
||||
val checkImpl = !languageVersionSettings.isFlagEnabled(AnalysisFlags.multiPlatformDoNotCheckImpl)
|
||||
val checkImpl = !languageVersionSettings.getFlag(AnalysisFlag.multiPlatformDoNotCheckImpl)
|
||||
if (descriptor.isHeader && declaration.hasModifier(KtTokens.HEADER_KEYWORD)) {
|
||||
checkHeaderDeclarationHasImplementation(declaration, descriptor, diagnosticHolder, descriptor.module, checkImpl)
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State =
|
||||
languageFeatures[feature] ?: delegate.getFeatureSupport(feature)
|
||||
|
||||
override fun isFlagEnabled(flag: AnalysisFlag): Boolean = false
|
||||
override fun <T> getFlag(flag: AnalysisFlag<T>): T = flag.defaultValue
|
||||
}
|
||||
|
||||
inner class TestFile(
|
||||
|
||||
@@ -29,9 +29,7 @@ abstract class AbstractForeignAnnotationsTest : AbstractDiagnosticsWithFullJdkTe
|
||||
open protected val annotationsPath: String
|
||||
get() = FOREIGN_ANNOTATIONS_SOURCES_PATH
|
||||
|
||||
override fun loadLanguageVersionSettings(module: List<TestFile>): LanguageVersionSettings {
|
||||
return LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE).apply {
|
||||
switchFlag(AnalysisFlags.loadJsr305Annotations, true)
|
||||
}
|
||||
}
|
||||
override fun loadLanguageVersionSettings(module: List<TestFile>): LanguageVersionSettings =
|
||||
LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE,
|
||||
mapOf(AnalysisFlag.loadJsr305Annotations to true))
|
||||
}
|
||||
|
||||
@@ -45,9 +45,9 @@ class LoadJavaPackageAnnotationsTest : KtUsefulTestCase() {
|
||||
if (useJavac) {
|
||||
put(JVMConfigurationKeys.USE_JAVAC, true)
|
||||
}
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE).apply {
|
||||
switchFlag(AnalysisFlags.loadJsr305Annotations, true)
|
||||
}
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, mapOf(AnalysisFlag.loadJsr305Annotations to true)
|
||||
)
|
||||
configurator(this)
|
||||
}
|
||||
val environment =
|
||||
|
||||
+3
-3
@@ -94,9 +94,9 @@ class TypeQualifierAnnotationResolverTest : KtUsefulTestCase() {
|
||||
),
|
||||
listOf(File(TEST_DATA_PATH))
|
||||
).apply {
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE).apply {
|
||||
switchFlag(AnalysisFlags.loadJsr305Annotations, true)
|
||||
}
|
||||
languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, mapOf(AnalysisFlag.loadJsr305Annotations to true)
|
||||
)
|
||||
}
|
||||
|
||||
val environment = KotlinCoreEnvironment.createForTests(myTestRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||
|
||||
+19
-15
@@ -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 }
|
||||
|
||||
Reference in New Issue
Block a user