[LL FIR] KT-50732 Add support for LL FIR-specific tests (.ll.kt)

- `.ll.kt` test data can be added in cases where LL FIR resolution
  legally diverges from K2 compiler results.
- Each `.ll.kt` test is prefixed with an `LL_FIR_DIVERGENCE` directive
  which must explain why the test may diverge from K2 compiler results.
  - `LLFirDivergenceCommentChecker` ensures that each `.ll.kt` file
    contains an `LL_FIR_DIVERGENCE` directive.
- `LLFirIdenticalChecker` results in an assertion error if the `.ll.kt`
  test and its base test are completely identical, including in their
  meta info (but ignoring `LL_FIR_DIVERGENCE`).
  - The checker additionally ensures that the base source file and the
    `.ll.kt` source file have identical Kotlin source code (ignoring
    meta info and `LL_FIR_DIVERGENCE`). This ensures that both tests
    test the exact same thing.
- `.ll.kt` files are ignored by select test generators, in addition to
  `.fir.kt` files.
This commit is contained in:
Marco Pennekamp
2022-12-02 19:01:54 +01:00
committed by teamcity
parent b0db0f59b4
commit 88ac5727cc
52 changed files with 3706 additions and 3010 deletions
@@ -1,5 +1,3 @@
// FIR_IDE_IGNORE
<!CONFLICTING_OVERLOADS!>fun test(x: Int)<!> {}
<!CONFLICTING_OVERLOADS!>fun test(y: Int)<!> {}
@@ -0,0 +1,128 @@
FILE: conflictingOverloads.ll.kt
public final fun test(x: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun test(y: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun test(): R|kotlin/Unit| {
}
public final fun test(z: R|kotlin/Int|, c: R|kotlin/Char|): R|kotlin/Unit| {
}
public open class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public open fun rest(s: R|kotlin/String|): R|kotlin/Unit| {
}
public open val u: R|kotlin/Int| = Int(20)
public get(): R|kotlin/Int|
}
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public final class B : R|A| {
public constructor(): R|B| {
super<R|A|>()
}
public open override fun rest(s: R|kotlin/String|): R|kotlin/Unit| {
}
public final fun rest(s: R|kotlin/String|): R|kotlin/Unit| {
}
public final fun rest(l: R|kotlin/Long|): R|kotlin/Unit| {
}
public open override val u: R|kotlin/Int| = Int(310)
public get(): R|kotlin/Int|
}
public abstract interface B : R|kotlin/Any| {
}
public final enum class B : R|kotlin/Enum<B>| {
private constructor(): R|B| {
super<R|kotlin/Enum<B>|>()
}
public final static fun values(): R|kotlin/Array<B>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|B| {
}
public final static val entries: R|kotlin/enums/EnumEntries<B>|
public get(): R|kotlin/enums/EnumEntries<B>|
}
public final val u: R|kotlin/Int| = Int(10)
public get(): R|kotlin/Int|
public final val u: R|kotlin/Int| = Int(20)
public get(): R|kotlin/Int|
public final typealias TA = R|A|
public final typealias TA = R|B|
public final typealias BA = R|A|
public final fun <T : R|(kotlin/String) -> kotlin/Any?|, R|kotlin/Char|> kek(t: R|T|): R|kotlin/Unit| {
}
public final fun <T : R|() -> kotlin/Boolean|, R|kotlin/String|> kek(t: R|T|): R|kotlin/Unit| {
}
public final fun <T : R|kotlin/Int|> kek(t: R|T|): R|kotlin/Unit| {
}
public final fun lol(a: R|kotlin/Array<kotlin/Int>|): R|kotlin/Unit| {
}
public final fun lol(a: R|kotlin/Array<kotlin/Boolean>|): R|kotlin/Unit| {
}
public final fun <T : R|() -> kotlin/Boolean|, R|kotlin/String|> mem(t: R|T|): R|kotlin/Unit| {
}
public final fun <T : R|kotlin/String|, R|() -> kotlin/Boolean|> mem(t: R|T|): R|kotlin/Unit| {
}
public final class M : R|kotlin/Any| {
public constructor(): R|M| {
super<R|kotlin/Any|>()
}
public final companion object Companion : R|kotlin/Any| {
private constructor(): R|M.Companion| {
super<R|kotlin/Any|>()
}
}
public final val Companion: R|kotlin/Any| = object : R|kotlin/Any| {
private constructor(): R|<anonymous>| {
super<R|kotlin/Any|>()
}
}
public get(): R|kotlin/Any|
}
public final fun R|B|.foo(): R|kotlin/Unit| {
}
public final class L : R|kotlin/Any| {
public constructor(): R|L| {
super<R|kotlin/Any|>()
}
public final fun R|B|.foo(): R|kotlin/Unit| {
}
}
public final fun mest(): R|kotlin/Unit| {
}
public final class mest : R|kotlin/Any| {
public constructor(): R|mest| {
super<R|kotlin/Any|>()
}
}
public final fun <no name provided>(): R|kotlin/Unit| {
}
private final fun <no name provided>(): R|kotlin/Unit| {
}
@@ -0,0 +1,72 @@
// LL_FIR_DIVERGENCE
// The compiler doesn't specify which declaration of `A` is chosen in supertype resolution given that `A` has multiple redeclarations.
// LL_FIR_DIVERGENCE
<!CONFLICTING_OVERLOADS!>fun test(x: Int)<!> {}
<!CONFLICTING_OVERLOADS!>fun test(y: Int)<!> {}
fun test() {}
fun test(z: Int, c: Char) {}
open class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
open fun rest(s: String) {}
open val u = 20
}
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
}
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : <!SUPERTYPE_NOT_INITIALIZED!>A<!> {
<!CONFLICTING_OVERLOADS!>override fun rest(s: String)<!> {}
<!CONFLICTING_OVERLOADS!>fun <!VIRTUAL_MEMBER_HIDDEN!>rest<!>(s: String)<!> {}
fun rest(l: Long) {}
override val u = 310
}
interface <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
enum class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
val <!REDECLARATION!>u<!> = 10
val <!REDECLARATION!>u<!> = 20
typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = A
typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = B
typealias BA = A
fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> kek(t: T) where T : (String) -> Any?, T : <!FINAL_UPPER_BOUND!>Char<!> {}
fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> kek(t: T) where T : () -> Boolean, T : <!FINAL_UPPER_BOUND!>String<!> {}
fun <T : <!FINAL_UPPER_BOUND!>Int<!>> kek(t: T) {}
fun lol(a: Array<Int>) {}
fun lol(a: Array<Boolean>) {}
<!CONFLICTING_OVERLOADS!>fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> mem(t: T)<!> where T : () -> Boolean, T : <!FINAL_UPPER_BOUND!>String<!> {}
<!CONFLICTING_OVERLOADS!>fun <<!CONFLICTING_UPPER_BOUNDS!>T<!>> mem(t: T)<!> where T : <!FINAL_UPPER_BOUND!>String<!>, T : () -> Boolean {}
class M {
companion <!REDECLARATION!>object<!> {}
val <!REDECLARATION!>Companion<!> = object : Any() {}
}
fun B.foo() {}
class L {
fun B.foo() {}
}
<!CONFLICTING_OVERLOADS!>fun mest()<!> {}
class <!CONFLICTING_OVERLOADS!>mest<!>
<!FUNCTION_DECLARATION_WITH_NO_NAME!>fun()<!> {}
<!FUNCTION_DECLARATION_WITH_NO_NAME!>private fun()<!> {}
@@ -1,5 +1,3 @@
// FIR_IDE_IGNORE
sealed class A
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : A()
@@ -0,0 +1,117 @@
FILE: sealedSupertype.ll.kt
public sealed class A : R|kotlin/Any| {
protected constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public final class B : R|A| {
public constructor(): R|B| {
super<R|A|>()
}
}
public abstract interface C : R|A| {
}
public abstract interface D : R|C|, R|A| {
}
public final class E : R|B|, R|A| {
public constructor(): R|E| {
super<R|A|>()
}
}
public sealed class P : R|kotlin/Any| {
protected constructor(): R|P| {
super<R|kotlin/Any|>()
}
public final object H : R|P| {
private constructor(): R|P.H| {
super<R|P|>()
}
}
public final class J : R|P| {
public constructor(): R|P.J| {
super<R|P|>()
}
}
public final object T : R|kotlin/Any| {
private constructor(): R|P.T| {
super<R|kotlin/Any|>()
}
public final object V : R|P| {
private constructor(): R|P.T.V| {
super<R|P|>()
}
}
public final class M : R|P| {
public constructor(): R|P.T.M| {
super<R|P|>()
}
}
}
public final val p: R|P| = object : R|P| {
private constructor(): R|<anonymous>| {
super<R|P|>()
}
}
public get(): R|P|
public final val r: R|P| = object : R|P| {
private constructor(): R|<anonymous>| {
super<R|P|>()
}
}
public get(): R|P|
}
public final class K : R|P| {
public constructor(): R|K| {
super<R|P|>()
}
}
public final object B : R|kotlin/Any| {
private constructor(): R|B| {
super<R|kotlin/Any|>()
}
public final class I : R|P| {
public constructor(): R|B.I| {
super<R|P|>()
}
}
}
public final fun test(): R|kotlin/Unit| {
local final class L : R|P| {
public constructor(): R|L| {
super<R|P|>()
}
}
lval a: R|<anonymous>| = object : R|P| {
private constructor(): R|<anonymous>| {
super<R|P|>()
}
}
}
@@ -0,0 +1,45 @@
// LL_FIR_DIVERGENCE
// The compiler doesn't specify which declaration of `B` is chosen in supertype resolution given that `B` is declared both as a class and
// as an object.
// LL_FIR_DIVERGENCE
sealed class A
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : A()
interface C : <!INTERFACE_WITH_SUPERCLASS!>A<!>
interface D : C, <!INTERFACE_WITH_SUPERCLASS!>A<!>
class E : <!FINAL_SUPERTYPE!>B<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST!>A<!>()
sealed class P {
object H: P()
class J : P()
object T {
object V : P()
class M : P()
}
val p: P = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>() {
}
val r = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>() {
}
}
class K : P()
object <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> {
class I : P()
}
fun test() {
class L : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>()
val a = object : <!SEALED_SUPERTYPE_IN_LOCAL_CLASS!>P<!>() {
}
}