Support target templates in bytecode tests

Avoid test data duplication
This commit is contained in:
Mikhael Bogdanov
2019-07-16 09:15:31 +02:00
parent de1e27c584
commit 496765f41e
46 changed files with 250 additions and 679 deletions
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun test() {
var sum = 0
for (i in arrayOf("", "", "", "").indices) {
@@ -1,19 +0,0 @@
// TARGET_BACKEND: JVM_IR
fun test() {
var sum = 0
for (i in arrayOf("", "", "", "").indices) {
sum += i
}
}
// JVM non-IR uses while.
// JVM IR uses if + do-while.
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 2 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun test() {
var sum = 0
for (i in intArrayOf(0, 0, 0, 0).indices) {
@@ -14,5 +13,12 @@ fun test() {
// 0 getEnd
// 0 getFirst
// 0 getLast
// JVM_TEMPLATES
// 1 IF_ICMPGE
// 1 IF
// 1 IF
// JVM_IR_TEMPLATES
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 2 IF
@@ -1,19 +0,0 @@
// TARGET_BACKEND: JVM_IR
fun test() {
var sum = 0
for (i in intArrayOf(0, 0, 0, 0).indices) {
sum += i
}
}
// JVM non-IR uses while.
// JVM IR uses if + do-while.
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 2 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
const val N = 'Z'
fun test(): Int {
@@ -18,5 +17,10 @@ fun test(): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF
// JVM_TEMPLATES
// 1 IF_ICMPGT
// 1 IF
// JVM_IR_TEMPLATES
// 1 IF_ICMPLE
@@ -1,22 +0,0 @@
// TARGET_BACKEND: JVM_IR
const val N = 'Z'
fun test(): Int {
var sum = 0
for (i in 'A' .. N) {
sum += i.toInt()
}
return sum
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF_ICMPLE
// 1 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
const val N = 42
fun test(): Int {
@@ -18,5 +17,10 @@ fun test(): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF
// JVM_TEMPLATES
// 1 IF_ICMPGT
// 1 IF
// JVM_IR_TEMPLATES
// 1 IF_ICMPLE
@@ -1,22 +0,0 @@
// TARGET_BACKEND: JVM_IR
const val N = 42
fun test(): Int {
var sum = 0
for (i in 1 .. N) {
sum += i
}
return sum
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF_ICMPLE
// 1 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
const val N = 42L
fun test(): Long {
@@ -18,8 +17,15 @@ fun test(): Long {
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 LCMP
// 1 IFGT
// 1 IF
// 0 L2I
// 0 I2L
// 0 I2L
// JVM_TEMPLATES
// 1 LCMP
// 1 IF
// JVM_IR_TEMPLATES
// 2 LCMP
// 1 IFLE
// 2 IF
@@ -1,26 +0,0 @@
// TARGET_BACKEND: JVM_IR
const val N = 42L
fun test(): Long {
var sum = 0L
for (i in 1L .. N) {
sum += i
}
return sum
}
// JVM non-IR uses while.
// JVM IR uses if + do-while.
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 LCMP
// 1 IFGT
// 1 IFLE
// 2 IF
// 0 L2I
// 0 I2L
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
object Host {
const val M = 1
const val N = 4
@@ -21,5 +20,10 @@ fun test(): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF
// JVM_TEMPLATES
// 1 IF_ICMPGT
// 1 IF
// JVM_IR_TEMPLATES
// 1 IF_ICMPLE
@@ -1,25 +0,0 @@
// TARGET_BACKEND: JVM_IR
object Host {
const val M = 1
const val N = 4
}
fun test(): Int {
var s = 0
for (i in Host.M .. Host.N) {
s += i
}
return s
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF_ICMPLE
// 1 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -22,5 +21,12 @@ fun box(): String {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 1 IFLT
// 1 IF
// 1 IF
// JVM_IR_TEMPLATES
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 2 IF
@@ -1,27 +0,0 @@
// TARGET_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
val arr = intArrayOf(1, 1, 1, 1)
var sum = 0
for (i in arr.indices.reversed()) {
sum = sum * 10 + i + arr[i]
}
assertEquals(4321, sum)
return "OK"
}
// JVM non-IR uses while.
// JVM IR uses if + do-while.
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 2 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -33,7 +32,15 @@ fun box(): String {
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMPGT
// 1 IFGT
// JVM_TEMPLATES
// 2 IF_ICMPGT
// 3 IF
// 1 LCMP
// 1 LCMP
// JVM_IR_TEMPLATES
// 2 IF_ICMPLE
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,40 +0,0 @@
// TARGET_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
var sum = 0
for (i in (4 downTo 1).reversed()) {
sum = sum * 10 + i
}
assertEquals(1234, sum)
var sumL = 0L
for (i in (4L downTo 1L).reversed()) {
sumL = sumL * 10 + i
}
assertEquals(1234L, sumL)
var sumC = 0
for (i in ('4' downTo '1').reversed()) {
sumC = sumC * 10 + i.toInt() - '0'.toInt()
}
assertEquals(1234, sumC)
return "OK"
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMPLE
// 1 IFGT
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -33,7 +32,16 @@ fun box(): String {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 2 IF_ICMPLT
// 1 IFLT
// 3 IF
// 1 LCMP
// 1 LCMP
// JVM_IR_TEMPLATES
// 2 IF_ICMPLE
// 1 IFGT
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,40 +0,0 @@
// TARGET_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
var sum = 0
for (i in (1 .. 4).reversed()) {
sum = sum * 10 + i
}
assertEquals(4321, sum)
var sumL = 0L
for (i in (1L .. 4L).reversed()) {
sumL = sumL * 10 + i
}
assertEquals(4321L, sumL)
var sumC = 0
for (i in ('1' .. '4').reversed()) {
sumC = sumC * 10 + i.toInt() - '0'.toInt()
}
assertEquals(4321, sumC)
return "OK"
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMPLE
// 1 IFGT
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -33,7 +32,16 @@ fun box(): String {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 2 IF_ICMPLT
// 1 IFLT
// 3 IF
// 1 LCMP
// 1 LCMP
// JVM_IR_TEMPLATES
// 2 IF_ICMPLE
// 1 IFGT
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,40 +0,0 @@
// TARGET_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
var sum = 0
for (i in (4 downTo 1).reversed().reversed()) {
sum = sum * 10 + i
}
assertEquals(1234, sum)
var sumL = 0L
for (i in (4L downTo 1L).reversed().reversed()) {
sumL = sumL * 10 + i
}
assertEquals(1234L, sumL)
var sumC = 0
for (i in ('4' downTo '1').reversed().reversed()) {
sumC = sumC * 10 + i.toInt() - '0'.toInt()
}
assertEquals(1234, sumC)
return "OK"
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMPLE
// 1 IFGT
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -30,7 +29,16 @@ fun box(): String {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 2 IF_ICMPGE
// 1 IFGE
// 3 IF
// 1 LCMP
// 1 LCMP
// JVM_IR_TEMPLATES
// 2 IF_ICMPLE
// 1 IFGT
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,37 +0,0 @@
// TARGET_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
var sum = 0
for (i in (1 until 5).reversed().reversed()) {
sum = sum * 10 + i
}
var sumL = 0L
for (i in (1L until 5L).reversed().reversed()) {
sumL = sumL * 10 + i
}
var sumC = 0
for (i in ('1' until '5').reversed().reversed()) {
sumC = sumC * 10 + i.toInt() - '0'.toInt()
}
return "OK"
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMPLE
// 1 IFGT
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -30,7 +29,16 @@ fun box(): String {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 2 IF_ICMPLT
// 1 IFLT
// 3 IF
// 1 LCMP
// 1 LCMP
// JVM_IR_TEMPLATES
// 2 IF_ICMPLE
// 1 IFGT
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,37 +0,0 @@
// TARGET_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
var sum = 0
for (i in (1 until 5).reversed()) {
sum = sum * 10 + i
}
var sumL = 0L
for (i in (1L until 5L).reversed()) {
sumL = sumL * 10 + i
}
var sumC = 0
for (i in ('1' until '5').reversed()) {
sumC = sumC * 10 + i.toInt() - '0'.toInt()
}
return "OK"
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMPLE
// 1 IFGT
// 1 IFLE
// 4 IF
// 2 LCMP
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun test(a: Char, b: Char): String {
var s = ""
for (i in a until b) {
@@ -16,5 +15,13 @@ fun test(a: Char, b: Char): String {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 1 IF_ICMPGE
// 1 IF
// 1 IF
// JVM_IR_TEMPLATES
// 1 IFEQ
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 3 IF
@@ -1,22 +0,0 @@
// TARGET_BACKEND: JVM_IR
fun test(a: Char, b: Char): String {
var s = ""
for (i in a until b) {
s += i
}
return s
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE.
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IFEQ
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 3 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
const val M = Char.MAX_VALUE
fun f(a: Char): Int {
@@ -18,5 +17,12 @@ fun f(a: Char): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 1 IF_ICMPGE
// 1 IF
// 1 IF
// JVM_IR_TEMPLATES
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 2 IF
@@ -1,23 +0,0 @@
// TARGET_BACKEND: JVM_IR
const val M = Char.MAX_VALUE
fun f(a: Char): Int {
var n = 0
for (i in a until M) {
n++
}
return n
}
// JVM non-IR uses while.
// JVM IR uses if + do-while.
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 2 IF
@@ -1,4 +1,3 @@
// TARGET_BACKEND: JVM_IR
const val M = Char.MIN_VALUE
fun f(a: Char): Int {
@@ -18,5 +17,10 @@ fun f(a: Char): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// 0 IF
// 0 LINENUMBER 7
// 0 LINENUMBER 7
// JVM_TEMPLATES
// 1 IF
// JVM_IR_TEMPLATES
// 0 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun test(a: Int, b: Int): Int {
var sum = 0
for (i in a until b) {
@@ -16,5 +15,14 @@ fun test(a: Int, b: Int): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 1 IF_ICMPGE
// 1 IF
// 1 IF
// JVM_IR_TEMPLATES
// 1 LDC -2147483648
// 1 IF_ICMPEQ
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 3 IF
@@ -1,23 +0,0 @@
// TARGET_BACKEND: JVM_IR
fun test(a: Int, b: Int): Int {
var sum = 0
for (i in a until b) {
sum = sum * 10 + i
}
return sum
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE.
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 LDC -2147483648
// 1 IF_ICMPEQ
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 3 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
const val M = Int.MAX_VALUE
fun f(a: Int): Int {
@@ -18,5 +17,12 @@ fun f(a: Int): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 1 IF_ICMPGE
// 1 IF
// 1 IF
// JVM_IR_TEMPLATES
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 2 IF
@@ -1,23 +0,0 @@
// TARGET_BACKEND: JVM_IR
const val M = Int.MAX_VALUE
fun f(a: Int): Int {
var n = 0
for (i in a until M) {
n++
}
return n
}
// JVM non-IR uses while.
// JVM IR uses if + do-while.
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF_ICMPGT
// 1 IF_ICMPLE
// 2 IF
@@ -1,4 +1,3 @@
// TARGET_BACKEND: JVM_IR
const val M = Int.MIN_VALUE
fun f(a: Int): Int {
@@ -18,5 +17,10 @@ fun f(a: Int): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// 0 IF
// 0 LINENUMBER 7
// 0 LINENUMBER 7
// JVM_TEMPLATES
// 1 IF
// JVM_IR_TEMPLATES
// 0 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun test(a: Long, b: Long): Long {
var sum = 0L
for (i in a until b) {
@@ -16,6 +15,16 @@ fun test(a: Long, b: Long): Long {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 1 LCMP
// 1 IFGE
// 1 IF
// 1 IF
// JVM_IR_TEMPLATES
// 1 LDC -9223372036854775808
// 3 LCMP
// 1 IFEQ
// 1 IFGT
// 1 IFLE
// 3 IF
@@ -1,24 +0,0 @@
// TARGET_BACKEND: JVM_IR
fun test(a: Long, b: Long): Long {
var sum = 0L
for (i in a until b) {
sum = sum * 10L + i
}
return sum
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE.
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 LDC -9223372036854775808
// 3 LCMP
// 1 IFEQ
// 1 IFGT
// 1 IFLE
// 3 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
const val M = Long.MAX_VALUE
fun f(a: Long): Int {
@@ -18,6 +17,14 @@ fun f(a: Long): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// JVM_TEMPLATES
// 1 LCMP
// 1 IFGE
// 1 IF
// 1 IF
// JVM_IR_TEMPLATES
// 2 LCMP
// 1 IFGT
// 1 IFLE
// 2 IF
@@ -1,24 +0,0 @@
// TARGET_BACKEND: JVM_IR
const val M = Long.MAX_VALUE
fun f(a: Long): Int {
var n = 0
for (i in a until M) {
n++
}
return n
}
// JVM non-IR uses while.
// JVM IR uses if + do-while.
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 LCMP
// 1 IFGT
// 1 IFLE
// 2 IF
@@ -1,4 +1,3 @@
// TARGET_BACKEND: JVM_IR
const val M = Long.MIN_VALUE
fun f(a: Long): Int {
@@ -18,5 +17,10 @@ fun f(a: Long): Int {
// 0 getFirst
// 0 getLast
// 0 getStep
// 0 IF
// 0 LINENUMBER 7
// 0 LINENUMBER 7
// JVM_TEMPLATES
// 1 IF
// JVM_IR_TEMPLATES
// 0 IF
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun f() {
for (i in 1..2) {
}
@@ -13,5 +12,10 @@ fun f() {
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF
// JVM_TEMPLATES
// 1 IF_ICMPGT
// 1 IF
// JVM_IR_TEMPLATES
// 1 IF_ICMPLE
@@ -1,17 +0,0 @@
// TARGET_BACKEND: JVM_IR
fun f() {
for (i in 1..2) {
}
}
// JVM non-IR uses while.
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF_ICMPLE
// 1 IF
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.TestJdkKind
import org.junit.Assert
import java.io.File
@@ -30,7 +31,7 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
} else {
val expected = readExpectedOccurrences(wholeFile.path)
val actual = generateToText("helpers/")
checkGeneratedTextAgainstExpectedOccurrences(actual, expected)
checkGeneratedTextAgainstExpectedOccurrences(actual, expected, getBackend())
}
}
@@ -45,25 +46,28 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
assertTextWasGenerated(expectedOutputFile, generated)
val generatedText = generated[expectedOutputFile]!!
val expectedOccurrences = expectedOccurrencesByOutputFile[expectedOutputFile]!!
checkGeneratedTextAgainstExpectedOccurrences(generatedText, expectedOccurrences)
checkGeneratedTextAgainstExpectedOccurrences(generatedText, expectedOccurrences, getBackend())
}
}
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))
result.add(parseOccurrenceInfo(matcher, backend))
}
}
return result
}
class OccurrenceInfo constructor(private val numberOfOccurrences: Int, private val needle: String) {
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"
@@ -88,13 +92,29 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
return kotlinFiles > 1
}
fun checkGeneratedTextAgainstExpectedOccurrences(text: String, expectedOccurrences: List<OccurrenceInfo>) {
fun checkGeneratedTextAgainstExpectedOccurrences(text: String, expectedOccurrences: List<OccurrenceInfo>, currentBackend: TargetBackend) {
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")
actual.append(info.getActualOccurrence(text)).append("\n")
if (info.backend == TargetBackend.ANY || info.backend == currentBackend) {
actual.append(info.getActualOccurrence(text)).append("\n")
} else {
actual.append(info).append("\n")
}
}
try {
@@ -117,9 +137,17 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
}
}
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)
@@ -135,16 +163,20 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
if (currentOccurrenceInfos == null) {
throw AssertionError("${file.name}: Should specify output file with '// @<OUTPUT_FILE_NAME>:' before expectations")
}
val occurrenceInfo = parseOccurrenceInfo(expectedOccurrencesMatcher)
val occurrenceInfo = parseOccurrenceInfo(expectedOccurrencesMatcher, backend)
currentOccurrenceInfos.add(occurrenceInfo)
}
}
}
private fun parseOccurrenceInfo(matcher: Matcher): 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)
return OccurrenceInfo(numberOfOccurrences, needle, backend)
}
}
protected open fun getBackend(): TargetBackend {
return TargetBackend.JVM
}
}
@@ -23,10 +23,7 @@ import kotlin.sequences.SequencesKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
import org.jetbrains.kotlin.test.CompilerTestUtil;
import org.jetbrains.kotlin.test.ConfigurationKind;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TestJdkKind;
import org.jetbrains.kotlin.test.*;
import java.io.File;
import java.util.Collections;
@@ -62,6 +59,6 @@ public abstract class AbstractTopLevelMembersInvocationTest extends AbstractByte
List<OccurrenceInfo> expected = readExpectedOccurrences(KotlinTestUtils.getTestDataPathBase() + "/codegen/" + sourceFiles.get(0));
String actual = generateToText();
Companion.checkGeneratedTextAgainstExpectedOccurrences(actual, expected);
Companion.checkGeneratedTextAgainstExpectedOccurrences(actual, expected, TargetBackend.ANY);
}
}
@@ -8,7 +8,12 @@ package org.jetbrains.kotlin.codegen.ir
import org.jetbrains.kotlin.codegen.AbstractBytecodeTextTest
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.test.TargetBackend
abstract class AbstractIrBytecodeTextTest : AbstractBytecodeTextTest() {
override fun updateConfiguration(configuration: CompilerConfiguration) = configuration.put(JVMConfigurationKeys.IR, true)
override fun getBackend(): TargetBackend {
return TargetBackend.JVM_IR
}
}
@@ -2082,6 +2082,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt");
}
@TestMetadata("forInUntilCharMinValue.kt")
public void testForInUntilCharMinValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValue.kt");
}
@TestMetadata("forInUntilInt.kt")
public void testForInUntilInt() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt");
@@ -2092,6 +2097,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt");
}
@TestMetadata("forInUntilIntMinValue.kt")
public void testForInUntilIntMinValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValue.kt");
}
@TestMetadata("forInUntilLong.kt")
public void testForInUntilLong() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt");
@@ -2101,6 +2111,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
public void testForInUntilLongMaxValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt");
}
@TestMetadata("forInUntilLongMinValue.kt")
public void testForInUntilLongMinValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValue.kt");
}
}
}
@@ -1657,11 +1657,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt");
}
@TestMetadata("forInRangeToCharConstIR.kt")
public void testForInRangeToCharConstIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConstIR.kt");
}
@TestMetadata("forInRangeToCharMaxValue.kt")
public void testForInRangeToCharMaxValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharMaxValue.kt");
@@ -1672,11 +1667,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt");
}
@TestMetadata("forInRangeToConstIR.kt")
public void testForInRangeToConstIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConstIR.kt");
}
@TestMetadata("forInRangeToIntMaxValue.kt")
public void testForInRangeToIntMaxValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToIntMaxValue.kt");
@@ -1687,11 +1677,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt");
}
@TestMetadata("forInRangeToLongConstIR.kt")
public void testForInRangeToLongConstIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConstIR.kt");
}
@TestMetadata("forInRangeToLongMaxValue.kt")
public void testForInRangeToLongMaxValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongMaxValue.kt");
@@ -1702,11 +1687,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt");
}
@TestMetadata("forInRangeToQualifiedConstIR.kt")
public void testForInRangeToQualifiedConstIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConstIR.kt");
}
@TestMetadata("forInRangeWithImplicitReceiver.kt")
public void testForInRangeWithImplicitReceiver() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt");
@@ -1737,11 +1717,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt");
}
@TestMetadata("primitiveLiteralRange1IR.kt")
public void testPrimitiveLiteralRange1IR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1IR.kt");
}
@TestMetadata("primitiveLiteralRange2.kt")
public void testPrimitiveLiteralRange2() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt");
@@ -1875,20 +1850,10 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt");
}
@TestMetadata("forInObjectArrayIndicesIR.kt")
public void testForInObjectArrayIndicesIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndicesIR.kt");
}
@TestMetadata("forInPrimitiveArrayIndices.kt")
public void testForInPrimitiveArrayIndices() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt");
}
@TestMetadata("forInPrimitiveArrayIndicesIR.kt")
public void testForInPrimitiveArrayIndicesIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndicesIR.kt");
}
}
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex")
@@ -1946,11 +1911,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt");
}
@TestMetadata("forInReversedArrayIndicesIR.kt")
public void testForInReversedArrayIndicesIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndicesIR.kt");
}
@TestMetadata("forInReversedCharSequenceIndices.kt")
public void testForInReversedCharSequenceIndices() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCharSequenceIndices.kt");
@@ -1966,11 +1926,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt");
}
@TestMetadata("forInReversedDownToIR.kt")
public void testForInReversedDownToIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownToIR.kt");
}
@TestMetadata("forInReversedEmptyRangeLiteral.kt")
public void testForInReversedEmptyRangeLiteral() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedEmptyRangeLiteral.kt");
@@ -1986,11 +1941,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt");
}
@TestMetadata("forInReversedRangeLiteralIR.kt")
public void testForInReversedRangeLiteralIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteralIR.kt");
}
@TestMetadata("forInReversedReversedArrayIndices.kt")
public void testForInReversedReversedArrayIndices() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedArrayIndices.kt");
@@ -2001,11 +1951,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt");
}
@TestMetadata("forInReversedReversedDownToIR.kt")
public void testForInReversedReversedDownToIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownToIR.kt");
}
@TestMetadata("ForInReversedReversedRange.kt")
public void testForInReversedReversedRange() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/ForInReversedReversedRange.kt");
@@ -2021,20 +1966,10 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt");
}
@TestMetadata("forInReversedReversedUntilIR.kt")
public void testForInReversedReversedUntilIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntilIR.kt");
}
@TestMetadata("forInReversedUntil.kt")
public void testForInReversedUntil() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt");
}
@TestMetadata("forInReversedUntilIR.kt")
public void testForInReversedUntilIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntilIR.kt");
}
}
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex")
@@ -2097,24 +2032,14 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt");
}
@TestMetadata("forInUntilCharIR.kt")
public void testForInUntilCharIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharIR.kt");
}
@TestMetadata("forInUntilCharMaxValue.kt")
public void testForInUntilCharMaxValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt");
}
@TestMetadata("forInUntilCharMaxValueIR.kt")
public void testForInUntilCharMaxValueIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValueIR.kt");
}
@TestMetadata("forInUntilCharMinValueIR.kt")
public void testForInUntilCharMinValueIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValueIR.kt");
@TestMetadata("forInUntilCharMinValue.kt")
public void testForInUntilCharMinValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValue.kt");
}
@TestMetadata("forInUntilInt.kt")
@@ -2122,24 +2047,14 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt");
}
@TestMetadata("forInUntilIntIR.kt")
public void testForInUntilIntIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntIR.kt");
}
@TestMetadata("forInUntilIntMaxValue.kt")
public void testForInUntilIntMaxValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt");
}
@TestMetadata("forInUntilIntMaxValueIR.kt")
public void testForInUntilIntMaxValueIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValueIR.kt");
}
@TestMetadata("forInUntilIntMinValueIR.kt")
public void testForInUntilIntMinValueIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValueIR.kt");
@TestMetadata("forInUntilIntMinValue.kt")
public void testForInUntilIntMinValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValue.kt");
}
@TestMetadata("forInUntilLong.kt")
@@ -2147,24 +2062,14 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt");
}
@TestMetadata("forInUntilLongIR.kt")
public void testForInUntilLongIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongIR.kt");
}
@TestMetadata("forInUntilLongMaxValue.kt")
public void testForInUntilLongMaxValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt");
}
@TestMetadata("forInUntilLongMaxValueIR.kt")
public void testForInUntilLongMaxValueIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValueIR.kt");
}
@TestMetadata("forInUntilLongMinValueIR.kt")
public void testForInUntilLongMinValueIR() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValueIR.kt");
@TestMetadata("forInUntilLongMinValue.kt")
public void testForInUntilLongMinValue() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValue.kt");
}
@TestMetadata("forInUntilWithMixedTypeBoundsBoundCheckNeededForIntRangeIR.kt")