[FIR] Support old FE-like multifile tests

This commit is contained in:
Dmitriy Novozhilov
2019-10-31 17:27:51 +03:00
parent 65eed24dbb
commit 09fa15c22b
36 changed files with 353 additions and 121 deletions
@@ -1,12 +0,0 @@
package annotations
@Target(AnnotationTarget.FILE, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.PROPERTY_GETTER)
annotation class Simple
annotation class WithInt(val value: Int)
annotation class WithString(val s: String)
annotation class Complex(val wi: WithInt, val ws: WithString)
annotation class VeryComplex(val f: Float, val d: Double, val b: Boolean, val l: Long, val n: Int?)
@@ -1,3 +1,20 @@
// FILE: annotations.kt
package annotations
@Target(AnnotationTarget.FILE, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.PROPERTY_GETTER)
annotation class Simple
annotation class WithInt(val value: Int)
annotation class WithString(val s: String)
annotation class Complex(val wi: WithInt, val ws: WithString)
annotation class VeryComplex(val f: Float, val d: Double, val b: Boolean, val l: Long, val n: Int?)
// FILE: main.kt
@file:Simple
package test
@@ -1,4 +1,62 @@
FILE: Annotations.kt
FILE: annotations.kt
@R|kotlin/annotation/Target|(Q|kotlin/annotation/AnnotationTarget.FILE|, Q|kotlin/annotation/AnnotationTarget.FUNCTION|, Q|kotlin/annotation/AnnotationTarget.TYPE|, Q|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|) public final annotation class Simple : R|kotlin/Annotation| {
public constructor(): R|annotations/Simple| {
super<R|kotlin/Annotation|>()
}
}
public final annotation class WithInt : R|kotlin/Annotation| {
public constructor(value: R|kotlin/Int|): R|annotations/WithInt| {
super<R|kotlin/Annotation|>()
}
public final val value: R|kotlin/Int| = R|<local>/value|
public get(): R|kotlin/Int|
}
public final annotation class WithString : R|kotlin/Annotation| {
public constructor(s: R|kotlin/String|): R|annotations/WithString| {
super<R|kotlin/Annotation|>()
}
public final val s: R|kotlin/String| = R|<local>/s|
public get(): R|kotlin/String|
}
public final annotation class Complex : R|kotlin/Annotation| {
public constructor(wi: R|annotations/WithInt|, ws: R|annotations/WithString|): R|annotations/Complex| {
super<R|kotlin/Annotation|>()
}
public final val wi: R|annotations/WithInt| = R|<local>/wi|
public get(): R|annotations/WithInt|
public final val ws: R|annotations/WithString| = R|<local>/ws|
public get(): R|annotations/WithString|
}
public final annotation class VeryComplex : R|kotlin/Annotation| {
public constructor(f: R|kotlin/Float|, d: R|kotlin/Double|, b: R|kotlin/Boolean|, l: R|kotlin/Long|, n: R|kotlin/Int?|): R|annotations/VeryComplex| {
super<R|kotlin/Annotation|>()
}
public final val f: R|kotlin/Float| = R|<local>/f|
public get(): R|kotlin/Float|
public final val d: R|kotlin/Double| = R|<local>/d|
public get(): R|kotlin/Double|
public final val b: R|kotlin/Boolean| = R|<local>/b|
public get(): R|kotlin/Boolean|
public final val l: R|kotlin/Long| = R|<local>/l|
public get(): R|kotlin/Long|
public final val n: R|kotlin/Int?| = R|<local>/n|
public get(): R|kotlin/Int?|
}
FILE: main.kt
@FILE:R|annotations/Simple|()
@R|annotations/WithInt|(Int(42)) public abstract class First : R|kotlin/Any| {
public constructor(): R|test/First| {
@@ -1,5 +0,0 @@
package Test
interface ByteArray {
val array: ByteArray
}
@@ -1,3 +1,13 @@
// FILE: byteArray.kt
package Test
interface ByteArray {
val array: ByteArray
}
// FILE: main.kt
package use
import test.*
@@ -1,4 +1,10 @@
FILE: ByteArray.kt
FILE: byteArray.kt
public abstract interface ByteArray : R|kotlin/Any| {
public abstract val array: R|Test/ByteArray|
public get(): R|Test/ByteArray|
}
FILE: main.kt
public abstract interface My : R|kotlin/Any| {
public abstract val array: R|kotlin/ByteArray|
public get(): R|kotlin/ByteArray|
@@ -1,7 +0,0 @@
package b
import c.C
open class B : C() {
open class NestedInB : NestedInC()
}
@@ -1,5 +0,0 @@
package c
open class C {
open class NestedInC
}
@@ -1,3 +1,23 @@
// FILE: C.kt
package c
open class C {
open class NestedInC
}
// FILE: B.kt
package b
import c.C
open class B : C() {
open class NestedInB : NestedInC()
}
// FILE: A.kt
package a
import b.B
@@ -1,4 +1,32 @@
FILE: NestedSuperType.kt
FILE: C.kt
public open class C : R|kotlin/Any| {
public constructor(): R|c/C| {
super<R|kotlin/Any|>()
}
public open class NestedInC : R|kotlin/Any| {
public constructor(): R|c/C.NestedInC| {
super<R|kotlin/Any|>()
}
}
}
FILE: B.kt
public open class B : R|c/C| {
public constructor(): R|b/B| {
super<R|c/C|>()
}
public open class NestedInB : R|c/C.NestedInC| {
public constructor(): R|b/B.NestedInB| {
super<R|c/C.NestedInC|>()
}
}
}
FILE: A.kt
public final class A : R|b/B| {
public constructor(): R|a/A| {
super<R|b/B|>()
@@ -1,7 +0,0 @@
package b
class A
typealias TA = A
// analyzePriority: 1
@@ -1,7 +1,15 @@
// FILE: B.kt
package b
class A
typealias TA = A
// FILE: A.kt
package a
import b.TA
class MyClass : TA()
// analyzePriority: 0
@@ -1,4 +1,12 @@
FILE: TypeAliasExpansion.kt
FILE: B.kt
public final class A : R|kotlin/Any| {
public constructor(): R|b/A| {
super<R|kotlin/Any|>()
}
}
public final typealias TA = R|b/A|
FILE: A.kt
public final class MyClass : R|b/TA| {
public constructor(): R|a/MyClass| {
super<R|b/TA|>()
@@ -1,6 +0,0 @@
package a
object A {
fun foo() {}
}
@@ -1,3 +1,13 @@
// FILE: a.kt
package a
object A {
fun foo() {}
}
// FILE: b.kt
package b
import a.A.foo
@@ -1,4 +1,14 @@
FILE: importFromObject.kt
FILE: a.kt
public final object A : R|kotlin/Any| {
private constructor(): R|a/A| {
super<R|kotlin/Any|>()
}
public final fun foo(): R|kotlin/Unit| {
}
}
FILE: b.kt
public final fun bar(): R|kotlin/Unit| {
this@R|a/A|.R|a/A.foo|()
}
@@ -1,7 +0,0 @@
package test
sealed class Test {
object O : Test()
class Extra(val x: Int): Test
}
@@ -1,3 +1,15 @@
// FILE: test.kt
package test
sealed class Test {
object O : Test()
class Extra(val x: Int): Test
}
// FILE: main.kt
package other
import test.Test.*
@@ -1,4 +1,28 @@
FILE: sealedStarImport.kt
FILE: test.kt
public sealed class Test : R|kotlin/Any| {
private constructor(): R|test/Test| {
super<R|kotlin/Any|>()
}
public final object O : R|test/Test| {
private constructor(): R|test/Test.O| {
super<R|test/Test|>()
}
}
public final class Extra : R|test/Test| {
public constructor(x: R|kotlin/Int|): R|test/Test.Extra| {
super<R|kotlin/Any|>()
}
public final val x: R|kotlin/Int| = R|<local>/x|
public get(): R|kotlin/Int|
}
}
FILE: main.kt
public abstract class Factory : R|kotlin/Any| {
public constructor(): R|other/Factory| {
super<R|kotlin/Any|>()
@@ -1,8 +0,0 @@
package b
abstract class MyClass
fun foo() {}
fun I() {}
interface I {}
@@ -1,3 +1,16 @@
// FILE: B.kt
package b
abstract class MyClass
fun foo() {}
fun I() {}
interface I {}
// FILE: A.kt
package a
import b.MyClass as HisClass
import b.foo as foo2
@@ -1,4 +1,17 @@
FILE: simpleAliasedImport.kt
FILE: B.kt
public abstract class MyClass : R|kotlin/Any| {
public constructor(): R|b/MyClass| {
super<R|kotlin/Any|>()
}
}
public final fun foo(): R|kotlin/Unit| {
}
public final fun I(): R|kotlin/Unit| {
}
public abstract interface I : R|kotlin/Any| {
}
FILE: A.kt
public final class YourClass : R|b/MyClass| {
public constructor(): R|a/YourClass| {
super<R|b/MyClass|>()
@@ -1,8 +0,0 @@
package b
abstract class MyClass
fun foo() {}
fun I() {}
interface I {}
@@ -1,3 +1,17 @@
// FILE B.kt
package b
abstract class MyClass
fun foo() {}
fun I() {}
interface I {}
// FILE A.kt
package a
import b.MyClass
import b.foo
@@ -1,6 +1,18 @@
FILE: simpleImport.kt
public abstract class MyClass : R|kotlin/Any| {
public constructor(): R|b/MyClass| {
super<R|kotlin/Any|>()
}
}
public final fun foo(): R|kotlin/Unit| {
}
public final fun I(): R|kotlin/Unit| {
}
public abstract interface I : R|kotlin/Any| {
}
public final class YourClass : R|b/MyClass| {
public constructor(): R|a/YourClass| {
public constructor(): R|b/YourClass| {
super<R|b/MyClass|>()
}
@@ -1,5 +0,0 @@
package a
class MyClass {
open class MyNested
}
@@ -1,3 +1,13 @@
// FILE: A.kt
package a
class MyClass {
open class MyNested
}
// FILE: B.kt
package b
import a.MyClass.MyNested
@@ -1,4 +1,18 @@
FILE: simpleImportNested.kt
FILE: A.kt
public final class MyClass : R|kotlin/Any| {
public constructor(): R|a/MyClass| {
super<R|kotlin/Any|>()
}
public open class MyNested : R|kotlin/Any| {
public constructor(): R|a/MyClass.MyNested| {
super<R|kotlin/Any|>()
}
}
}
FILE: B.kt
public final class YourClass : R|a/MyClass.MyNested| {
public constructor(): R|b/YourClass| {
super<R|a/MyClass.MyNested|>()
@@ -1,5 +0,0 @@
package a
class Outer {
open class Nested
}
@@ -1,3 +1,13 @@
// FILE: A.kt
package a
class Outer {
open class Nested
}
// FILE: B.kt
package b
import a.Outer
@@ -1,4 +1,18 @@
FILE: simpleImportOuter.kt
FILE: A.kt
public final class Outer : R|kotlin/Any| {
public constructor(): R|a/Outer| {
super<R|kotlin/Any|>()
}
public open class Nested : R|kotlin/Any| {
public constructor(): R|a/Outer.Nested| {
super<R|kotlin/Any|>()
}
}
}
FILE: B.kt
public final class My : R|a/Outer.Nested| {
public constructor(): R|b/My| {
super<R|a/Outer.Nested|>()
@@ -1,7 +0,0 @@
package b.d
expect interface Other
expect class Another
fun baz() {}
@@ -1,3 +1,15 @@
// FILE: B.kt
package b.d
expect interface Other
expect class Another
fun baz() {}
// FILE: A.kt
package a.d
import b.d.*
@@ -1,4 +1,15 @@
FILE: simpleStarImport.kt
FILE: B.kt
public abstract expect interface Other : R|kotlin/Any| {
}
public final expect class Another : R|kotlin/Any| {
public constructor(): R|b/d/Another| {
super<R|kotlin/Any|>()
}
}
public final fun baz(): R|kotlin/Unit| {
}
FILE: A.kt
public final fun foo(arg: R|b/d/Other|): R|b/d/Another|
public final fun bar(): R|kotlin/Unit| {
R|b/d/baz|()
@@ -38,10 +38,10 @@ abstract class AbstractFirCfgBuildingTest : AbstractFirResolveTestCase() {
override val configurationKind: ConfigurationKind
get() = ConfigurationKind.ALL
override fun doTest(path: String) {
val firFiles = processInputFile(path)
checkFir(path, firFiles)
override fun doTest(path: String): List<FirFile> {
val firFiles = super.doTest(path)
checkCfg(path, firFiles)
return firFiles
}
fun checkCfg(path: String, firFiles: List<FirFile>) {
@@ -62,38 +62,18 @@ abstract class AbstractFirResolveTestCase : AbstractFirResolveWithSessionTestCas
}
}
protected fun generateKtFiles(path: String): List<KtFile> {
val file = File(path)
val allFiles = listOf(file) + file.parentFile.listFiles { sibling ->
sibling.name.removePrefix(file.nameWithoutExtension).removeSuffix(file.extension).matches("\\.[0-9]+\\.".toRegex())
}
return allFiles.map {
val text = KotlinTestUtils.doLoadFile(it)
it.name to text
}.sortedBy { (_, text) ->
KotlinTestUtils.parseDirectives(text)["analyzePriority"]?.toInt()
}.map { (name, text) ->
KotlinTestUtils.createFile(name, text, project)
}
}
protected fun processInputFile(path: String): List<FirFile> {
return doCreateAndProcessFir(generateKtFiles(path))
}
open fun doTest(path: String) {
open fun doTest(path: String): List<FirFile> {
val file = File(path)
val expectedText = KotlinTestUtils.doLoadFile(file)
val testFiles = createTestFiles(file, expectedText)
val firFiles = doCreateAndProcessFir(testFiles.mapNotNull { it.ktFile })
checkDiagnostics(file, testFiles, firFiles)
checkFir(path, firFiles)
return firFiles
}
fun checkFir(path: String, firFiles: List<FirFile>) {
val firFileDump = StringBuilder().also { firFiles.first().accept(FirRenderer(it), null) }.toString()
val firFileDump = StringBuilder().apply { firFiles.forEach { it.accept(FirRenderer(this), null) } }.toString()
val expectedPath = path.replace(".kt", ".txt")
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
}