Support per files test directives
This commit is contained in:
committed by
Mikhail Bogdanov
parent
34547b4e27
commit
ab7e71fd68
+1
-1
@@ -243,7 +243,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
expectedText,
|
||||
object : TestFiles.TestFileFactoryNoModules<TestFile>() {
|
||||
override fun create(fileName: String, text: String, directives: Map<String, String>): TestFile {
|
||||
return TestFile(fileName, text)
|
||||
return TestFile(fileName, text, directives)
|
||||
}
|
||||
}, false,
|
||||
"kotlin.coroutines"
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
// FILE: inline.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
// FILE: inline.kt
|
||||
// WITH_RUNTIME
|
||||
// FULL_JDK
|
||||
// TARGET_BACKEND: JVM
|
||||
@@ -11,7 +11,6 @@ inline fun inlineMe() {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
|
||||
import test.*
|
||||
|
||||
|
||||
-1
@@ -11,7 +11,6 @@ inline fun inlineMe() {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
|
||||
import test.*
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// FILE: inline.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
// FILE: inline.kt
|
||||
// WITH_RUNTIME
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
|
||||
@@ -11,7 +11,6 @@ inline fun call(c: () -> Unit) {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
|
||||
import test.*
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ class A {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
import test.*
|
||||
|
||||
class B {
|
||||
|
||||
@@ -17,7 +17,6 @@ class State {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
import test.*
|
||||
|
||||
class CheckerJvmAssertInlineFunctionAssertionsEnabled {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// FILE: inline.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
// FILE: inline.kt
|
||||
// WITH_RUNTIME
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
|
||||
@@ -14,7 +14,6 @@ object CrossinlineLambdaContainer {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
|
||||
import test.CrossinlineLambdaContainer.call
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// FILE: inline.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
// FILE: inline.kt
|
||||
// WITH_RUNTIME
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
|
||||
@@ -17,7 +17,6 @@ object CrossinlineLambdaContainer {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
|
||||
import test.CrossinlineLambdaContainer.call
|
||||
|
||||
|
||||
+1
-2
@@ -1,6 +1,6 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// FILE: inline.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
// FILE: inline.kt
|
||||
// WITH_RUNTIME
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
|
||||
@@ -17,7 +17,6 @@ object CrossinlineLambdaContainer {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
|
||||
import test.CrossinlineLambdaContainer.call
|
||||
|
||||
|
||||
-1
@@ -14,7 +14,6 @@ object CrossinlineLambdaContainer {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
|
||||
import test.CrossinlineLambdaContainer.call
|
||||
|
||||
|
||||
-1
@@ -13,7 +13,6 @@ object CrossinlineLambdaContainer {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
|
||||
import test.CrossinlineLambdaContainer.call
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ class B {
|
||||
}
|
||||
|
||||
// FILE: inlineSite.kt
|
||||
// KOTLIN_CONFIGURATION_FLAGS: ASSERTIONS_MODE=jvm
|
||||
import test.*
|
||||
|
||||
class Checker {
|
||||
|
||||
Vendored
+2
-2
@@ -1,12 +1,12 @@
|
||||
// TODO: split SKIP_INLINE_CHECK_IN by files
|
||||
// SKIP_INLINE_CHECK_IN: bar$default, foo$default
|
||||
// FILE: 1.kt
|
||||
// SKIP_INLINE_CHECK_IN: bar$default
|
||||
package test
|
||||
|
||||
inline fun bar(f: () -> String = { "OK" }) = f()
|
||||
// FILE: 2.kt
|
||||
|
||||
import test.*
|
||||
// SKIP_INLINE_CHECK_IN: foo$default
|
||||
inline fun foo(f: () -> String = { bar() }) = f()
|
||||
|
||||
fun box(): String {
|
||||
|
||||
+2
-2
@@ -57,8 +57,8 @@ abstract class AbstractCompilerLightClassTest : KotlinMultiFileTestWithJava<Kotl
|
||||
module: TestModule?,
|
||||
fileName: String,
|
||||
text: String,
|
||||
directives: Map<String, String>
|
||||
): TestFile = TestFile(fileName, text)
|
||||
directives: Map<String, String?>
|
||||
): TestFile = TestFile(fileName, text, directives)
|
||||
|
||||
companion object {
|
||||
fun findLightClass(allowFrontendExceptions: Boolean, environment: KotlinCoreEnvironment, fqname: String): PsiClass? {
|
||||
|
||||
@@ -83,7 +83,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
): TestModule =
|
||||
TestModule(name, dependencies, friends)
|
||||
|
||||
override fun createTestFile(module: TestModule?, fileName: String, text: String, directives: Map<String, String>): TestFile =
|
||||
override fun createTestFile(module: TestModule?, fileName: String, text: String, directives: Map<String, String?>): TestFile =
|
||||
TestFile(module, fileName, text, directives)
|
||||
|
||||
|
||||
@@ -138,8 +138,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
val module: TestModule?,
|
||||
val fileName: String,
|
||||
textWithMarkers: String,
|
||||
val directives: Map<String, String>
|
||||
) : KotlinBaseTest.TestFile(fileName, textWithMarkers) {
|
||||
directives: Map<String, String?>
|
||||
) : KotlinBaseTest.TestFile(fileName, textWithMarkers, directives) {
|
||||
val diagnosedRanges: MutableList<DiagnosedRange> = mutableListOf()
|
||||
private val diagnosedRangesToDiagnosticNames: MutableMap<IntRange, MutableSet<String>> = mutableMapOf()
|
||||
val actualDiagnostics: MutableList<ActualDiagnostic> = mutableListOf()
|
||||
@@ -411,7 +411,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
val DIAGNOSTIC_IN_TESTDATA_PATTERN = Regex("<!>|<!(.*?(\\(\".*?\"\\)|\\(\\))??)+(?<!<)!>")
|
||||
|
||||
fun parseDiagnosticFilterDirective(
|
||||
directiveMap: Map<String, String>,
|
||||
directiveMap: Map<String, String?>,
|
||||
allowUnderscoreUsage: Boolean
|
||||
): Condition<Diagnostic> {
|
||||
val directives = directiveMap[DIAGNOSTICS_DIRECTIVE]
|
||||
@@ -499,7 +499,7 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseJvmTarget(directiveMap: Map<String, String>) = directiveMap[JVM_TARGET]?.let { JvmTarget.fromString(it) }
|
||||
private fun parseJvmTarget(directiveMap: Map<String, String?>) = directiveMap[JVM_TARGET]?.let { JvmTarget.fromString(it) }
|
||||
|
||||
protected fun parseModulePlatformByName(moduleName: String): TargetPlatform? {
|
||||
val nameSuffix = moduleName.substringAfterLast("-", "").toUpperCase()
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ private fun specificFeaturesForTests(): Map<LanguageFeature, LanguageFeature.Sta
|
||||
fun parseLanguageVersionSettingsOrDefault(directiveMap: Map<String, String>): CompilerTestLanguageVersionSettings =
|
||||
parseLanguageVersionSettings(directiveMap) ?: defaultLanguageVersionSettings()
|
||||
|
||||
fun parseLanguageVersionSettings(directives: Map<String, String>): CompilerTestLanguageVersionSettings? {
|
||||
fun parseLanguageVersionSettings(directives: Map<String, String?>): CompilerTestLanguageVersionSettings? {
|
||||
val apiVersionString = directives[API_VERSION_DIRECTIVE]
|
||||
val languageFeaturesString = directives[LANGUAGE_DIRECTIVE]
|
||||
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ abstract class KotlinMultiFileTestWithJava<M : KotlinBaseTest.TestModule, F : Ko
|
||||
|
||||
protected abstract fun createTestModule(name: String, dependencies: List<String>, friends: List<String>): M?
|
||||
|
||||
protected abstract fun createTestFile(module: M?, fileName: String, text: String, directives: Map<String, String>): F
|
||||
protected abstract fun createTestFile(module: M?, fileName: String, text: String, directives: Map<String, String?>): F
|
||||
|
||||
protected open fun createTestFiles(
|
||||
file: File,
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ abstract class AbstractBlackBoxInlineCodegenTest : AbstractBlackBoxCodegenTest()
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
||||
super.doMultiFileTest(wholeFile, files)
|
||||
try {
|
||||
InlineTestUtil.checkNoCallsToInline(initializedClassLoader.allGeneratedFiles.filterClassFiles(), myFiles.psiFiles)
|
||||
InlineTestUtil.checkNoCallsToInline(initializedClassLoader.allGeneratedFiles.filterClassFiles(), files)
|
||||
SMAPTestUtil.checkSMAP(files, generateClassesInFile().getClassFiles(), false)
|
||||
} catch (e: Throwable) {
|
||||
println(generateToText())
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ abstract class AbstractCompileKotlinAgainstInlineKotlinTest : AbstractCompileKot
|
||||
try {
|
||||
val allGeneratedFiles = factory1.asList() + factory2.asList()
|
||||
val sourceFiles = factory1.inputFiles + factory2.inputFiles
|
||||
InlineTestUtil.checkNoCallsToInline(allGeneratedFiles.filterClassFiles(), sourceFiles)
|
||||
InlineTestUtil.checkNoCallsToInline(allGeneratedFiles.filterClassFiles(), files)
|
||||
SMAPTestUtil.checkSMAP(files, allGeneratedFiles.filterClassFiles(), true)
|
||||
} catch (e: Throwable) {
|
||||
if (!isIgnored) {
|
||||
|
||||
+5
@@ -83,6 +83,11 @@ public abstract class AbstractCompileKotlinAgainstKotlinTest extends CodegenTest
|
||||
callBoxMethodAndCheckResult(createGeneratedClassLoader(), className);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean parseDirectivesPerFiles() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private URLClassLoader createGeneratedClassLoader() throws Exception {
|
||||
return new URLClassLoader(
|
||||
|
||||
@@ -70,6 +70,7 @@ 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;
|
||||
import static org.jetbrains.kotlin.test.KotlinTestUtils.getAnnotationsJar;
|
||||
import static org.jetbrains.kotlin.test.KotlinTestUtils.parseDirectivesAndFlags;
|
||||
import static org.jetbrains.kotlin.test.clientserver.TestProcessServerKt.getBoxMethodOrNull;
|
||||
import static org.jetbrains.kotlin.test.clientserver.TestProcessServerKt.getGeneratedClass;
|
||||
|
||||
@@ -131,7 +132,7 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
||||
CompilerConfiguration configuration = KotlinTestUtils.newConfiguration(kind, jdkKind, classpath, javaSource);
|
||||
configuration.put(JVMConfigurationKeys.IR, getBackend().isIR());
|
||||
|
||||
updateConfigurationByDirectivesInTestFiles(testFilesWithConfigurationDirectives, configuration, coroutinesPackage);
|
||||
updateConfigurationByDirectivesInTestFiles(testFilesWithConfigurationDirectives, configuration, coroutinesPackage, parseDirectivesPerFiles());
|
||||
updateConfiguration(configuration);
|
||||
setCustomDefaultJvmTarget(configuration);
|
||||
|
||||
@@ -144,13 +145,14 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
||||
@NotNull List<TestFile> testFilesWithConfigurationDirectives,
|
||||
@NotNull CompilerConfiguration configuration
|
||||
) {
|
||||
updateConfigurationByDirectivesInTestFiles(testFilesWithConfigurationDirectives, configuration, "");
|
||||
updateConfigurationByDirectivesInTestFiles(testFilesWithConfigurationDirectives, configuration, "", false);
|
||||
}
|
||||
|
||||
private static void updateConfigurationByDirectivesInTestFiles(
|
||||
@NotNull List<TestFile> testFilesWithConfigurationDirectives,
|
||||
@NotNull CompilerConfiguration configuration,
|
||||
@NotNull String coroutinesPackage
|
||||
@NotNull String coroutinesPackage,
|
||||
boolean usePreparsedDirectives
|
||||
) {
|
||||
LanguageVersionSettings explicitLanguageVersionSettings = null;
|
||||
boolean disableReleaseCoroutines = false;
|
||||
@@ -158,17 +160,22 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
||||
|
||||
List<String> kotlinConfigurationFlags = new ArrayList<>(0);
|
||||
for (TestFile testFile : testFilesWithConfigurationDirectives) {
|
||||
kotlinConfigurationFlags.addAll(InTextDirectivesUtils.findListWithPrefixes(testFile.content, "// KOTLIN_CONFIGURATION_FLAGS:"));
|
||||
String content = testFile.content;
|
||||
Map<String, String> directives = usePreparsedDirectives ? testFile.directives : parseDirectivesAndFlags(content);
|
||||
|
||||
List<String> lines = InTextDirectivesUtils.findLinesWithPrefixesRemoved(testFile.content, "// JVM_TARGET:");
|
||||
if (!lines.isEmpty()) {
|
||||
String targetString = CollectionsKt.single(lines);
|
||||
String configurationFlags = directives.get("KOTLIN_CONFIGURATION_FLAGS");
|
||||
if (configurationFlags != null) {
|
||||
kotlinConfigurationFlags.addAll(InTextDirectivesUtils.splitValues(new ArrayList<>(), configurationFlags));
|
||||
}
|
||||
|
||||
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 = InTextDirectivesUtils.findStringWithPrefixes(testFile.content, "// LANGUAGE_VERSION:");
|
||||
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" +
|
||||
@@ -178,20 +185,18 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
||||
);
|
||||
}
|
||||
|
||||
if (!InTextDirectivesUtils.findLinesWithPrefixesRemoved(testFile.content, "// COMMON_COROUTINES_TEST").isEmpty()) {
|
||||
assert !testFile.content.contains("COROUTINES_PACKAGE") : "Must replace COROUTINES_PACKAGE prior to tests compilation";
|
||||
if (directives.containsKey("COMMON_COROUTINES_TEST")) {
|
||||
assert !directives.containsKey("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 (testFile.content.contains(DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString())) {
|
||||
if (content.contains(DescriptorUtils.COROUTINES_PACKAGE_FQ_NAME_EXPERIMENTAL.asString())) {
|
||||
includeCompatExperimentalCoroutines = true;
|
||||
}
|
||||
|
||||
Map<String, String> directives = KotlinTestUtils.parseDirectives(testFile.content);
|
||||
|
||||
LanguageVersionSettings fileLanguageVersionSettings = parseLanguageVersionSettings(directives);
|
||||
if (fileLanguageVersionSettings != null) {
|
||||
assert explicitLanguageVersionSettings == null : "Should not specify !LANGUAGE directive twice";
|
||||
@@ -770,20 +775,24 @@ public abstract class CodegenTestCase extends KotlinBaseTest<KotlinBaseTest.Test
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected List<TestFile> createTestFilesFromFile(File file, String expectedText) {
|
||||
protected List<TestFile> createTestFilesFromFile(File file, @NotNull String expectedText) {
|
||||
List testFiles = TestFiles.createTestFiles(file.getName(), expectedText, new TestFiles.TestFileFactoryNoModules<TestFile>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public TestFile create(@NotNull String fileName, @NotNull String text, @NotNull Map<String, String> directives) {
|
||||
return new TestFile(fileName, text);
|
||||
return new TestFile(fileName, text, directives);
|
||||
}
|
||||
}, coroutinesPackage);
|
||||
}, false, coroutinesPackage, parseDirectivesPerFiles());
|
||||
if (InTextDirectivesUtils.isDirectiveDefined(expectedText, "WITH_HELPERS")) {
|
||||
testFiles.add(new TestFile("CodegenTestHelpers.kt", TestHelperGeneratorKt.createTextForCodegenTestHelpers(getBackend())));
|
||||
}
|
||||
return testFiles;
|
||||
}
|
||||
|
||||
protected boolean parseDirectivesPerFiles() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected File getJavaSourcesOutputDirectory() {
|
||||
return createTempDirectory("java-files");
|
||||
|
||||
@@ -27,12 +27,13 @@ import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.KotlinBaseTest
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import java.util.*
|
||||
|
||||
object InlineTestUtil {
|
||||
fun checkNoCallsToInline(outputFiles: Iterable<OutputFile>, sourceFiles: List<KtFile>) {
|
||||
fun checkNoCallsToInline(outputFiles: Iterable<OutputFile>, files: List<KotlinBaseTest.TestFile>) {
|
||||
val inlineInfo = obtainInlineInfo(outputFiles)
|
||||
val inlineMethods = inlineInfo.inlineMethods
|
||||
assert(inlineMethods.isNotEmpty()) { "There are no inline methods" }
|
||||
@@ -40,12 +41,12 @@ object InlineTestUtil {
|
||||
val notInlinedCalls = checkInlineMethodNotInvoked(outputFiles, inlineMethods)
|
||||
assert(notInlinedCalls.isEmpty()) { "All inline methods should be inlined but:\n" + notInlinedCalls.joinToString("\n") }
|
||||
|
||||
val skipParameterChecking = sourceFiles.any {
|
||||
InTextDirectivesUtils.isDirectiveDefined(it.text, "NO_CHECK_LAMBDA_INLINING")
|
||||
val skipParameterChecking = files.any {
|
||||
it.directives.containsKey("NO_CHECK_LAMBDA_INLINING")
|
||||
} || !doLambdaInliningCheck(outputFiles, inlineInfo)
|
||||
|
||||
if (!skipParameterChecking) {
|
||||
val notInlinedParameters = checkParametersInlined(outputFiles, inlineInfo, sourceFiles)
|
||||
val notInlinedParameters = checkParametersInlined(outputFiles, inlineInfo, files)
|
||||
assert(notInlinedParameters.isEmpty()) {
|
||||
"All inline parameters should be inlined but:\n${notInlinedParameters.joinToString("\n")}\n" +
|
||||
"but if you have not inlined lambdas or anonymous objects enable NO_CHECK_LAMBDA_INLINING directive"
|
||||
@@ -167,11 +168,11 @@ object InlineTestUtil {
|
||||
}
|
||||
|
||||
private fun checkParametersInlined(
|
||||
outputFiles: Iterable<OutputFile>, inlineInfo: InlineInfo, sourceFiles: List<KtFile>
|
||||
outputFiles: Iterable<OutputFile>, inlineInfo: InlineInfo, files: List<KotlinBaseTest.TestFile>
|
||||
): ArrayList<NotInlinedParameter> {
|
||||
val skipMethods =
|
||||
sourceFiles.flatMap {
|
||||
InTextDirectivesUtils.findLinesWithPrefixesRemoved(it.text, "// SKIP_INLINE_CHECK_IN: ")
|
||||
files.flatMap {
|
||||
it.getListDirectiveIfPresent("SKIP_INLINE_CHECK_IN") ?: emptyList()
|
||||
}.toSet()
|
||||
|
||||
val inlinedMethods = inlineInfo.inlineMethods
|
||||
|
||||
@@ -62,21 +62,26 @@ public final class InTextDirectivesUtils {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
for (String line : findLinesWithPrefixesRemoved(fileText, prefixes)) {
|
||||
String unquoted = StringUtil.unquoteString(line);
|
||||
if (!unquoted.equals(line)) {
|
||||
result.add(unquoted);
|
||||
}
|
||||
else{
|
||||
String[] variants = line.split(",");
|
||||
for (String variant : variants) {
|
||||
result.add(variant.trim());
|
||||
}
|
||||
}
|
||||
splitValues(result, line);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<String> splitValues(List<String> result, String line) {
|
||||
String unquoted = StringUtil.unquoteString(line);
|
||||
if (!unquoted.equals(line)) {
|
||||
result.add(unquoted);
|
||||
}
|
||||
else{
|
||||
String[] variants = line.split(",");
|
||||
for (String variant : variants) {
|
||||
result.add(variant.trim());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isDirectiveDefined(String fileText, String directive) {
|
||||
return !findListWithPrefixes(fileText, directive).isEmpty();
|
||||
}
|
||||
|
||||
@@ -70,7 +70,11 @@ abstract class KotlinBaseTest<F : KotlinBaseTest.TestFile> : KtUsefulTestCase()
|
||||
}
|
||||
|
||||
|
||||
open class TestFile(@JvmField val name: String, @JvmField val content: String) : Comparable<TestFile> {
|
||||
open class TestFile @JvmOverloads constructor(
|
||||
@JvmField val name: String,
|
||||
@JvmField val content: String,
|
||||
@JvmField val directives: Map<String, String?> = emptyMap()
|
||||
) : Comparable<TestFile> {
|
||||
override operator fun compareTo(other: TestFile): Int {
|
||||
return name.compareTo(other.name)
|
||||
}
|
||||
@@ -86,6 +90,12 @@ abstract class KotlinBaseTest<F : KotlinBaseTest.TestFile> : KtUsefulTestCase()
|
||||
override fun toString(): String {
|
||||
return name
|
||||
}
|
||||
|
||||
fun getListDirectiveIfPresent(name: String): List<String>? {
|
||||
return directives[name]?.let {
|
||||
InTextDirectivesUtils.splitValues(arrayListOf(), it)
|
||||
} ?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
open class TestModule(
|
||||
|
||||
@@ -98,6 +98,7 @@ public class KotlinTestUtils {
|
||||
private static final List<File> filesToDelete = new ArrayList<>();
|
||||
|
||||
static final Pattern DIRECTIVE_PATTERN = Pattern.compile("^//\\s*!([\\w_]+)(:\\s*(.*)$)?", Pattern.MULTILINE);
|
||||
static final Pattern BACKEND_DIRECTIVE_PATTERN = Pattern.compile("^//\\s*(FULL_JDK|JVM_TARGET|KOTLIN_CONFIGURATION_FLAGS|LANGUAGE_VERSION|COMMON_COROUTINES_TEST|COROUTINES_PACKAGE|WITH_RUNTIME|WITH_REFLECT|NO_CHECK_LAMBDA_INLINING|SKIP_INLINE_CHECK_IN)(:[ \\t]*(.*)$)?", Pattern.MULTILINE);
|
||||
|
||||
private KotlinTestUtils() {
|
||||
}
|
||||
@@ -526,16 +527,27 @@ public class KotlinTestUtils {
|
||||
@NotNull
|
||||
public static Map<String, String> parseDirectives(String expectedText) {
|
||||
Map<String, String> directives = new HashMap<>();
|
||||
Matcher directiveMatcher = DIRECTIVE_PATTERN.matcher(expectedText);
|
||||
return parseByRegexp(DIRECTIVE_PATTERN, expectedText, directives);
|
||||
}
|
||||
|
||||
private static Map<String, String> parseByRegexp(Pattern pattern, String expectedText, Map<String, String> directives) {
|
||||
Matcher directiveMatcher = pattern.matcher(expectedText);
|
||||
while (directiveMatcher.find()) {
|
||||
String name = directiveMatcher.group(1);
|
||||
String value = directiveMatcher.group(3);
|
||||
String oldValue = directives.put(name, value);
|
||||
Assert.assertNull("Directive overwritten: " + name + " old value: " + oldValue + " new value: " + value, oldValue);
|
||||
Assert.assertNull("Directive or flag overwritten: " + name + " old value: " + oldValue + " new value: " + value, oldValue);
|
||||
}
|
||||
return directives;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<String, String> parseDirectivesAndFlags(String expectedText) {
|
||||
Map<String, String> directiveAndFlags = parseDirectives(expectedText);
|
||||
parseByRegexp(BACKEND_DIRECTIVE_PATTERN, expectedText, directiveAndFlags);
|
||||
return directiveAndFlags;
|
||||
}
|
||||
|
||||
public static List<String> loadBeforeAfterText(String filePath) {
|
||||
String content;
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jetbrains.kotlin.test.InTextDirectivesUtils.isDirectiveDefined;
|
||||
import static org.jetbrains.kotlin.test.KotlinTestUtils.parseDirectives;
|
||||
import static org.jetbrains.kotlin.test.KotlinTestUtils.parseDirectivesAndFlags;
|
||||
|
||||
public class TestFiles {
|
||||
/**
|
||||
@@ -51,19 +53,30 @@ public class TestFiles {
|
||||
@NotNull
|
||||
public static <M extends KotlinBaseTest.TestModule, F> List<F> createTestFiles(String testFileName, String expectedText, TestFileFactory<M , F> factory,
|
||||
boolean preserveLocations, String coroutinesPackage) {
|
||||
Map<String, String> directives = KotlinTestUtils.parseDirectives(expectedText);
|
||||
return createTestFiles(testFileName, expectedText, factory, preserveLocations, coroutinesPackage, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <M extends KotlinBaseTest.TestModule, F> List<F> createTestFiles(String testFileName, String expectedText, TestFileFactory<M , F> factory,
|
||||
boolean preserveLocations, String coroutinesPackage, boolean parseDirectivesPerFile) {
|
||||
Map<String, M> modules = new HashMap<>();
|
||||
List<F> testFiles = Lists.newArrayList();
|
||||
Matcher matcher = FILE_OR_MODULE_PATTERN.matcher(expectedText);
|
||||
boolean hasModules = false;
|
||||
String commonPrefixOrWholeFile;
|
||||
if (!matcher.find()) {
|
||||
assert testFileName != null : "testFileName should not be null if no FILE directive defined";
|
||||
// One file
|
||||
testFiles.add(factory.createFile(null, testFileName, expectedText, directives));
|
||||
testFiles.add(factory.createFile(null, testFileName, expectedText, parseDirectivesAndFlags(expectedText)));
|
||||
commonPrefixOrWholeFile = expectedText;
|
||||
}
|
||||
else {
|
||||
Map<String, String> allFilesOrCommonPrefixDirectives = parseDirectivesPerFile ? null : parseDirectivesAndFlags(expectedText);
|
||||
int processedChars = 0;
|
||||
M module = null;
|
||||
boolean firstFileProcessed = false;
|
||||
commonPrefixOrWholeFile = expectedText.substring(0, matcher.start());
|
||||
|
||||
// Many files
|
||||
while (true) {
|
||||
String moduleName = matcher.group(1);
|
||||
@@ -91,10 +104,14 @@ public class TestFiles {
|
||||
String fileText = preserveLocations ?
|
||||
substringKeepingLocations(expectedText, start, end) :
|
||||
expectedText.substring(start,end);
|
||||
|
||||
|
||||
testFiles.add(factory.createFile(module, fileName, fileText,
|
||||
parseDirectivesPerFile ?
|
||||
parseDirectivesAndFlags(firstFileProcessed ? commonPrefixOrWholeFile + fileText : fileText)
|
||||
: allFilesOrCommonPrefixDirectives));
|
||||
processedChars = end;
|
||||
|
||||
testFiles.add(factory.createFile(module, fileName, fileText, directives));
|
||||
|
||||
firstFileProcessed = true;
|
||||
if (!nextFileExists) break;
|
||||
}
|
||||
assert processedChars == expectedText.length() : "Characters skipped from " +
|
||||
@@ -123,7 +140,7 @@ public class TestFiles {
|
||||
"CoroutineUtil.kt",
|
||||
TestHelperGeneratorKt.createTextForCoroutineHelpers(
|
||||
isReleaseCoroutines, checkStateMachine, checkTailCallOptimization),
|
||||
directives
|
||||
parseDirectives(commonPrefixOrWholeFile)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.visualizer
|
||||
|
||||
import org.jetbrains.kotlin.test.KotlinBaseTest
|
||||
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import org.jetbrains.kotlin.test.KotlinBaseTest
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractVisualizer : KotlinMultiFileTestWithJava<KotlinBaseTest.TestModule, KotlinBaseTest.TestFile>() {
|
||||
@@ -22,8 +20,8 @@ abstract class AbstractVisualizer : KotlinMultiFileTestWithJava<KotlinBaseTest.T
|
||||
): TestModule? = null
|
||||
|
||||
|
||||
override fun createTestFile(module: TestModule?, fileName: String, text: String, directives: Map<String, String>): TestFile =
|
||||
TestFile(fileName, text)
|
||||
override fun createTestFile(module: TestModule?, fileName: String, text: String, directives: Map<String, String?>): TestFile =
|
||||
TestFile(fileName, text, directives)
|
||||
|
||||
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
||||
|
||||
+2
-2
@@ -129,8 +129,8 @@ abstract class KotlinDescriptorTestCase : DescriptorTestCase() {
|
||||
wholeFile.name,
|
||||
wholeFileContents,
|
||||
object : org.jetbrains.kotlin.test.TestFiles.TestFileFactoryNoModules<TestFile>() {
|
||||
override fun create(fileName: String, text: String, directives: Map<String, String>): TestFile {
|
||||
return TestFile(fileName, text)
|
||||
override fun create(fileName: String, text: String, directives: Map<String, String?>): TestFile {
|
||||
return TestFile(fileName, text, directives)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -147,7 +147,7 @@ abstract class AbstractJsLineNumberTest : KotlinTestWithEnvironment() {
|
||||
KotlinTestUtils.mkdirs(temporaryFile.parentFile)
|
||||
temporaryFile.writeText(text, Charsets.UTF_8)
|
||||
|
||||
return TestFile(temporaryFile.absolutePath, text, currentModule)
|
||||
return TestFile(temporaryFile.absolutePath, text, currentModule, directives)
|
||||
}
|
||||
|
||||
override fun createModule(name: String, dependencies: List<String>, friends: List<String>) = TestModule(name, dependencies, friends)
|
||||
@@ -165,7 +165,8 @@ abstract class AbstractJsLineNumberTest : KotlinTestWithEnvironment() {
|
||||
val files = mutableListOf<TestFile>()
|
||||
}
|
||||
|
||||
private class TestFile(val fileName: String, content: String, val module: TestModule) : KotlinBaseTest.TestFile(fileName, content) {
|
||||
private class TestFile(val fileName: String, content: String, val module: TestModule, directives: Map<String, String?>) :
|
||||
KotlinBaseTest.TestFile(fileName, content, directives) {
|
||||
init {
|
||||
module.files += this
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user