Move common logic from CodegenTestCase to KotlinBaseTest
This commit is contained in:
+2
-2
@@ -294,7 +294,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
val kind = KotlinBaseTest.extractConfigurationKind(testFiles)
|
||||
val jdkKind = KotlinBaseTest.getTestJdkKind(testFiles)
|
||||
val keyConfiguration = CompilerConfiguration()
|
||||
CodegenTestCase.updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration)
|
||||
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration)
|
||||
|
||||
val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString())
|
||||
val compiler = if (isJvm8Target) {
|
||||
@@ -303,7 +303,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
val filesHolder = holders.getOrPut(key) {
|
||||
FilesWriter(compiler, KotlinTestUtils.newConfiguration(kind, jdkKind, KotlinTestUtils.getAnnotationsJar()).apply {
|
||||
println("Creating new configuration by $key")
|
||||
CodegenTestCase.updateConfigurationByDirectivesInTestFiles(testFiles, this)
|
||||
KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, this)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -24,7 +24,7 @@ abstract class AbstractCompileKotlinAgainstKlibTest : AbstractBlackBoxCodegenTes
|
||||
lateinit var klibName: String
|
||||
lateinit var outputDir: File
|
||||
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
||||
outputDir = javaSourcesOutputDirectory
|
||||
@@ -56,6 +56,7 @@ abstract class AbstractCompileKotlinAgainstKlibTest : AbstractBlackBoxCodegenTes
|
||||
}
|
||||
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
super.updateConfiguration(configuration)
|
||||
configuration.put(JVMConfigurationKeys.KLIB_PATHS, listOf(klibName + ".klib"))
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
|
||||
abstract class AbstractForeignAnnotationsNoAnnotationInClasspathWithPsiClassReadingTest :
|
||||
AbstractForeignAnnotationsNoAnnotationInClasspathTest() {
|
||||
override fun performCustomConfiguration(configuration: CompilerConfiguration) {
|
||||
super.performCustomConfiguration(configuration)
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
super.updateConfiguration(configuration)
|
||||
configuration.put(JVMConfigurationKeys.USE_PSI_CLASS_FILES_READING, true)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-7
@@ -44,11 +44,12 @@ abstract class KotlinMultiFileTestWithJava<M : KotlinBaseTest.TestModule, F : Ko
|
||||
file: File,
|
||||
files: List<F>
|
||||
): KotlinCoreEnvironment {
|
||||
val configuration = KotlinTestUtils.newConfiguration(
|
||||
val configuration = createConfiguration(
|
||||
extractConfigurationKind(files),
|
||||
getTestJdkKind(files),
|
||||
getClasspath(file),
|
||||
if (isJavaSourceRootNeeded()) listOf(javaFilesDir) else emptyList()
|
||||
if (isJavaSourceRootNeeded()) listOf(javaFilesDir) else emptyList(),
|
||||
files
|
||||
)
|
||||
if (isScriptingNeeded(file)) {
|
||||
loadScriptingPlugin(configuration)
|
||||
@@ -61,16 +62,12 @@ abstract class KotlinMultiFileTestWithJava<M : KotlinBaseTest.TestModule, F : Ko
|
||||
// The main difference is the fact that the new class file reading implementation doesn't load parameter names from JDK classes.
|
||||
configuration.put(JVMConfigurationKeys.USE_PSI_CLASS_FILES_READING, true)
|
||||
|
||||
performCustomConfiguration(configuration)
|
||||
updateConfiguration(configuration)
|
||||
return createForTests(testRootDisposable, configuration, getEnvironmentConfigFiles())
|
||||
}
|
||||
|
||||
protected open fun isJavaSourceRootNeeded(): Boolean = true
|
||||
|
||||
protected open fun performCustomConfiguration(configuration: CompilerConfiguration) {}
|
||||
|
||||
protected open fun setupEnvironment(environment: KotlinCoreEnvironment) {}
|
||||
|
||||
protected open fun setupEnvironment(
|
||||
environment: KotlinCoreEnvironment,
|
||||
testDataFile: File,
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ abstract class AbstractBlackBoxAgainstJavaCodegenTest : AbstractBlackBoxCodegenT
|
||||
}
|
||||
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
super.updateConfiguration(configuration)
|
||||
configuration.addJvmClasspathRoot(javaClassesOutputDirectory)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
|
||||
@@ -26,6 +25,7 @@ abstract class AbstractDumpDeclarationsTest : CodegenTestCase() {
|
||||
}
|
||||
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
super.updateConfiguration(configuration)
|
||||
configuration.put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, dumpToFile.path)
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -38,6 +38,7 @@ public abstract class AbstractScriptCodegenTest extends CodegenTestCase {
|
||||
|
||||
@Override
|
||||
protected void updateConfiguration(@NotNull CompilerConfiguration configuration) {
|
||||
super.updateConfiguration(configuration);
|
||||
loadScriptingPlugin(configuration);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.testFramework.TestDataFile;
|
||||
@@ -21,7 +19,6 @@ import org.jetbrains.kotlin.TestsCompilerError;
|
||||
import org.jetbrains.kotlin.TestsCompiletimeError;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection;
|
||||
import org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil;
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
|
||||
import org.jetbrains.kotlin.cli.common.output.OutputUtilsKt;
|
||||
@@ -29,14 +26,14 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace;
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot;
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt;
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.config.*;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys;
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider;
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper;
|
||||
import org.jetbrains.kotlin.test.*;
|
||||
@@ -55,17 +52,13 @@ import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.*;
|
||||
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.OutputUtilsKt.writeAllTo;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenTestUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.TestUtilsKt.extractUrls;
|
||||
@@ -118,192 +111,6 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
||||
);
|
||||
}
|
||||
|
||||
protected void configureTestSpecific(@NotNull CompilerConfiguration configuration, @NotNull List<TestFile> testFiles) {}
|
||||
|
||||
@NotNull
|
||||
protected CompilerConfiguration createConfiguration(
|
||||
@NotNull ConfigurationKind kind,
|
||||
@NotNull TestJdkKind jdkKind,
|
||||
@NotNull List<File> classpath,
|
||||
@NotNull List<File> javaSource,
|
||||
@NotNull List<TestFile> testFilesWithConfigurationDirectives
|
||||
) {
|
||||
CompilerConfiguration configuration = KotlinTestUtils.newConfiguration(kind, jdkKind, classpath, javaSource);
|
||||
configuration.put(JVMConfigurationKeys.IR, getBackend().isIR());
|
||||
|
||||
updateConfigurationByDirectivesInTestFiles(testFilesWithConfigurationDirectives, configuration, coroutinesPackage, parseDirectivesPerFiles());
|
||||
updateConfiguration(configuration);
|
||||
setCustomDefaultJvmTarget(configuration);
|
||||
|
||||
configureTestSpecific(configuration, testFilesWithConfigurationDirectives);
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public static void updateConfigurationByDirectivesInTestFiles(
|
||||
@NotNull List<TestFile> testFilesWithConfigurationDirectives,
|
||||
@NotNull CompilerConfiguration configuration
|
||||
) {
|
||||
updateConfigurationByDirectivesInTestFiles(testFilesWithConfigurationDirectives, configuration, "", false);
|
||||
}
|
||||
|
||||
private static void updateConfigurationByDirectivesInTestFiles(
|
||||
@NotNull List<TestFile> testFilesWithConfigurationDirectives,
|
||||
@NotNull CompilerConfiguration configuration,
|
||||
@NotNull String coroutinesPackage,
|
||||
boolean usePreparsedDirectives
|
||||
) {
|
||||
LanguageVersionSettings explicitLanguageVersionSettings = null;
|
||||
boolean disableReleaseCoroutines = false;
|
||||
boolean includeCompatExperimentalCoroutines = false;
|
||||
|
||||
List<String> kotlinConfigurationFlags = new ArrayList<>(0);
|
||||
for (TestFile testFile : testFilesWithConfigurationDirectives) {
|
||||
String content = testFile.content;
|
||||
Directives directives = usePreparsedDirectives ? testFile.directives : KotlinTestUtils.parseDirectives(content);
|
||||
List<String> flags = directives.listValues("KOTLIN_CONFIGURATION_FLAGS");
|
||||
if (flags != null) {
|
||||
kotlinConfigurationFlags.addAll(flags);
|
||||
}
|
||||
|
||||
String targetString = directives.get("JVM_TARGET");
|
||||
if (targetString != null) {
|
||||
JvmTarget jvmTarget = JvmTarget.Companion.fromString(targetString);
|
||||
assert jvmTarget != null : "Unknown target: " + targetString;
|
||||
configuration.put(JVMConfigurationKeys.JVM_TARGET, jvmTarget);
|
||||
}
|
||||
|
||||
String version = directives.get("LANGUAGE_VERSION");
|
||||
if (version != null) {
|
||||
throw new AssertionError(
|
||||
"Do not use LANGUAGE_VERSION directive in compiler tests because it's prone to limiting the test\n" +
|
||||
"to a specific language version, which will become obsolete at some point and the test won't check\n" +
|
||||
"things like feature intersection with newer releases. Use `// !LANGUAGE: [+-]FeatureName` directive instead,\n" +
|
||||
"where FeatureName is an entry of the enum `LanguageFeature`\n"
|
||||
);
|
||||
}
|
||||
|
||||
if (directives.contains("COMMON_COROUTINES_TEST")) {
|
||||
assert !directives.contains("COROUTINES_PACKAGE") : "Must replace COROUTINES_PACKAGE prior to tests compilation";
|
||||
if (DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString().equals(coroutinesPackage)) {
|
||||
disableReleaseCoroutines = true;
|
||||
includeCompatExperimentalCoroutines = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (content.contains(DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString())) {
|
||||
includeCompatExperimentalCoroutines = true;
|
||||
}
|
||||
|
||||
LanguageVersionSettings fileLanguageVersionSettings = parseLanguageVersionSettings(directives);
|
||||
if (fileLanguageVersionSettings != null) {
|
||||
assert explicitLanguageVersionSettings == null : "Should not specify !LANGUAGE directive twice";
|
||||
explicitLanguageVersionSettings = fileLanguageVersionSettings;
|
||||
}
|
||||
}
|
||||
|
||||
if (disableReleaseCoroutines) {
|
||||
explicitLanguageVersionSettings = new CompilerTestLanguageVersionSettings(
|
||||
Collections.singletonMap(LanguageFeature.ReleaseCoroutines, LanguageFeature.State.DISABLED),
|
||||
ApiVersion.LATEST_STABLE,
|
||||
LanguageVersion.LATEST_STABLE,
|
||||
Collections.emptyMap()
|
||||
);
|
||||
}
|
||||
if (includeCompatExperimentalCoroutines) {
|
||||
JvmContentRootsKt.addJvmClasspathRoot(configuration, ForTestCompileRuntime.coroutinesCompatForTests());
|
||||
}
|
||||
|
||||
if (explicitLanguageVersionSettings != null) {
|
||||
CommonConfigurationKeysKt.setLanguageVersionSettings(configuration, explicitLanguageVersionSettings);
|
||||
}
|
||||
|
||||
updateConfigurationWithFlags(configuration, kotlinConfigurationFlags);
|
||||
}
|
||||
|
||||
private static final Map<String, Class<?>> FLAG_NAMESPACE_TO_CLASS = ImmutableMap.of(
|
||||
"CLI", CLIConfigurationKeys.class,
|
||||
"JVM", JVMConfigurationKeys.class
|
||||
);
|
||||
|
||||
private static final List<Class<?>> FLAG_CLASSES = ImmutableList.of(CLIConfigurationKeys.class, JVMConfigurationKeys.class);
|
||||
|
||||
private static final Pattern BOOLEAN_FLAG_PATTERN = Pattern.compile("([+-])(([a-zA-Z_0-9]*)\\.)?([a-zA-Z_0-9]*)");
|
||||
private static final Pattern CONSTRUCTOR_CALL_NORMALIZATION_MODE_FLAG_PATTERN = Pattern.compile(
|
||||
"CONSTRUCTOR_CALL_NORMALIZATION_MODE=([a-zA-Z_\\-0-9]*)");
|
||||
private static final Pattern ASSERTIONS_MODE_FLAG_PATTERN = Pattern.compile("ASSERTIONS_MODE=([a-zA-Z_0-9-]*)");
|
||||
|
||||
private static void updateConfigurationWithFlags(@NotNull CompilerConfiguration configuration, @NotNull List<String> flags) {
|
||||
for (String flag : flags) {
|
||||
Matcher m = BOOLEAN_FLAG_PATTERN.matcher(flag);
|
||||
if (m.matches()) {
|
||||
boolean flagEnabled = !"-".equals(m.group(1));
|
||||
String flagNamespace = m.group(3);
|
||||
String flagName = m.group(4);
|
||||
|
||||
tryApplyBooleanFlag(configuration, flag, flagEnabled, flagNamespace, flagName);
|
||||
continue;
|
||||
}
|
||||
|
||||
m = CONSTRUCTOR_CALL_NORMALIZATION_MODE_FLAG_PATTERN.matcher(flag);
|
||||
if (m.matches()) {
|
||||
String flagValueString = m.group(1);
|
||||
JVMConstructorCallNormalizationMode mode = JVMConstructorCallNormalizationMode.fromStringOrNull(flagValueString);
|
||||
assert mode != null : "Wrong CONSTRUCTOR_CALL_NORMALIZATION_MODE value: " + flagValueString;
|
||||
configuration.put(JVMConfigurationKeys.CONSTRUCTOR_CALL_NORMALIZATION_MODE, mode);
|
||||
}
|
||||
|
||||
m = ASSERTIONS_MODE_FLAG_PATTERN.matcher(flag);
|
||||
if (m.matches()) {
|
||||
String flagValueString = m.group(1);
|
||||
JVMAssertionsMode mode = JVMAssertionsMode.fromStringOrNull(flagValueString);
|
||||
assert mode != null : "Wrong ASSERTIONS_MODE value: " + flagValueString;
|
||||
configuration.put(JVMConfigurationKeys.ASSERTIONS_MODE, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void tryApplyBooleanFlag(
|
||||
@NotNull CompilerConfiguration configuration,
|
||||
@NotNull String flag,
|
||||
boolean flagEnabled,
|
||||
@Nullable String flagNamespace,
|
||||
@NotNull String flagName
|
||||
) {
|
||||
Class<?> configurationKeysClass;
|
||||
Field configurationKeyField = null;
|
||||
if (flagNamespace == null) {
|
||||
for (Class<?> flagClass : FLAG_CLASSES) {
|
||||
try {
|
||||
configurationKeyField = flagClass.getField(flagName);
|
||||
break;
|
||||
}
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
configurationKeysClass = FLAG_NAMESPACE_TO_CLASS.get(flagNamespace);
|
||||
assert configurationKeysClass != null : "Expected [+|-][namespace.]configurationKey, got: " + flag;
|
||||
try {
|
||||
configurationKeyField = configurationKeysClass.getField(flagName);
|
||||
}
|
||||
catch (Exception e) {
|
||||
configurationKeyField = null;
|
||||
}
|
||||
}
|
||||
assert configurationKeyField != null : "Expected [+|-][namespace.]configurationKey, got: " + flag;
|
||||
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
CompilerConfigurationKey<Boolean> configurationKey = (CompilerConfigurationKey<Boolean>) configurationKeyField.get(null);
|
||||
configuration.put(configurationKey, flagEnabled);
|
||||
}
|
||||
catch (Exception e) {
|
||||
assert false : "Expected [+|-][namespace.]configurationKey, got: " + flag;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
myFiles = null;
|
||||
@@ -638,19 +445,16 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
||||
return findDeclaredMethodByName(generateFacadeClass(), name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateConfiguration(@NotNull CompilerConfiguration configuration) {
|
||||
|
||||
setCustomDefaultJvmTarget(configuration);
|
||||
}
|
||||
|
||||
protected ClassBuilderFactory getClassBuilderFactory() {
|
||||
return ClassBuilderFactories.TEST;
|
||||
}
|
||||
|
||||
protected void setupEnvironment(@NotNull KotlinCoreEnvironment environment) {
|
||||
|
||||
}
|
||||
|
||||
protected void setCustomDefaultJvmTarget(CompilerConfiguration configuration) {
|
||||
private static void setCustomDefaultJvmTarget(CompilerConfiguration configuration) {
|
||||
if (DEFAULT_JVM_TARGET != null) {
|
||||
JvmTarget customDefaultTarget = JvmTarget.fromString(DEFAULT_JVM_TARGET);
|
||||
assert customDefaultTarget != null : "Can't construct JvmTarget for " + DEFAULT_JVM_TARGET;
|
||||
@@ -750,6 +554,8 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected TargetBackend getBackend() {
|
||||
return TargetBackend.JVM;
|
||||
}
|
||||
@@ -801,9 +607,6 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
||||
return testFiles;
|
||||
}
|
||||
|
||||
protected boolean parseDirectivesPerFiles() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected File getJavaSourcesOutputDirectory() {
|
||||
|
||||
+2
-1
@@ -8,5 +8,6 @@ package org.jetbrains.kotlin.codegen.debugInformation
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrLocalVariableTest : AbstractLocalVariableTest() {
|
||||
override fun getBackend(): TargetBackend = TargetBackend.JVM_IR
|
||||
override val backend: TargetBackend
|
||||
get() = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+2
-1
@@ -8,5 +8,6 @@ package org.jetbrains.kotlin.codegen.debugInformation
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrSteppingTest : AbstractSteppingTest() {
|
||||
override fun getBackend(): TargetBackend = TargetBackend.JVM_IR
|
||||
override val backend: TargetBackend
|
||||
get() = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
|
||||
abstract class AbstractFirBlackBoxCodegenTest : AbstractIrBlackBoxCodegenTest() {
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
super.updateConfiguration(configuration)
|
||||
configuration.put(CommonConfigurationKeys.USE_FIR, true)
|
||||
configuration.put(JVMConfigurationKeys.IR, true)
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.codegen.AbstractAsmLikeInstructionListingTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrAsmLikeInstructionListingTest : AbstractAsmLikeInstructionListingTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
+1
-1
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.codegen.AbstractBlackBoxAgainstJavaCodegenTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrBlackBoxAgainstJavaCodegenTest : AbstractBlackBoxAgainstJavaCodegenTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,5 +20,5 @@ import org.jetbrains.kotlin.codegen.AbstractBlackBoxCodegenTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrBlackBoxCodegenTest : AbstractBlackBoxCodegenTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -20,5 +20,5 @@ import org.jetbrains.kotlin.codegen.AbstractBlackBoxCodegenTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrBlackBoxInlineCodegenTest : AbstractBlackBoxCodegenTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.codegen.AbstractBytecodeListingTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrBytecodeListingTest : AbstractBytecodeListingTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.codegen.AbstractBytecodeTextTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrBytecodeTextTest : AbstractBytecodeTextTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.codegen.AbstractCheckLocalVariablesTableTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrCheckLocalVariablesTableTest : AbstractCheckLocalVariablesTableTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.codegen.AbstractCompileKotlinAgainstInlineKotlinTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrCompileKotlinAgainstInlineKotlinTest : AbstractCompileKotlinAgainstInlineKotlinTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.codegen.AbstractCompileKotlinAgainstKotlinTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrCompileKotlinAgainstKotlinTest : AbstractCompileKotlinAgainstKotlinTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.codegen.flags.AbstractWriteFlagsTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrWriteFlagsTest : AbstractWriteFlagsTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@ import org.jetbrains.kotlin.jvm.compiler.AbstractWriteSignatureTest
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrWriteSignatureTest : AbstractWriteSignatureTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
@@ -5,8 +5,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.test
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.common.collect.ImmutableMap
|
||||
import org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettings
|
||||
import org.jetbrains.kotlin.checkers.parseLanguageVersionSettings
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.config.JvmTarget.Companion.fromString
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||
import java.io.File
|
||||
import java.lang.reflect.Field
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
abstract class KotlinBaseTest<F : KotlinBaseTest.TestFile> : KtUsefulTestCase() {
|
||||
|
||||
@@ -58,6 +72,35 @@ abstract class KotlinBaseTest<F : KotlinBaseTest.TestFile> : KtUsefulTestCase()
|
||||
return Companion.extractConfigurationKind(files)
|
||||
}
|
||||
|
||||
protected open fun updateConfiguration(configuration: CompilerConfiguration) {}
|
||||
|
||||
protected open fun setupEnvironment(environment: KotlinCoreEnvironment) {}
|
||||
|
||||
protected open fun parseDirectivesPerFiles() = false
|
||||
|
||||
protected open val backend = TargetBackend.ANY
|
||||
|
||||
protected open fun configureTestSpecific(configuration: CompilerConfiguration, testFiles: List<TestFile>) {}
|
||||
|
||||
protected open fun createConfiguration(
|
||||
kind: ConfigurationKind,
|
||||
jdkKind: TestJdkKind,
|
||||
classpath: List<File?>,
|
||||
javaSource: List<File?>,
|
||||
testFilesWithConfigurationDirectives: List<TestFile>
|
||||
): CompilerConfiguration {
|
||||
val configuration = KotlinTestUtils.newConfiguration(kind, jdkKind, classpath, javaSource)
|
||||
configuration.put(JVMConfigurationKeys.IR, backend.isIR)
|
||||
updateConfigurationByDirectivesInTestFiles(
|
||||
testFilesWithConfigurationDirectives,
|
||||
configuration,
|
||||
coroutinesPackage,
|
||||
parseDirectivesPerFiles()
|
||||
)
|
||||
updateConfiguration(configuration)
|
||||
configureTestSpecific(configuration, testFilesWithConfigurationDirectives)
|
||||
return configuration
|
||||
}
|
||||
|
||||
open class TestFile @JvmOverloads constructor(
|
||||
@JvmField val name: String,
|
||||
@@ -97,6 +140,161 @@ abstract class KotlinBaseTest<F : KotlinBaseTest.TestFile> : KtUsefulTestCase()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private val FLAG_NAMESPACE_TO_CLASS: Map<String, Class<*>> = ImmutableMap.of(
|
||||
"CLI", CLIConfigurationKeys::class.java,
|
||||
"JVM", JVMConfigurationKeys::class.java
|
||||
)
|
||||
|
||||
private val FLAG_CLASSES: List<Class<*>> = ImmutableList.of(
|
||||
CLIConfigurationKeys::class.java,
|
||||
JVMConfigurationKeys::class.java
|
||||
)
|
||||
|
||||
private val BOOLEAN_FLAG_PATTERN = Pattern.compile("([+-])(([a-zA-Z_0-9]*)\\.)?([a-zA-Z_0-9]*)")
|
||||
private val CONSTRUCTOR_CALL_NORMALIZATION_MODE_FLAG_PATTERN = Pattern.compile(
|
||||
"CONSTRUCTOR_CALL_NORMALIZATION_MODE=([a-zA-Z_\\-0-9]*)"
|
||||
)
|
||||
private val ASSERTIONS_MODE_FLAG_PATTERN = Pattern.compile("ASSERTIONS_MODE=([a-zA-Z_0-9-]*)")
|
||||
|
||||
private fun tryApplyBooleanFlag(
|
||||
configuration: CompilerConfiguration,
|
||||
flag: String,
|
||||
flagEnabled: Boolean,
|
||||
flagNamespace: String?,
|
||||
flagName: String
|
||||
) {
|
||||
val configurationKeysClass: Class<*>?
|
||||
var configurationKeyField: Field? = null
|
||||
if (flagNamespace == null) {
|
||||
for (flagClass in FLAG_CLASSES) {
|
||||
try {
|
||||
configurationKeyField = flagClass.getField(flagName)
|
||||
break
|
||||
} catch (ignored: java.lang.Exception) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
configurationKeysClass = FLAG_NAMESPACE_TO_CLASS[flagNamespace]
|
||||
assert(configurationKeysClass != null) { "Expected [+|-][namespace.]configurationKey, got: $flag" }
|
||||
configurationKeyField = try {
|
||||
configurationKeysClass!!.getField(flagName)
|
||||
} catch (e: java.lang.Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
assert(configurationKeyField != null) { "Expected [+|-][namespace.]configurationKey, got: $flag" }
|
||||
try {
|
||||
val configurationKey = configurationKeyField!![null] as CompilerConfigurationKey<Boolean>
|
||||
configuration.put(configurationKey, flagEnabled)
|
||||
} catch (e: java.lang.Exception) {
|
||||
assert(false) { "Expected [+|-][namespace.]configurationKey, got: $flag" }
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun updateConfigurationByDirectivesInTestFiles1(
|
||||
testFilesWithConfigurationDirectives: List<TestFile>,
|
||||
configuration: CompilerConfiguration
|
||||
) {
|
||||
updateConfigurationByDirectivesInTestFiles(testFilesWithConfigurationDirectives, configuration, "", false)
|
||||
}
|
||||
|
||||
|
||||
private fun updateConfigurationByDirectivesInTestFiles(
|
||||
testFilesWithConfigurationDirectives: List<TestFile>,
|
||||
configuration: CompilerConfiguration,
|
||||
coroutinesPackage: String,
|
||||
usePreparsedDirectives: Boolean
|
||||
) {
|
||||
var explicitLanguageVersionSettings: LanguageVersionSettings? = null
|
||||
var disableReleaseCoroutines = false
|
||||
var includeCompatExperimentalCoroutines = false
|
||||
val kotlinConfigurationFlags: MutableList<String> = ArrayList(0)
|
||||
for (testFile in testFilesWithConfigurationDirectives) {
|
||||
val content = testFile.content
|
||||
val directives = if (usePreparsedDirectives) testFile.directives else KotlinTestUtils.parseDirectives(content)
|
||||
val flags = directives.listValues("KOTLIN_CONFIGURATION_FLAGS")
|
||||
if (flags != null) {
|
||||
kotlinConfigurationFlags.addAll(flags)
|
||||
}
|
||||
val targetString = directives["JVM_TARGET"]
|
||||
if (targetString != null) {
|
||||
val jvmTarget = fromString(targetString)
|
||||
?: error("Unknown target: $targetString")
|
||||
configuration.put(JVMConfigurationKeys.JVM_TARGET, jvmTarget)
|
||||
}
|
||||
val version = directives["LANGUAGE_VERSION"]
|
||||
if (version != null) {
|
||||
throw AssertionError(
|
||||
"""
|
||||
Do not use LANGUAGE_VERSION directive in compiler tests because it's prone to limiting the test
|
||||
to a specific language version, which will become obsolete at some point and the test won't check
|
||||
things like feature intersection with newer releases. Use `// !LANGUAGE: [+-]FeatureName` directive instead,
|
||||
where FeatureName is an entry of the enum `LanguageFeature`
|
||||
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
if (directives.contains("COMMON_COROUTINES_TEST")) {
|
||||
assert(!directives.contains("COROUTINES_PACKAGE")) { "Must replace COROUTINES_PACKAGE prior to tests compilation" }
|
||||
if (DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString() == coroutinesPackage) {
|
||||
disableReleaseCoroutines = true
|
||||
includeCompatExperimentalCoroutines = true
|
||||
}
|
||||
}
|
||||
if (content.contains(DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString())) {
|
||||
includeCompatExperimentalCoroutines = true
|
||||
}
|
||||
val fileLanguageVersionSettings: LanguageVersionSettings? = parseLanguageVersionSettings(directives)
|
||||
if (fileLanguageVersionSettings != null) {
|
||||
assert(explicitLanguageVersionSettings == null) { "Should not specify !LANGUAGE directive twice" }
|
||||
explicitLanguageVersionSettings = fileLanguageVersionSettings
|
||||
}
|
||||
}
|
||||
if (disableReleaseCoroutines) {
|
||||
explicitLanguageVersionSettings = CompilerTestLanguageVersionSettings(
|
||||
Collections.singletonMap(LanguageFeature.ReleaseCoroutines, LanguageFeature.State.DISABLED),
|
||||
ApiVersion.LATEST_STABLE,
|
||||
LanguageVersion.LATEST_STABLE, emptyMap()
|
||||
)
|
||||
}
|
||||
if (includeCompatExperimentalCoroutines) {
|
||||
configuration.addJvmClasspathRoot(ForTestCompileRuntime.coroutinesCompatForTests())
|
||||
}
|
||||
if (explicitLanguageVersionSettings != null) {
|
||||
configuration.languageVersionSettings = explicitLanguageVersionSettings
|
||||
}
|
||||
updateConfigurationWithFlags(configuration, kotlinConfigurationFlags)
|
||||
}
|
||||
|
||||
private fun updateConfigurationWithFlags(configuration: CompilerConfiguration, flags: List<String>) {
|
||||
for (flag in flags) {
|
||||
var m = BOOLEAN_FLAG_PATTERN.matcher(flag)
|
||||
if (m.matches()) {
|
||||
val flagEnabled = "-" != m.group(1)
|
||||
val flagNamespace = m.group(3)
|
||||
val flagName = m.group(4)
|
||||
tryApplyBooleanFlag(configuration, flag, flagEnabled, flagNamespace, flagName)
|
||||
continue
|
||||
}
|
||||
m = CONSTRUCTOR_CALL_NORMALIZATION_MODE_FLAG_PATTERN.matcher(flag)
|
||||
if (m.matches()) {
|
||||
val flagValueString = m.group(1)
|
||||
val mode = JVMConstructorCallNormalizationMode.fromStringOrNull(flagValueString)
|
||||
?: error("Wrong CONSTRUCTOR_CALL_NORMALIZATION_MODE value: $flagValueString")
|
||||
configuration.put(JVMConfigurationKeys.CONSTRUCTOR_CALL_NORMALIZATION_MODE, mode)
|
||||
}
|
||||
m = ASSERTIONS_MODE_FLAG_PATTERN.matcher(flag)
|
||||
if (m.matches()) {
|
||||
val flagValueString = m.group(1)
|
||||
val mode = JVMAssertionsMode.fromStringOrNull(flagValueString)
|
||||
?: error("Wrong ASSERTIONS_MODE value: $flagValueString")
|
||||
configuration.put(JVMConfigurationKeys.ASSERTIONS_MODE, mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun extractConfigurationKind(files: List<TestFile>): ConfigurationKind {
|
||||
var addRuntime = false
|
||||
var addReflect = false
|
||||
|
||||
@@ -37,6 +37,7 @@ abstract class AbstractCustomScriptCodegenTest : CodegenTestCase() {
|
||||
}
|
||||
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
super.updateConfiguration(configuration)
|
||||
if (scriptDefinitions.isNotEmpty()) {
|
||||
configureScriptDefinitions(
|
||||
scriptDefinitions, configuration, this::class.java.classLoader, MessageCollector.NONE, defaultJvmScriptingHostConfiguration
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.ir;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.codegen.AbstractGenerateNotNullAssertionsTest;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
|
||||
@@ -13,6 +14,7 @@ public class IrGenerateNotNullAssertionsTest extends AbstractGenerateNotNullAsse
|
||||
doTestNoAssertionsForKotlinFromBinary("noAssertionsForKotlin.kt", "noAssertionsForKotlinMain.kt");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected TargetBackend getBackend() {
|
||||
return TargetBackend.JVM_IR;
|
||||
|
||||
+1
-1
@@ -8,5 +8,5 @@ package org.jetbrains.kotlin.android.parcel
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractParcelIrBoxTest : AbstractParcelBoxTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.test.TargetBackend
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractParcelIrBytecodeListingTest : AbstractParcelBytecodeListingTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
|
||||
override fun getExpectedTextFileName(wholeFile: File): String {
|
||||
return wholeFile.nameWithoutExtension + ".ir.txt"
|
||||
|
||||
+1
-1
@@ -8,5 +8,5 @@ package org.jetbrains.kotlin.android.synthetic.test
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractAndroidIrBoxTest : AbstractAndroidBoxTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+2
-2
@@ -17,8 +17,8 @@ abstract class AbstractFirAllOpenDiagnosticTest : AbstractFirDiagnosticsTest() {
|
||||
service.registerExtensions(FirAllOpenComponentRegistrar().configure())
|
||||
}
|
||||
|
||||
override fun performCustomConfiguration(configuration: CompilerConfiguration) {
|
||||
super.performCustomConfiguration(configuration)
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
super.updateConfiguration(configuration)
|
||||
val jar = File("plugins/fir/fir-plugin-prototype/plugin-annotations/build/libs/plugin-annotations-1.4.255-SNAPSHOT.jar")
|
||||
if (!jar.exists()) {
|
||||
throw AssertionError("Jar with annotations does not exist. Please run :plugins:fir:fir-plugin-prototype:plugin-annotations:jar")
|
||||
|
||||
+1
-1
@@ -8,5 +8,5 @@ package org.jetbrains.kotlin.kapt3.test
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
|
||||
abstract class AbstractIrKotlinKapt3IntegrationTest : AbstractKotlinKapt3IntegrationTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+2
-2
@@ -12,9 +12,9 @@ Currently Kapt3 only works with the old backend. To enable IR, modify the isIrBa
|
||||
*/
|
||||
|
||||
abstract class AbstractIrClassFileToSourceStubConverterTest : AbstractClassFileToSourceStubConverterTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
abstract class AbstractIrKotlinKaptContextTest : AbstractKotlinKaptContextTest() {
|
||||
override fun getBackend() = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ abstract class AbstractSerializationIrBytecodeListingTest : AbstractAsmLikeInstr
|
||||
return wholeFile.nameWithoutExtension + ".ir.txt"
|
||||
}
|
||||
|
||||
override fun getBackend(): TargetBackend = TargetBackend.JVM_IR
|
||||
override val backend = TargetBackend.JVM_IR
|
||||
|
||||
override fun setupEnvironment(environment: KotlinCoreEnvironment) {
|
||||
SerializationComponentRegistrar.registerExtensions(environment.project)
|
||||
|
||||
Reference in New Issue
Block a user