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 }
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.intellij.openapi.roots.ProjectFileIndex
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.cli.common.arguments.Argument
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JvmCompilerArgumentsHolder
|
||||
@@ -88,9 +88,7 @@ fun Project.getLanguageVersionSettings(contextModule: Module? = null): LanguageV
|
||||
compilerSettings,
|
||||
null
|
||||
)
|
||||
return LanguageVersionSettingsImpl(languageVersion, apiVersion, extraLanguageFeatures).apply {
|
||||
switchFlag(AnalysisFlags.skipMetadataVersionCheck, arguments.skipMetadataVersionCheck)
|
||||
}
|
||||
return LanguageVersionSettingsImpl(languageVersion, apiVersion, arguments.configureAnalysisFlags(), extraLanguageFeatures)
|
||||
}
|
||||
|
||||
val Module.languageVersionSettings: LanguageVersionSettings
|
||||
@@ -109,9 +107,19 @@ val Module.languageVersionSettings: LanguageVersionSettings
|
||||
this
|
||||
)
|
||||
|
||||
return LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion), extraLanguageFeatures).apply {
|
||||
switchFlag(AnalysisFlags.skipMetadataVersionCheck, facetSettings.skipMetadataVersionCheck)
|
||||
val arguments = facetSettings.compilerArguments
|
||||
if (arguments != null) {
|
||||
facetSettings.compilerSettings?.let { compilerSettings ->
|
||||
parseCommandLineArguments(compilerSettings.additionalArgumentsAsList, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
return LanguageVersionSettingsImpl(
|
||||
languageVersion,
|
||||
ApiVersion.createByLanguageVersion(apiVersion),
|
||||
arguments?.configureAnalysisFlags().orEmpty(),
|
||||
extraLanguageFeatures
|
||||
)
|
||||
}
|
||||
|
||||
val Module.targetPlatform: TargetPlatformKind<*>?
|
||||
|
||||
@@ -124,12 +124,6 @@ class KotlinFacetSettings {
|
||||
LanguageFeature.State.ENABLED_WITH_ERROR, LanguageFeature.State.DISABLED -> CommonCompilerArguments.ERROR
|
||||
}
|
||||
}
|
||||
|
||||
var skipMetadataVersionCheck: Boolean
|
||||
get() = compilerArguments?.skipMetadataVersionCheck == true
|
||||
set(value) {
|
||||
compilerArguments!!.skipMetadataVersionCheck = value
|
||||
}
|
||||
}
|
||||
|
||||
fun TargetPlatformKind<*>.createCompilerArguments(init: CommonCompilerArguments.() -> Unit = {}): CommonCompilerArguments {
|
||||
|
||||
@@ -163,8 +163,7 @@ public class JsConfig {
|
||||
|
||||
Set<String> modules = new HashSet<>();
|
||||
|
||||
boolean skipMetadataVersionCheck =
|
||||
getLanguageVersionSettings(configuration).isFlagEnabled(AnalysisFlags.getSkipMetadataVersionCheck());
|
||||
boolean skipMetadataVersionCheck = getLanguageVersionSettings(configuration).getFlag(AnalysisFlag.getSkipMetadataVersionCheck());
|
||||
|
||||
for (String path : libraries) {
|
||||
if (librariesToSkip != null && librariesToSkip.contains(path)) continue;
|
||||
@@ -312,7 +311,7 @@ public class JsConfig {
|
||||
return factoryMap.computeIfAbsent(metadata, m -> {
|
||||
LanguageVersionSettings languageVersionSettings = CommonConfigurationKeysKt.getLanguageVersionSettings(configuration);
|
||||
assert m.getVersion().isCompatible() ||
|
||||
languageVersionSettings.isFlagEnabled(AnalysisFlags.getSkipMetadataVersionCheck()) :
|
||||
languageVersionSettings.getFlag(AnalysisFlag.getSkipMetadataVersionCheck()) :
|
||||
"Expected JS metadata version " + JsMetadataVersion.INSTANCE + ", but actual metadata version is " + m.getVersion();
|
||||
|
||||
ModuleDescriptorImpl moduleDescriptor = new ModuleDescriptorImpl(
|
||||
|
||||
+3
-3
@@ -71,8 +71,8 @@ class KotlinJsr223JvmLocalScriptEngine(
|
||||
addJvmClasspathRoots(PathUtil.getJdkClassesRootsFromCurrentJre())
|
||||
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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user