Support !LANGUAGE directive in codegen tests
LANGUAGE_VERSION directive will be removed later, for now it's left for simplicity
This commit is contained in:
@@ -222,7 +222,7 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
}
|
||||
}
|
||||
|
||||
return result ?: BaseDiagnosticsTest.DiagnosticTestLanguageVersionSettings(
|
||||
return result ?: CompilerTestLanguageVersionSettings(
|
||||
BaseDiagnosticsTest.DEFAULT_DIAGNOSTIC_TESTS_FEATURES,
|
||||
LanguageVersionSettingsImpl.DEFAULT.apiVersion,
|
||||
LanguageVersionSettingsImpl.DEFAULT.languageVersion
|
||||
|
||||
@@ -28,7 +28,9 @@ import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestFile
|
||||
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.TestModule
|
||||
import org.jetbrains.kotlin.checkers.CheckerTestUtil.ActualDiagnostic
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
import org.jetbrains.kotlin.load.java.InternalFlexibleTypeTransformer
|
||||
@@ -111,19 +113,6 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
override fun toString(): String = name
|
||||
}
|
||||
|
||||
data class DiagnosticTestLanguageVersionSettings(
|
||||
private val languageFeatures: Map<LanguageFeature, LanguageFeature.State>,
|
||||
override val apiVersion: ApiVersion,
|
||||
override val languageVersion: LanguageVersion
|
||||
) : LanguageVersionSettings {
|
||||
private val delegate = LanguageVersionSettingsImpl(languageVersion, apiVersion)
|
||||
|
||||
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State =
|
||||
languageFeatures[feature] ?: delegate.getFeatureSupport(feature)
|
||||
|
||||
override fun <T> getFlag(flag: AnalysisFlag<T>): T = flag.defaultValue
|
||||
}
|
||||
|
||||
inner class TestFile(
|
||||
val module: TestModule?,
|
||||
fileName: String,
|
||||
@@ -293,15 +282,10 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
CheckerTestUtil.DebugInfoDiagnosticFactory.UNRESOLVED_WITH_TARGET
|
||||
)
|
||||
|
||||
val LANGUAGE_DIRECTIVE = "LANGUAGE"
|
||||
private val LANGUAGE_PATTERN = Pattern.compile("(\\+|\\-|warn:)(\\w+)\\s*")
|
||||
|
||||
val DEFAULT_DIAGNOSTIC_TESTS_FEATURES = mapOf(
|
||||
LanguageFeature.Coroutines to LanguageFeature.State.ENABLED
|
||||
)
|
||||
|
||||
val API_VERSION_DIRECTIVE = "API_VERSION"
|
||||
|
||||
val CHECK_TYPE_DIRECTIVE = "CHECK_TYPE"
|
||||
val CHECK_TYPE_PACKAGE = "tests._checkType"
|
||||
private val CHECK_TYPE_DECLARATIONS = "\npackage " + CHECK_TYPE_PACKAGE +
|
||||
@@ -322,53 +306,6 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
|
||||
val MARK_DYNAMIC_CALLS_DIRECTIVE = "MARK_DYNAMIC_CALLS"
|
||||
|
||||
private fun parseLanguageVersionSettings(directiveMap: Map<String, String>): LanguageVersionSettings? {
|
||||
val apiVersionString = directiveMap[API_VERSION_DIRECTIVE]
|
||||
val directives = directiveMap[LANGUAGE_DIRECTIVE]
|
||||
if (apiVersionString == null && directives == null) return null
|
||||
|
||||
val apiVersion = (if (apiVersionString != null) ApiVersion.parse(apiVersionString) else ApiVersion.LATEST_STABLE)
|
||||
?: error("Unknown API version: $apiVersionString")
|
||||
|
||||
val languageFeatures = directives?.let(this::collectLanguageFeatureMap).orEmpty()
|
||||
|
||||
return DiagnosticTestLanguageVersionSettings(languageFeatures, apiVersion, LanguageVersion.LATEST_STABLE)
|
||||
}
|
||||
|
||||
private fun collectLanguageFeatureMap(directives: String): Map<LanguageFeature, LanguageFeature.State> {
|
||||
val matcher = LANGUAGE_PATTERN.matcher(directives)
|
||||
if (!matcher.find()) {
|
||||
Assert.fail(
|
||||
"Wrong syntax in the '// !$LANGUAGE_DIRECTIVE: ...' directive:\n" +
|
||||
"found: '$directives'\n" +
|
||||
"Must be '((+|-|warn:)LanguageFeatureName)+'\n" +
|
||||
"where '+' means 'enable', '-' means 'disable', 'warn:' means 'enable with warning'\n" +
|
||||
"and language feature names are names of enum entries in LanguageFeature enum class"
|
||||
)
|
||||
}
|
||||
|
||||
val values = HashMap<LanguageFeature, LanguageFeature.State>()
|
||||
do {
|
||||
val mode = when (matcher.group(1)) {
|
||||
"+" -> LanguageFeature.State.ENABLED
|
||||
"-" -> LanguageFeature.State.DISABLED
|
||||
"warn:" -> LanguageFeature.State.ENABLED_WITH_WARNING
|
||||
else -> error("Unknown mode for language feature: ${matcher.group(1)}")
|
||||
}
|
||||
val name = matcher.group(2)
|
||||
val feature = LanguageFeature.fromString(name) ?: throw AssertionError(
|
||||
"Language feature not found, please check spelling: $name\n" +
|
||||
"Known features:\n ${LanguageFeature.values().joinToString("\n ")}"
|
||||
)
|
||||
if (values.put(feature, mode) != null) {
|
||||
Assert.fail("Duplicate entry for the language feature: $name")
|
||||
}
|
||||
}
|
||||
while (matcher.find())
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
private fun parseDiagnosticFilterDirective(directiveMap: Map<String, String>, allowUnderscoreUsage: Boolean): Condition<Diagnostic> {
|
||||
val directives = directiveMap[DIAGNOSTICS_DIRECTIVE]
|
||||
val initialCondition =
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.checkers
|
||||
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.junit.Assert
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
const val LANGUAGE_DIRECTIVE = "LANGUAGE"
|
||||
const val API_VERSION_DIRECTIVE = "API_VERSION"
|
||||
|
||||
data class CompilerTestLanguageVersionSettings(
|
||||
private val languageFeatures: Map<LanguageFeature, LanguageFeature.State>,
|
||||
override val apiVersion: ApiVersion,
|
||||
override val languageVersion: LanguageVersion
|
||||
) : LanguageVersionSettings {
|
||||
private val delegate = LanguageVersionSettingsImpl(languageVersion, apiVersion)
|
||||
|
||||
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State =
|
||||
languageFeatures[feature] ?: delegate.getFeatureSupport(feature)
|
||||
|
||||
override fun <T> getFlag(flag: AnalysisFlag<T>): T = flag.defaultValue
|
||||
}
|
||||
|
||||
fun parseLanguageVersionSettings(directiveMap: Map<String, String>): LanguageVersionSettings? {
|
||||
val apiVersionString = directiveMap[API_VERSION_DIRECTIVE]
|
||||
val directives = directiveMap[LANGUAGE_DIRECTIVE]
|
||||
if (apiVersionString == null && directives == null) return null
|
||||
|
||||
val apiVersion = (if (apiVersionString != null) ApiVersion.parse(apiVersionString) else ApiVersion.LATEST_STABLE)
|
||||
?: error("Unknown API version: $apiVersionString")
|
||||
|
||||
val languageFeatures = directives?.let(::collectLanguageFeatureMap).orEmpty()
|
||||
|
||||
return CompilerTestLanguageVersionSettings(languageFeatures, apiVersion, LanguageVersion.LATEST_STABLE)
|
||||
}
|
||||
|
||||
private val languagePattern = Pattern.compile("(\\+|\\-|warn:)(\\w+)\\s*")
|
||||
|
||||
private fun collectLanguageFeatureMap(directives: String): Map<LanguageFeature, LanguageFeature.State> {
|
||||
val matcher = languagePattern.matcher(directives)
|
||||
if (!matcher.find()) {
|
||||
Assert.fail(
|
||||
"Wrong syntax in the '// !$LANGUAGE_DIRECTIVE: ...' directive:\n" +
|
||||
"found: '$directives'\n" +
|
||||
"Must be '((+|-|warn:)LanguageFeatureName)+'\n" +
|
||||
"where '+' means 'enable', '-' means 'disable', 'warn:' means 'enable with warning'\n" +
|
||||
"and language feature names are names of enum entries in LanguageFeature enum class"
|
||||
)
|
||||
}
|
||||
|
||||
val values = HashMap<LanguageFeature, LanguageFeature.State>()
|
||||
do {
|
||||
val mode = when (matcher.group(1)) {
|
||||
"+" -> LanguageFeature.State.ENABLED
|
||||
"-" -> LanguageFeature.State.DISABLED
|
||||
"warn:" -> LanguageFeature.State.ENABLED_WITH_WARNING
|
||||
else -> error("Unknown mode for language feature: ${matcher.group(1)}")
|
||||
}
|
||||
val name = matcher.group(2)
|
||||
val feature = LanguageFeature.fromString(name) ?: throw AssertionError(
|
||||
"Language feature not found, please check spelling: $name\n" +
|
||||
"Known features:\n ${LanguageFeature.values().joinToString("\n ")}"
|
||||
)
|
||||
if (values.put(feature, mode) != null) {
|
||||
Assert.fail("Duplicate entry for the language feature: $name")
|
||||
}
|
||||
}
|
||||
while (matcher.find())
|
||||
|
||||
return values
|
||||
}
|
||||
@@ -76,6 +76,7 @@ import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettingsKt.parseLanguageVersionSettings;
|
||||
import static org.jetbrains.kotlin.cli.common.output.outputUtils.OutputUtilsKt.writeAllTo;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenTestUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.TestUtilsKt.*;
|
||||
@@ -161,8 +162,10 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
@NotNull List<TestFile> testFilesWithConfigurationDirectives,
|
||||
@NotNull CompilerConfiguration configuration
|
||||
) {
|
||||
List<String> kotlinConfigurationFlags = new ArrayList<>(0);
|
||||
LanguageVersionSettings explicitLanguageVersionSettings = null;
|
||||
LanguageVersion explicitLanguageVersion = null;
|
||||
|
||||
List<String> kotlinConfigurationFlags = new ArrayList<>(0);
|
||||
for (TestFile testFile : testFilesWithConfigurationDirectives) {
|
||||
kotlinConfigurationFlags.addAll(InTextDirectivesUtils.findListWithPrefixes(testFile.content, "// KOTLIN_CONFIGURATION_FLAGS:"));
|
||||
|
||||
@@ -176,12 +179,22 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
|
||||
String version = InTextDirectivesUtils.findStringWithPrefixes(testFile.content, "// LANGUAGE_VERSION:");
|
||||
if (version != null) {
|
||||
assert explicitLanguageVersion == null : "Should not specify LANGUAGE_VERSION twice";
|
||||
assertDirectivesToNull(explicitLanguageVersionSettings, explicitLanguageVersion);
|
||||
explicitLanguageVersion = LanguageVersion.fromVersionString(version);
|
||||
}
|
||||
|
||||
Map<String, String> directives = KotlinTestUtils.parseDirectives(testFile.content);
|
||||
LanguageVersionSettings fileLanguageVersionSettings = parseLanguageVersionSettings(directives);
|
||||
if (fileLanguageVersionSettings != null) {
|
||||
assertDirectivesToNull(explicitLanguageVersionSettings, explicitLanguageVersion);
|
||||
explicitLanguageVersionSettings = fileLanguageVersionSettings;
|
||||
}
|
||||
}
|
||||
|
||||
if (explicitLanguageVersion != null) {
|
||||
if (explicitLanguageVersionSettings != null) {
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, explicitLanguageVersionSettings);
|
||||
}
|
||||
else if (explicitLanguageVersion != null) {
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(
|
||||
configuration,
|
||||
new LanguageVersionSettingsImpl(explicitLanguageVersion, ApiVersion.createByLanguageVersion(explicitLanguageVersion))
|
||||
@@ -191,6 +204,10 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
updateConfigurationWithFlags(configuration, kotlinConfigurationFlags);
|
||||
}
|
||||
|
||||
private static void assertDirectivesToNull(@Nullable LanguageVersionSettings settings, @Nullable LanguageVersion version) {
|
||||
assert settings == null && version == null : "Should not specify LANGUAGE_VERSION twice or together with !LANGUAGE directive";
|
||||
}
|
||||
|
||||
private static final Map<String, Class<?>> FLAG_NAMESPACE_TO_CLASS = ImmutableMap.of(
|
||||
"CLI", CLIConfigurationKeys.class,
|
||||
"JVM", JVMConfigurationKeys.class
|
||||
|
||||
Reference in New Issue
Block a user