[Test] Migrate AbstractBytecodeTextTest to new test infrastructure
This commit is contained in:
+1044
-496
File diff suppressed because it is too large
Load Diff
+144
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
|
import org.jetbrains.kotlin.test.Assertions
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
|
import java.io.File
|
||||||
|
import java.util.ArrayList
|
||||||
|
import java.util.regex.Matcher
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
|
private val AT_OUTPUT_FILE_PATTERN = Pattern.compile("^\\s*//\\s*@(.*):$")
|
||||||
|
private val EXPECTED_OCCURRENCES_PATTERN = Pattern.compile("^\\s*//\\s*(\\d+)\\s*(.*)$")
|
||||||
|
private const val JVM_TEMPLATES = "// JVM_TEMPLATES"
|
||||||
|
private const val JVM_IR_TEMPLATES = "// JVM_IR_TEMPLATES"
|
||||||
|
|
||||||
|
class OccurrenceInfo constructor(private val numberOfOccurrences: Int, private val needle: String, val backend: TargetBackend) {
|
||||||
|
private val pattern = Pattern.compile("($needle)")
|
||||||
|
|
||||||
|
fun getActualOccurrence(text: String): String {
|
||||||
|
val actualCount = StringUtil.findMatches(text, pattern).size
|
||||||
|
return "$actualCount $needle"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "$numberOfOccurrences $needle"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readExpectedOccurrences(filename: String): List<OccurrenceInfo> {
|
||||||
|
val lines = File(filename).readLines().dropLastWhile(String::isEmpty)
|
||||||
|
return readExpectedOccurrences(lines)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readExpectedOccurrences(lines: List<String>): List<OccurrenceInfo> {
|
||||||
|
val result = ArrayList<OccurrenceInfo>()
|
||||||
|
var backend = TargetBackend.ANY
|
||||||
|
for (line in lines) {
|
||||||
|
if (line.contains(JVM_TEMPLATES)) backend = TargetBackend.JVM
|
||||||
|
else if (line.contains(JVM_IR_TEMPLATES)) backend = TargetBackend.JVM_IR
|
||||||
|
|
||||||
|
val matcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line)
|
||||||
|
if (matcher.matches()) {
|
||||||
|
result.add(parseOccurrenceInfo(matcher, backend))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readExpectedOccurrencesForMultiFileTest(
|
||||||
|
fileName: String,
|
||||||
|
fileContent: String,
|
||||||
|
destination: MutableMap<String, List<OccurrenceInfo>>
|
||||||
|
) {
|
||||||
|
var currentOccurrenceInfos: MutableList<OccurrenceInfo>? = null
|
||||||
|
var backend = TargetBackend.ANY
|
||||||
|
for (line in fileContent.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
|
||||||
|
if (line.contains(JVM_TEMPLATES)) backend = TargetBackend.JVM
|
||||||
|
else if (line.contains(JVM_IR_TEMPLATES)) backend = TargetBackend.JVM_IR
|
||||||
|
|
||||||
|
val atOutputFileMatcher = AT_OUTPUT_FILE_PATTERN.matcher(line)
|
||||||
|
if (atOutputFileMatcher.matches()) {
|
||||||
|
val outputFileName = atOutputFileMatcher.group(1)
|
||||||
|
if (destination.containsKey(outputFileName)) {
|
||||||
|
throw AssertionError("${fileName}: Expected occurrences for output file $outputFileName were already provided")
|
||||||
|
}
|
||||||
|
currentOccurrenceInfos = ArrayList()
|
||||||
|
destination[outputFileName] = currentOccurrenceInfos
|
||||||
|
}
|
||||||
|
|
||||||
|
val expectedOccurrencesMatcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line)
|
||||||
|
if (expectedOccurrencesMatcher.matches()) {
|
||||||
|
if (currentOccurrenceInfos == null) {
|
||||||
|
throw AssertionError("${fileName}: Should specify output file with '// @<OUTPUT_FILE_NAME>:' before expectations")
|
||||||
|
}
|
||||||
|
val occurrenceInfo = parseOccurrenceInfo(expectedOccurrencesMatcher, backend)
|
||||||
|
currentOccurrenceInfos.add(occurrenceInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseOccurrenceInfo(matcher: Matcher, backend: TargetBackend): OccurrenceInfo {
|
||||||
|
val numberOfOccurrences = Integer.parseInt(matcher.group(1))
|
||||||
|
val needle = matcher.group(2)
|
||||||
|
return OccurrenceInfo(numberOfOccurrences, needle, backend)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkGeneratedTextAgainstExpectedOccurrences(
|
||||||
|
text: String,
|
||||||
|
expectedOccurrences: List<OccurrenceInfo>,
|
||||||
|
currentBackend: TargetBackend,
|
||||||
|
reportProblems: Boolean,
|
||||||
|
assertions: Assertions
|
||||||
|
) {
|
||||||
|
val expected = StringBuilder()
|
||||||
|
val actual = StringBuilder()
|
||||||
|
var lastBackend = TargetBackend.ANY
|
||||||
|
for (info in expectedOccurrences) {
|
||||||
|
if (lastBackend != info.backend) {
|
||||||
|
when (info.backend) {
|
||||||
|
TargetBackend.JVM -> JVM_TEMPLATES
|
||||||
|
TargetBackend.JVM_IR -> JVM_IR_TEMPLATES
|
||||||
|
else -> error("Common part should be first one: ${expectedOccurrences.joinToString("\n")}")
|
||||||
|
}.also {
|
||||||
|
actual.append("\n$it\n")
|
||||||
|
expected.append("\n$it\n")
|
||||||
|
}
|
||||||
|
lastBackend = info.backend
|
||||||
|
}
|
||||||
|
|
||||||
|
expected.append(info).append("\n")
|
||||||
|
if (info.backend == TargetBackend.ANY || info.backend == currentBackend) {
|
||||||
|
actual.append(info.getActualOccurrence(text)).append("\n")
|
||||||
|
} else {
|
||||||
|
actual.append(info).append("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertions.assertEquals(expected.toString(), actual.toString()) { text }
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (reportProblems) {
|
||||||
|
println(text)
|
||||||
|
}
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun assertTextWasGenerated(expectedOutputFile: String, generated: Map<String, String>, assertions: Assertions) {
|
||||||
|
if (!generated.containsKey(expectedOutputFile)) {
|
||||||
|
val failMessage = StringBuilder()
|
||||||
|
failMessage.append("Missing output file ").append(expectedOutputFile).append(", got ").append(generated.size).append(": ")
|
||||||
|
for (generatedFile in generated.keys) {
|
||||||
|
failMessage.append(generatedFile).append(" ")
|
||||||
|
}
|
||||||
|
assertions.fail { failMessage.toString() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -7,6 +7,6 @@ class A {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 public final g\$test_module\(Lkotlin/coroutines/Continuation;\)Ljava/lang/Object;
|
// 1 public final g\$main\(Lkotlin/coroutines/Continuation;\)Ljava/lang/Object;
|
||||||
// 1 private final g\$test_module\$\$forInline\(Lkotlin/coroutines/Continuation;\)Ljava/lang/Object;
|
// 1 private final g\$main\$\$forInline\(Lkotlin/coroutines/Continuation;\)Ljava/lang/Object;
|
||||||
// 0 g\$\$forInline
|
// 0 g\$\$forInline
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
// FILE: JClass.java
|
// FILE: JClass.java
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class JClass {
|
public class JClass {
|
||||||
public final static int PrimitiveInt = 9000;
|
public final static int PrimitiveInt = 9000;
|
||||||
@@ -8,7 +9,7 @@ public class JClass {
|
|||||||
public final static long PrimitiveLong = 100000;
|
public final static long PrimitiveLong = 100000;
|
||||||
public final static short PrimitiveShort = 901;
|
public final static short PrimitiveShort = 901;
|
||||||
public final static boolean PrimitiveBool = false;
|
public final static boolean PrimitiveBool = false;
|
||||||
public final static float PrimitiveFloat = 36.6;
|
public final static float PrimitiveFloat = 36.6f;
|
||||||
public final static double PrimitiveDouble = 42.4242;
|
public final static double PrimitiveDouble = 42.4242;
|
||||||
public final static byte PrimitiveByte = -8;
|
public final static byte PrimitiveByte = -8;
|
||||||
public final static char PrimitiveChar = 'K';
|
public final static char PrimitiveChar = 'K';
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ fun box(): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check the names of mangled functions
|
// Check the names of mangled functions
|
||||||
// 1 public final f\$test_module\(\)Ljava/lang/String;
|
// 1 public final f\$main\(\)Ljava/lang/String;
|
||||||
// 1 public final static f\$test_module\(\)Ljava/lang/String;
|
// 1 public final static f\$main\(\)Ljava/lang/String;
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM
|
|
||||||
fun main() {
|
fun main() {
|
||||||
println("FAIL")
|
println("FAIL")
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
// FILE: JClass.java
|
// FILE: JClass.java
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class JClass {
|
public class JClass {
|
||||||
public final static int PrimitiveInt = 9000;
|
public final static int PrimitiveInt = 9000;
|
||||||
@@ -8,7 +9,7 @@ public class JClass {
|
|||||||
public final static long PrimitiveLong = 100000;
|
public final static long PrimitiveLong = 100000;
|
||||||
public final static short PrimitiveShort = 901;
|
public final static short PrimitiveShort = 901;
|
||||||
public final static boolean PrimitiveBool = false;
|
public final static boolean PrimitiveBool = false;
|
||||||
public final static float PrimitiveFloat = 36.6;
|
public final static float PrimitiveFloat = 36.6f;
|
||||||
public final static double PrimitiveDouble = 42.4242;
|
public final static double PrimitiveDouble = 42.4242;
|
||||||
public final static byte PrimitiveByte = -8;
|
public final static byte PrimitiveByte = -8;
|
||||||
public final static char PrimitiveChar = 'K';
|
public final static char PrimitiveChar = 'K';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
public class J {
|
public class J {
|
||||||
public interface F {
|
public interface F {
|
||||||
public int call(String x)
|
public int call(String x);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void g(F r) {
|
public static void g(F r) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=indy-with-constants
|
// KOTLIN_CONFIGURATION_FLAGS: STRING_CONCAT=indy-with-constants
|
||||||
|
// IGNORE_JAVA_ERRORS
|
||||||
// JVM_TARGET: 9
|
// JVM_TARGET: 9
|
||||||
// FILE: JavaClass.java
|
// FILE: JavaClass.java
|
||||||
|
|
||||||
|
|||||||
+1041
-514
File diff suppressed because it is too large
Load Diff
+1044
-496
File diff suppressed because it is too large
Load Diff
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.test.backend.handlers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.codegen.*
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
||||||
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.TREAT_AS_ONE_FILE
|
||||||
|
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||||
|
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
||||||
|
import org.jetbrains.kotlin.test.model.TestFile
|
||||||
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
|
import org.jetbrains.kotlin.test.services.isKtFile
|
||||||
|
import java.util.LinkedHashMap
|
||||||
|
|
||||||
|
class BytecodeTextHandler(testServices: TestServices) : JvmBinaryArtifactHandler(testServices) {
|
||||||
|
companion object {
|
||||||
|
private const val IGNORED_PREFIX = "helpers/"
|
||||||
|
}
|
||||||
|
|
||||||
|
override val directivesContainers: List<DirectivesContainer>
|
||||||
|
get() = listOf(CodegenTestDirectives)
|
||||||
|
|
||||||
|
override fun processModule(module: TestModule, info: BinaryArtifacts.Jvm) {
|
||||||
|
val targetBackend = module.targetBackend!!
|
||||||
|
val isIgnored = targetBackend in module.directives[CodegenTestDirectives.IGNORE_BACKEND]
|
||||||
|
val files = module.files.filter { it.isKtFile }
|
||||||
|
if (files.size > 1 && TREAT_AS_ONE_FILE !in module.directives) {
|
||||||
|
processMultiFileTest(files, info, targetBackend, !isIgnored)
|
||||||
|
} else {
|
||||||
|
val file = files.first { !it.isAdditional }
|
||||||
|
val expected = readExpectedOccurrences(file.originalContent.split("\n"))
|
||||||
|
val actual = info.classFileFactory.createText(IGNORED_PREFIX)
|
||||||
|
checkGeneratedTextAgainstExpectedOccurrences(actual, expected, targetBackend, !isIgnored, assertions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processMultiFileTest(
|
||||||
|
files: List<TestFile>,
|
||||||
|
info: BinaryArtifacts.Jvm,
|
||||||
|
targetBackend: TargetBackend,
|
||||||
|
reportProblems: Boolean
|
||||||
|
) {
|
||||||
|
val expectedOccurrencesByOutputFile = LinkedHashMap<String, List<OccurrenceInfo>>()
|
||||||
|
for (file in files) {
|
||||||
|
readExpectedOccurrencesForMultiFileTest(file.name, file.originalContent, expectedOccurrencesByOutputFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
val generated = info.classFileFactory.createTextForEachFile()
|
||||||
|
for (expectedOutputFile in expectedOccurrencesByOutputFile.keys) {
|
||||||
|
assertTextWasGenerated(expectedOutputFile, generated, assertions)
|
||||||
|
val generatedText = generated[expectedOutputFile]!!
|
||||||
|
val expectedOccurrences = expectedOccurrencesByOutputFile[expectedOutputFile]!!
|
||||||
|
checkGeneratedTextAgainstExpectedOccurrences(generatedText, expectedOccurrences, targetBackend, reportProblems, assertions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
||||||
|
}
|
||||||
+5
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.test.directives
|
package org.jetbrains.kotlin.test.directives
|
||||||
|
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
|
import org.jetbrains.kotlin.test.backend.handlers.BytecodeTextHandler
|
||||||
import org.jetbrains.kotlin.test.backend.handlers.IrPrettyKotlinDumpHandler
|
import org.jetbrains.kotlin.test.backend.handlers.IrPrettyKotlinDumpHandler
|
||||||
import org.jetbrains.kotlin.test.backend.handlers.IrTextDumpHandler
|
import org.jetbrains.kotlin.test.backend.handlers.IrTextDumpHandler
|
||||||
import org.jetbrains.kotlin.test.backend.handlers.NoCompilationErrorsHandler
|
import org.jetbrains.kotlin.test.backend.handlers.NoCompilationErrorsHandler
|
||||||
@@ -85,4 +86,8 @@ object CodegenTestDirectives : SimpleDirectivesContainer() {
|
|||||||
val SKIP_KT_DUMP by directive(
|
val SKIP_KT_DUMP by directive(
|
||||||
description = "Skips check pretty kt IR dump (disables ${IrPrettyKotlinDumpHandler::class})"
|
description = "Skips check pretty kt IR dump (disables ${IrPrettyKotlinDumpHandler::class})"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val TREAT_AS_ONE_FILE by directive(
|
||||||
|
description = "Treat bytecode from all files as one in ${BytecodeTextHandler::class}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+101
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.test.runners.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.test.Constructor
|
||||||
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
|
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
|
||||||
|
import org.jetbrains.kotlin.test.backend.classic.ClassicJvmBackendFacade
|
||||||
|
import org.jetbrains.kotlin.test.backend.handlers.BytecodeTextHandler
|
||||||
|
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
|
||||||
|
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||||
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
|
||||||
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_PSI_CLASS_FILES_READING
|
||||||
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_REFLECT
|
||||||
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.WITH_STDLIB
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2ClassicBackendConverter
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
|
||||||
|
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
|
||||||
|
import org.jetbrains.kotlin.test.model.*
|
||||||
|
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
|
||||||
|
|
||||||
|
abstract class AbstractBytecodeTextTestBase<R : ResultingArtifact.FrontendOutput<R>>(
|
||||||
|
targetBackend: TargetBackend,
|
||||||
|
val targetFrontend: FrontendKind<*>
|
||||||
|
) : AbstractKotlinCompilerWithTargetBackendTest(targetBackend) {
|
||||||
|
abstract val frontendFacade: Constructor<FrontendFacade<R>>
|
||||||
|
abstract val frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>>
|
||||||
|
abstract val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
|
||||||
|
|
||||||
|
override fun TestConfigurationBuilder.configuration() {
|
||||||
|
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
|
||||||
|
|
||||||
|
defaultDirectives {
|
||||||
|
+WITH_STDLIB
|
||||||
|
+WITH_REFLECT
|
||||||
|
}
|
||||||
|
|
||||||
|
useArtifactsHandlers(::BytecodeTextHandler)
|
||||||
|
|
||||||
|
useAfterAnalysisCheckers(::BlackBoxCodegenSuppressor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class AbstractBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact>(
|
||||||
|
targetBackend = TargetBackend.JVM,
|
||||||
|
targetFrontend = FrontendKinds.ClassicFrontend
|
||||||
|
) {
|
||||||
|
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
|
||||||
|
get() = ::ClassicFrontendFacade
|
||||||
|
|
||||||
|
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>>
|
||||||
|
get() = ::ClassicFrontend2ClassicBackendConverter
|
||||||
|
|
||||||
|
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
|
||||||
|
get() = ::ClassicJvmBackendFacade
|
||||||
|
}
|
||||||
|
|
||||||
|
open class AbstractIrBytecodeTextTest : AbstractBytecodeTextTestBase<ClassicFrontendOutputArtifact>(
|
||||||
|
targetBackend = TargetBackend.JVM_IR,
|
||||||
|
targetFrontend = FrontendKinds.ClassicFrontend
|
||||||
|
) {
|
||||||
|
override val frontendFacade: Constructor<FrontendFacade<ClassicFrontendOutputArtifact>>
|
||||||
|
get() = ::ClassicFrontendFacade
|
||||||
|
|
||||||
|
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<ClassicFrontendOutputArtifact, *>>
|
||||||
|
get() = ::ClassicFrontend2IrConverter
|
||||||
|
|
||||||
|
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
|
||||||
|
get() = ::JvmIrBackendFacade
|
||||||
|
}
|
||||||
|
|
||||||
|
open class AbstractFirBytecodeTextTest : AbstractBytecodeTextTestBase<FirOutputArtifact>(
|
||||||
|
targetBackend = TargetBackend.JVM_IR,
|
||||||
|
targetFrontend = FrontendKinds.FIR
|
||||||
|
) {
|
||||||
|
override val frontendFacade: Constructor<FrontendFacade<FirOutputArtifact>>
|
||||||
|
get() = ::FirFrontendFacade
|
||||||
|
|
||||||
|
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, *>>
|
||||||
|
get() = ::Fir2IrResultsConverter
|
||||||
|
|
||||||
|
override val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
|
||||||
|
get() = ::JvmIrBackendFacade
|
||||||
|
|
||||||
|
override fun configure(builder: TestConfigurationBuilder) {
|
||||||
|
super.configure(builder)
|
||||||
|
with(builder) {
|
||||||
|
defaultDirectives {
|
||||||
|
// See KT-44152
|
||||||
|
-USE_PSI_CLASS_FILES_READING
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-33
@@ -5,21 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.test.runners.codegen
|
package org.jetbrains.kotlin.test.runners.codegen
|
||||||
|
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
|
||||||
import org.jetbrains.kotlin.test.Constructor
|
import org.jetbrains.kotlin.test.Constructor
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
|
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
|
||||||
import org.jetbrains.kotlin.test.backend.handlers.*
|
import org.jetbrains.kotlin.test.backend.handlers.*
|
||||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.RUN_DEX_CHECKER
|
|
||||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_PSI_CLASS_FILES_READING
|
|
||||||
import org.jetbrains.kotlin.test.model.*
|
import org.jetbrains.kotlin.test.model.*
|
||||||
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
|
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
|
||||||
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
|
|
||||||
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
|
|
||||||
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
|
|
||||||
import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFilesProvider
|
|
||||||
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
|
|
||||||
|
|
||||||
abstract class AbstractJvmBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendOutput<R>>(
|
abstract class AbstractJvmBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendOutput<R>>(
|
||||||
val targetFrontend: FrontendKind<R>,
|
val targetFrontend: FrontendKind<R>,
|
||||||
@@ -30,31 +22,7 @@ abstract class AbstractJvmBlackBoxCodegenTestBase<R : ResultingArtifact.Frontend
|
|||||||
abstract val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
|
abstract val backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
|
||||||
|
|
||||||
override fun TestConfigurationBuilder.configuration() {
|
override fun TestConfigurationBuilder.configuration() {
|
||||||
globalDefaults {
|
commonConfigurationForCodegenTest(targetFrontend, frontendFacade, frontendToBackendConverter, backendFacade)
|
||||||
frontend = targetFrontend
|
|
||||||
targetPlatform = JvmPlatforms.defaultJvmPlatform
|
|
||||||
dependencyKind = DependencyKind.Binary
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultDirectives {
|
|
||||||
+USE_PSI_CLASS_FILES_READING
|
|
||||||
+RUN_DEX_CHECKER
|
|
||||||
}
|
|
||||||
|
|
||||||
useConfigurators(
|
|
||||||
::CommonEnvironmentConfigurator,
|
|
||||||
::JvmEnvironmentConfigurator
|
|
||||||
)
|
|
||||||
|
|
||||||
useAdditionalSourceProviders(
|
|
||||||
::AdditionalDiagnosticsSourceFilesProvider,
|
|
||||||
::CoroutineHelpersSourceFilesProvider,
|
|
||||||
::CodegenHelpersSourceFilesProvider,
|
|
||||||
)
|
|
||||||
|
|
||||||
useFrontendFacades(frontendFacade)
|
|
||||||
useFrontend2BackendConverters(frontendToBackendConverter)
|
|
||||||
useBackendFacades(backendFacade)
|
|
||||||
|
|
||||||
useFrontendHandlers(
|
useFrontendHandlers(
|
||||||
::NoCompilationErrorsHandler,
|
::NoCompilationErrorsHandler,
|
||||||
|
|||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.test.runners.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
|
import org.jetbrains.kotlin.test.Constructor
|
||||||
|
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||||
|
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.RUN_DEX_CHECKER
|
||||||
|
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_PSI_CLASS_FILES_READING
|
||||||
|
import org.jetbrains.kotlin.test.model.*
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
|
||||||
|
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
|
||||||
|
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
|
||||||
|
import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFilesProvider
|
||||||
|
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
|
||||||
|
|
||||||
|
fun <R : ResultingArtifact.FrontendOutput<R>> TestConfigurationBuilder.commonConfigurationForCodegenTest(
|
||||||
|
targetFrontend: FrontendKind<*>,
|
||||||
|
frontendFacade: Constructor<FrontendFacade<R>>,
|
||||||
|
frontendToBackendConverter: Constructor<Frontend2BackendConverter<R, *>>,
|
||||||
|
backendFacade: Constructor<BackendFacade<*, BinaryArtifacts.Jvm>>
|
||||||
|
) {
|
||||||
|
globalDefaults {
|
||||||
|
frontend = targetFrontend
|
||||||
|
targetPlatform = JvmPlatforms.defaultJvmPlatform
|
||||||
|
dependencyKind = DependencyKind.Binary
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultDirectives {
|
||||||
|
+USE_PSI_CLASS_FILES_READING
|
||||||
|
+RUN_DEX_CHECKER
|
||||||
|
}
|
||||||
|
|
||||||
|
useConfigurators(
|
||||||
|
::CommonEnvironmentConfigurator,
|
||||||
|
::JvmEnvironmentConfigurator
|
||||||
|
)
|
||||||
|
|
||||||
|
useAdditionalSourceProviders(
|
||||||
|
::AdditionalDiagnosticsSourceFilesProvider,
|
||||||
|
::CoroutineHelpersSourceFilesProvider,
|
||||||
|
::CodegenHelpersSourceFilesProvider,
|
||||||
|
)
|
||||||
|
|
||||||
|
useFrontendFacades(frontendFacade)
|
||||||
|
useFrontend2BackendConverters(frontendToBackendConverter)
|
||||||
|
useBackendFacades(backendFacade)
|
||||||
|
}
|
||||||
+7
-130
@@ -5,16 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.util.JUnit4Assertions
|
||||||
import org.junit.Assert
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.regex.Matcher
|
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
|
@ObsoleteTestInfrastructure
|
||||||
abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
||||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
|
||||||
val isIgnored = InTextDirectivesUtils.isIgnoredTarget(backend, wholeFile)
|
val isIgnored = InTextDirectivesUtils.isIgnoredTarget(backend, wholeFile)
|
||||||
@@ -31,57 +29,26 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
|||||||
} else {
|
} else {
|
||||||
val expected = readExpectedOccurrences(wholeFile.path)
|
val expected = readExpectedOccurrences(wholeFile.path)
|
||||||
val actual = generateToText("helpers/")
|
val actual = generateToText("helpers/")
|
||||||
checkGeneratedTextAgainstExpectedOccurrences(actual, expected, backend, !isIgnored)
|
checkGeneratedTextAgainstExpectedOccurrences(actual, expected, backend, !isIgnored, JUnit4Assertions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doTestMultiFile(files: List<TestFile>, reportProblems: Boolean) {
|
private fun doTestMultiFile(files: List<TestFile>, reportProblems: Boolean) {
|
||||||
val expectedOccurrencesByOutputFile = LinkedHashMap<String, List<OccurrenceInfo>>()
|
val expectedOccurrencesByOutputFile = LinkedHashMap<String, List<OccurrenceInfo>>()
|
||||||
for (file in files) {
|
for (file in files) {
|
||||||
readExpectedOccurrencesForMultiFileTest(file, expectedOccurrencesByOutputFile)
|
readExpectedOccurrencesForMultiFileTest(file.name, file.content, expectedOccurrencesByOutputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
val generated = generateEachFileToText()
|
val generated = generateEachFileToText()
|
||||||
for (expectedOutputFile in expectedOccurrencesByOutputFile.keys) {
|
for (expectedOutputFile in expectedOccurrencesByOutputFile.keys) {
|
||||||
assertTextWasGenerated(expectedOutputFile, generated)
|
assertTextWasGenerated(expectedOutputFile, generated, JUnit4Assertions)
|
||||||
val generatedText = generated[expectedOutputFile]!!
|
val generatedText = generated[expectedOutputFile]!!
|
||||||
val expectedOccurrences = expectedOccurrencesByOutputFile[expectedOutputFile]!!
|
val expectedOccurrences = expectedOccurrencesByOutputFile[expectedOutputFile]!!
|
||||||
checkGeneratedTextAgainstExpectedOccurrences(generatedText, expectedOccurrences, backend, reportProblems)
|
checkGeneratedTextAgainstExpectedOccurrences(generatedText, expectedOccurrences, backend, reportProblems, JUnit4Assertions)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun readExpectedOccurrences(filename: String): List<OccurrenceInfo> {
|
|
||||||
val result = ArrayList<OccurrenceInfo>()
|
|
||||||
val lines = File(filename).readLines().dropLastWhile(String::isEmpty)
|
|
||||||
var backend = TargetBackend.ANY
|
|
||||||
for (line in lines) {
|
|
||||||
if (line.contains(JVM_TEMPLATES)) backend = TargetBackend.JVM
|
|
||||||
else if (line.contains(JVM_IR_TEMPLATES)) backend = TargetBackend.JVM_IR
|
|
||||||
|
|
||||||
val matcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line)
|
|
||||||
if (matcher.matches()) {
|
|
||||||
result.add(parseOccurrenceInfo(matcher, backend))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
class OccurrenceInfo constructor(private val numberOfOccurrences: Int, private val needle: String, val backend: TargetBackend) {
|
|
||||||
fun getActualOccurrence(text: String): String? {
|
|
||||||
val actualCount = StringUtil.findMatches(text, Pattern.compile("($needle)")).size
|
|
||||||
return "$actualCount $needle"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {
|
|
||||||
return "$numberOfOccurrences $needle"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val AT_OUTPUT_FILE_PATTERN = Pattern.compile("^\\s*//\\s*@(.*):$")
|
|
||||||
private val EXPECTED_OCCURRENCES_PATTERN = Pattern.compile("^\\s*//\\s*(\\d+)\\s*(.*)$")
|
|
||||||
|
|
||||||
private fun isMultiFileTest(files: List<TestFile>): Boolean {
|
private fun isMultiFileTest(files: List<TestFile>): Boolean {
|
||||||
var kotlinFiles = 0
|
var kotlinFiles = 0
|
||||||
for (file in files) {
|
for (file in files) {
|
||||||
@@ -91,95 +58,5 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
|||||||
}
|
}
|
||||||
return kotlinFiles > 1
|
return kotlinFiles > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkGeneratedTextAgainstExpectedOccurrences(
|
|
||||||
text: String,
|
|
||||||
expectedOccurrences: List<OccurrenceInfo>,
|
|
||||||
currentBackend: TargetBackend,
|
|
||||||
reportProblems: Boolean
|
|
||||||
) {
|
|
||||||
val expected = StringBuilder()
|
|
||||||
val actual = StringBuilder()
|
|
||||||
var lastBackend = TargetBackend.ANY
|
|
||||||
for (info in expectedOccurrences) {
|
|
||||||
if (lastBackend != info.backend) {
|
|
||||||
when (info.backend) {
|
|
||||||
TargetBackend.JVM -> JVM_TEMPLATES
|
|
||||||
TargetBackend.JVM_IR -> JVM_IR_TEMPLATES
|
|
||||||
else -> error("Common part should be first one: ${expectedOccurrences.joinToString("\n")}")
|
|
||||||
}.also {
|
|
||||||
actual.append("\n$it\n")
|
|
||||||
expected.append("\n$it\n")
|
|
||||||
}
|
|
||||||
lastBackend = info.backend
|
|
||||||
}
|
|
||||||
|
|
||||||
expected.append(info).append("\n")
|
|
||||||
if (info.backend == TargetBackend.ANY || info.backend == currentBackend) {
|
|
||||||
actual.append(info.getActualOccurrence(text)).append("\n")
|
|
||||||
} else {
|
|
||||||
actual.append(info).append("\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Assert.assertEquals(text, expected.toString(), actual.toString())
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
if (reportProblems) {
|
|
||||||
println(text)
|
|
||||||
}
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun assertTextWasGenerated(expectedOutputFile: String, generated: Map<String, String>) {
|
|
||||||
if (!generated.containsKey(expectedOutputFile)) {
|
|
||||||
val failMessage = StringBuilder()
|
|
||||||
failMessage.append("Missing output file ").append(expectedOutputFile).append(", got ").append(generated.size).append(": ")
|
|
||||||
for (generatedFile in generated.keys) {
|
|
||||||
failMessage.append(generatedFile).append(" ")
|
|
||||||
}
|
|
||||||
Assert.fail(failMessage.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private const val JVM_TEMPLATES = "// JVM_TEMPLATES"
|
|
||||||
|
|
||||||
private const val JVM_IR_TEMPLATES = "// JVM_IR_TEMPLATES"
|
|
||||||
|
|
||||||
private fun readExpectedOccurrencesForMultiFileTest(file: TestFile, occurrenceMap: MutableMap<String, List<OccurrenceInfo>>) {
|
|
||||||
var currentOccurrenceInfos: MutableList<OccurrenceInfo>? = null
|
|
||||||
var backend = TargetBackend.ANY
|
|
||||||
for (line in file.content.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
|
|
||||||
if (line.contains(JVM_TEMPLATES)) backend = TargetBackend.JVM
|
|
||||||
else if (line.contains(JVM_IR_TEMPLATES)) backend = TargetBackend.JVM_IR
|
|
||||||
|
|
||||||
val atOutputFileMatcher = AT_OUTPUT_FILE_PATTERN.matcher(line)
|
|
||||||
if (atOutputFileMatcher.matches()) {
|
|
||||||
val outputFileName = atOutputFileMatcher.group(1)
|
|
||||||
if (occurrenceMap.containsKey(outputFileName)) {
|
|
||||||
throw AssertionError("${file.name}: Expected occurrences for output file $outputFileName were already provided")
|
|
||||||
}
|
|
||||||
currentOccurrenceInfos = ArrayList()
|
|
||||||
occurrenceMap[outputFileName] = currentOccurrenceInfos
|
|
||||||
}
|
|
||||||
|
|
||||||
val expectedOccurrencesMatcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line)
|
|
||||||
if (expectedOccurrencesMatcher.matches()) {
|
|
||||||
if (currentOccurrenceInfos == null) {
|
|
||||||
throw AssertionError("${file.name}: Should specify output file with '// @<OUTPUT_FILE_NAME>:' before expectations")
|
|
||||||
}
|
|
||||||
val occurrenceInfo = parseOccurrenceInfo(expectedOccurrencesMatcher, backend)
|
|
||||||
currentOccurrenceInfos.add(occurrenceInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseOccurrenceInfo(matcher: Matcher, backend: TargetBackend): OccurrenceInfo {
|
|
||||||
val numberOfOccurrences = Integer.parseInt(matcher.group(1))
|
|
||||||
val needle = matcher.group(2)
|
|
||||||
return OccurrenceInfo(numberOfOccurrences, needle, backend)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -24,12 +24,16 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||||
import org.jetbrains.kotlin.test.*;
|
import org.jetbrains.kotlin.test.*;
|
||||||
|
import org.jetbrains.kotlin.test.util.JUnit4Assertions;
|
||||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.BytecodeTextUtilsKt.checkGeneratedTextAgainstExpectedOccurrences;
|
||||||
|
import static org.jetbrains.kotlin.codegen.BytecodeTextUtilsKt.readExpectedOccurrences;
|
||||||
|
|
||||||
public abstract class AbstractTopLevelMembersInvocationTest extends AbstractBytecodeTextTest {
|
public abstract class AbstractTopLevelMembersInvocationTest extends AbstractBytecodeTextTest {
|
||||||
@Override
|
@Override
|
||||||
public void doTest(@NotNull String filename) throws Exception {
|
public void doTest(@NotNull String filename) throws Exception {
|
||||||
@@ -60,6 +64,6 @@ public abstract class AbstractTopLevelMembersInvocationTest extends AbstractByte
|
|||||||
|
|
||||||
List<OccurrenceInfo> expected = readExpectedOccurrences(KtTestUtil.getTestDataPathBase() + "/codegen/" + sourceFiles.get(0));
|
List<OccurrenceInfo> expected = readExpectedOccurrences(KtTestUtil.getTestDataPathBase() + "/codegen/" + sourceFiles.get(0));
|
||||||
String actual = generateToText();
|
String actual = generateToText();
|
||||||
Companion.checkGeneratedTextAgainstExpectedOccurrences(actual, expected, TargetBackend.ANY, true);
|
checkGeneratedTextAgainstExpectedOccurrences(actual, expected, TargetBackend.ANY, true, JUnit4Assertions.INSTANCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.ir
|
package org.jetbrains.kotlin.codegen.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.codegen.AbstractBytecodeTextTest
|
import org.jetbrains.kotlin.codegen.AbstractBytecodeTextTest
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
|
|
||||||
|
@OptIn(ObsoleteTestInfrastructure::class)
|
||||||
abstract class AbstractComposeLikeIrBytecodeTextTest : AbstractBytecodeTextTest() {
|
abstract class AbstractComposeLikeIrBytecodeTextTest : AbstractBytecodeTextTest() {
|
||||||
override val backend = TargetBackend.JVM_IR
|
override val backend = TargetBackend.JVM_IR
|
||||||
|
|
||||||
|
|||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.ir
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
|
||||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
|
||||||
|
|
||||||
abstract class AbstractFirBytecodeTextTest : AbstractIrBytecodeTextTest() {
|
|
||||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
|
||||||
super.updateConfiguration(configuration)
|
|
||||||
configuration.put(CommonConfigurationKeys.USE_FIR, true)
|
|
||||||
configuration.put(JVMConfigurationKeys.IR, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.ir
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.AbstractBytecodeTextTest
|
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
|
||||||
|
|
||||||
abstract class AbstractIrBytecodeTextTest : AbstractBytecodeTextTest() {
|
|
||||||
override val backend = TargetBackend.JVM_IR
|
|
||||||
}
|
|
||||||
+13
-8
@@ -32,14 +32,19 @@ fun compileJavaFiles(
|
|||||||
val diagnosticCollector = DiagnosticCollector<JavaFileObject>()
|
val diagnosticCollector = DiagnosticCollector<JavaFileObject>()
|
||||||
javaCompiler.getStandardFileManager(diagnosticCollector, Locale.ENGLISH, Charset.forName("utf-8")).use { fileManager ->
|
javaCompiler.getStandardFileManager(diagnosticCollector, Locale.ENGLISH, Charset.forName("utf-8")).use { fileManager ->
|
||||||
val javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(files)
|
val javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(files)
|
||||||
val task = javaCompiler.getTask(
|
val task = try {
|
||||||
StringWriter(), // do not write to System.err
|
javaCompiler.getTask(
|
||||||
fileManager,
|
StringWriter(), // do not write to System.err
|
||||||
diagnosticCollector,
|
fileManager,
|
||||||
options,
|
diagnosticCollector,
|
||||||
null,
|
options,
|
||||||
javaFileObjectsFromFiles
|
null,
|
||||||
)
|
javaFileObjectsFromFiles
|
||||||
|
)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (ignoreJavaErrors) return false
|
||||||
|
else throw e
|
||||||
|
}
|
||||||
val success = task.call() // do NOT inline this variable, call() should complete before errorsToString()
|
val success = task.call() // do NOT inline this variable, call() should complete before errorsToString()
|
||||||
if (javaErrorFile == null || !javaErrorFile.exists()) {
|
if (javaErrorFile == null || !javaErrorFile.exists()) {
|
||||||
assertions.assertTrue(success || ignoreJavaErrors) { errorsToString(diagnosticCollector, true) }
|
assertions.assertTrue(success || ignoreJavaErrors) { errorsToString(diagnosticCollector, true) }
|
||||||
|
|||||||
-12
@@ -140,10 +140,6 @@ fun generateJUnit3CompilerTests(args: Array<String>) {
|
|||||||
model("codegen/customScript", pattern = "^(.*)$")
|
model("codegen/customScript", pattern = "^(.*)$")
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractBytecodeTextTest> {
|
|
||||||
model("codegen/bytecodeText", targetBackend = TargetBackend.JVM)
|
|
||||||
}
|
|
||||||
|
|
||||||
testClass<AbstractIrJsTextTestCase> {
|
testClass<AbstractIrJsTextTestCase> {
|
||||||
model("ir/irJsText", pattern = "^(.+)\\.kt(s)?\$")
|
model("ir/irJsText", pattern = "^(.+)\\.kt(s)?\$")
|
||||||
}
|
}
|
||||||
@@ -484,10 +480,6 @@ fun generateJUnit3CompilerTests(args: Array<String>) {
|
|||||||
model("codegen/boxInline", targetBackend = TargetBackend.JVM_IR)
|
model("codegen/boxInline", targetBackend = TargetBackend.JVM_IR)
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractIrBytecodeTextTest> {
|
|
||||||
model("codegen/bytecodeText", targetBackend = TargetBackend.JVM_IR, excludeDirs = listOf("oldLanguageVersions"))
|
|
||||||
}
|
|
||||||
|
|
||||||
testClass<AbstractIrAsmLikeInstructionListingTest> {
|
testClass<AbstractIrAsmLikeInstructionListingTest> {
|
||||||
model("codegen/asmLike", targetBackend = TargetBackend.JVM_IR)
|
model("codegen/asmLike", targetBackend = TargetBackend.JVM_IR)
|
||||||
}
|
}
|
||||||
@@ -510,10 +502,6 @@ fun generateJUnit3CompilerTests(args: Array<String>) {
|
|||||||
model("codegen/boxAgainstJava", targetBackend = TargetBackend.JVM_IR, excludeDirs = listOf("oldLanguageVersions"))
|
model("codegen/boxAgainstJava", targetBackend = TargetBackend.JVM_IR, excludeDirs = listOf("oldLanguageVersions"))
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractFirBytecodeTextTest> {
|
|
||||||
model("codegen/bytecodeText", targetBackend = TargetBackend.JVM_IR, excludeDirs = listOf("oldLanguageVersions"))
|
|
||||||
}
|
|
||||||
|
|
||||||
testClass<AbstractFirCompileKotlinAgainstKotlinTest> {
|
testClass<AbstractFirCompileKotlinAgainstKotlinTest> {
|
||||||
model("compileKotlinAgainstKotlin", targetBackend = TargetBackend.JVM_IR)
|
model("compileKotlinAgainstKotlin", targetBackend = TargetBackend.JVM_IR)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-3
@@ -9,9 +9,7 @@ import org.jetbrains.kotlin.generators.model.annotation
|
|||||||
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
|
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.runners.*
|
import org.jetbrains.kotlin.test.runners.*
|
||||||
import org.jetbrains.kotlin.test.runners.codegen.AbstractBlackBoxCodegenTest
|
import org.jetbrains.kotlin.test.runners.codegen.*
|
||||||
import org.jetbrains.kotlin.test.runners.codegen.AbstractFirBlackBoxCodegenTest
|
|
||||||
import org.jetbrains.kotlin.test.runners.codegen.AbstractIrBlackBoxCodegenTest
|
|
||||||
import org.jetbrains.kotlin.test.runners.ir.AbstractFir2IrTextTest
|
import org.jetbrains.kotlin.test.runners.ir.AbstractFir2IrTextTest
|
||||||
import org.jetbrains.kotlin.test.runners.ir.AbstractIrTextTest
|
import org.jetbrains.kotlin.test.runners.ir.AbstractIrTextTest
|
||||||
import org.junit.jupiter.api.parallel.Execution
|
import org.junit.jupiter.api.parallel.Execution
|
||||||
@@ -73,6 +71,14 @@ fun generateJUnit5CompilerTests(args: Array<String>) {
|
|||||||
testClass<AbstractIrTextTest> {
|
testClass<AbstractIrTextTest> {
|
||||||
model("ir/irText")
|
model("ir/irText")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractBytecodeTextTest> {
|
||||||
|
model("codegen/bytecodeText")
|
||||||
|
}
|
||||||
|
|
||||||
|
testClass<AbstractIrBytecodeTextTest> {
|
||||||
|
model("codegen/bytecodeText", excludeDirs = listOf("oldLanguageVersions"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------- FIR tests ----------------------------------------------
|
// ---------------------------------------------- FIR tests ----------------------------------------------
|
||||||
@@ -105,6 +111,10 @@ fun generateJUnit5CompilerTests(args: Array<String>) {
|
|||||||
testClass<AbstractFir2IrTextTest> {
|
testClass<AbstractFir2IrTextTest> {
|
||||||
model("ir/irText")
|
model("ir/irText")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractFirBytecodeTextTest> {
|
||||||
|
model("codegen/bytecodeText", excludeDirs = listOf("oldLanguageVersions"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||||
|
|
||||||
|
@OptIn(ObsoleteTestInfrastructure::class)
|
||||||
class CustomBytecodeTextTest : AbstractBytecodeTextTest() {
|
class CustomBytecodeTextTest : AbstractBytecodeTextTest() {
|
||||||
fun testEnumMapping() {
|
fun testEnumMapping() {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL)
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL)
|
||||||
|
|||||||
+6
-1
@@ -16,13 +16,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.android.synthetic.test
|
package org.jetbrains.kotlin.android.synthetic.test
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||||
import org.jetbrains.kotlin.codegen.AbstractBytecodeTextTest
|
import org.jetbrains.kotlin.codegen.AbstractBytecodeTextTest
|
||||||
|
import org.jetbrains.kotlin.codegen.checkGeneratedTextAgainstExpectedOccurrences
|
||||||
|
import org.jetbrains.kotlin.codegen.readExpectedOccurrences
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.jetbrains.kotlin.test.TargetBackend
|
import org.jetbrains.kotlin.test.TargetBackend
|
||||||
import org.jetbrains.kotlin.test.TestJdkKind
|
import org.jetbrains.kotlin.test.TestJdkKind
|
||||||
|
import org.jetbrains.kotlin.test.util.JUnit4Assertions
|
||||||
|
|
||||||
|
@OptIn(ObsoleteTestInfrastructure::class)
|
||||||
abstract class AbstractAndroidBytecodeShapeTest : AbstractBytecodeTextTest() {
|
abstract class AbstractAndroidBytecodeShapeTest : AbstractBytecodeTextTest() {
|
||||||
private fun createAndroidAPIEnvironment(path: String) {
|
private fun createAndroidAPIEnvironment(path: String) {
|
||||||
return createEnvironmentForConfiguration(KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.ANDROID_API), path)
|
return createEnvironmentForConfiguration(KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.ANDROID_API), path)
|
||||||
@@ -40,6 +45,6 @@ abstract class AbstractAndroidBytecodeShapeTest : AbstractBytecodeTextTest() {
|
|||||||
loadFileByFullPath(fileName)
|
loadFileByFullPath(fileName)
|
||||||
val expected = readExpectedOccurrences(fileName)
|
val expected = readExpectedOccurrences(fileName)
|
||||||
val actual = generateToText()
|
val actual = generateToText()
|
||||||
checkGeneratedTextAgainstExpectedOccurrences(actual, expected, TargetBackend.ANY, true)
|
checkGeneratedTextAgainstExpectedOccurrences(actual, expected, TargetBackend.ANY, true, JUnit4Assertions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user