[LL API] Add tests for FIR tree guards
^KT-59297 Fixed
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
// WITH_STDLIB
|
||||||
|
|
||||||
|
import broken.lib.Foo
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
buildList {
|
||||||
|
add(1)
|
||||||
|
add(Foo("foo", 1).result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> consume(a: T) {}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// WITH_STDLIB
|
||||||
|
|
||||||
|
import broken.lib.Foo
|
||||||
|
|
||||||
|
val x by lazy { Foo("foo", 1).result }
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_STDLIB
|
||||||
|
|
||||||
|
import broken.lib.Foo
|
||||||
|
|
||||||
|
val x = run {
|
||||||
|
Foo("foo", 1).result
|
||||||
|
}
|
||||||
+179
@@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.low.level.api.fir.resolve
|
||||||
|
|
||||||
|
import com.intellij.lang.java.JavaLanguage
|
||||||
|
import com.intellij.mock.MockApplication
|
||||||
|
import com.intellij.mock.MockProject
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.impl.file.PsiPackageImpl
|
||||||
|
import com.intellij.psi.impl.light.LightMethodBuilder
|
||||||
|
import com.intellij.psi.impl.light.LightModifierList
|
||||||
|
import com.intellij.psi.impl.light.LightPsiClassBase
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.search.PsiSearchScopeUtil
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolveWithClearCaches
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AbstractLowLevelApiSingleFileTest
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator
|
||||||
|
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||||
|
import org.jetbrains.kotlin.test.impl.testConfiguration
|
||||||
|
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||||
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
|
abstract class AbstractErrorResistanceTest : AbstractLowLevelApiSingleFileTest() {
|
||||||
|
override val configurator: AnalysisApiFirSourceTestConfigurator = ErrorResistanceConfigurator
|
||||||
|
|
||||||
|
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
|
||||||
|
resolveWithClearCaches(ktFile) { firResolveSession ->
|
||||||
|
ENABLE_INTERRUPTION.set(true)
|
||||||
|
|
||||||
|
try {
|
||||||
|
ktFile.collectDiagnosticsForFile(firResolveSession, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
|
||||||
|
fail("Analysis should be interrupted")
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
val errors = generateSequence(e) { it.cause }
|
||||||
|
if (errors.none { it is AnalysisInterruptedException }) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ENABLE_INTERRUPTION.set(false)
|
||||||
|
|
||||||
|
val diagnostics = ktFile.collectDiagnosticsForFile(firResolveSession, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
|
||||||
|
assert(diagnostics.isEmpty()) {
|
||||||
|
val messages = diagnostics.map { it.factoryName }
|
||||||
|
"There should be no diagnostics, found:\n" + messages.joinToString("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object ErrorResistanceConfigurator : AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false) {
|
||||||
|
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar>
|
||||||
|
get() = buildList {
|
||||||
|
addAll(super.serviceRegistrars)
|
||||||
|
add(ErrorResistanceServiceRegistrar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object ErrorResistanceServiceRegistrar : AnalysisApiTestServiceRegistrar() {
|
||||||
|
override fun registerApplicationServices(application: MockApplication, testServices: TestServices) {}
|
||||||
|
override fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) {}
|
||||||
|
override fun registerProjectServices(project: MockProject, testServices: TestServices) {}
|
||||||
|
|
||||||
|
@OptIn(TestInfrastructureInternals::class)
|
||||||
|
override fun registerProjectModelServices(project: MockProject, testServices: TestServices) {
|
||||||
|
with(PsiElementFinder.EP.getPoint(project)) {
|
||||||
|
registerExtension(BrokenLibraryElementFinder(project), testServices.testConfiguration.rootDisposable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AnalysisInterruptedException : RuntimeException()
|
||||||
|
|
||||||
|
private var ENABLE_INTERRUPTION = ThreadLocal.withInitial { false }
|
||||||
|
|
||||||
|
private fun interruptAnalysis() {
|
||||||
|
if (ENABLE_INTERRUPTION.get()) {
|
||||||
|
throw AnalysisInterruptedException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BrokenLibraryElementFinder(project: Project) : PsiElementFinder() {
|
||||||
|
private val manager = PsiManager.getInstance(project)
|
||||||
|
private val brokenPackage = BrokenPackage("broken.lib", manager)
|
||||||
|
private val brokenClass = BrokenClass(brokenPackage.qualifiedName, "Foo", manager)
|
||||||
|
|
||||||
|
override fun findPackage(qualifiedName: String): PsiPackage? {
|
||||||
|
return when (qualifiedName) {
|
||||||
|
brokenPackage.qualifiedName -> brokenPackage
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findClass(qualifiedName: String, scope: GlobalSearchScope): PsiClass? {
|
||||||
|
val klass = when (qualifiedName) {
|
||||||
|
brokenClass.qualifiedName -> brokenClass
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
return klass?.takeIf { PsiSearchScopeUtil.isInScope(scope, it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun findClasses(qualifiedName: String, scope: GlobalSearchScope): Array<PsiClass> {
|
||||||
|
val klass = findClass(qualifiedName, scope) ?: return PsiClass.EMPTY_ARRAY
|
||||||
|
return arrayOf(klass)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BrokenPackage(packageName: String, manager: PsiManager) : PsiPackageImpl(manager, packageName) {
|
||||||
|
override fun isValid(): Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BrokenClass(
|
||||||
|
private val packageName: String,
|
||||||
|
name: String,
|
||||||
|
manager: PsiManager
|
||||||
|
) : LightPsiClassBase(manager, JavaLanguage.INSTANCE, name) {
|
||||||
|
private val modifierList: PsiModifierList = LightModifierList(manager, JavaLanguage.INSTANCE, PsiModifier.PUBLIC)
|
||||||
|
private val methods: Array<PsiMethod> = arrayOf(ConstructorMethod(this), GetterMethod(this))
|
||||||
|
|
||||||
|
override fun getQualifiedName(): String = "$packageName.$name"
|
||||||
|
override fun getModifierList(): PsiModifierList = modifierList
|
||||||
|
override fun getContainingClass(): PsiClass? = null
|
||||||
|
override fun getTypeParameterList(): PsiTypeParameterList? = null
|
||||||
|
|
||||||
|
override fun getMethods(): Array<PsiMethod> {
|
||||||
|
return methods
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFields(): Array<PsiField> {
|
||||||
|
return PsiField.EMPTY_ARRAY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInnerClasses(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
|
||||||
|
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
|
||||||
|
|
||||||
|
override fun getExtendsList(): PsiReferenceList? = null
|
||||||
|
override fun getImplementsList(): PsiReferenceList? = null
|
||||||
|
|
||||||
|
override fun getScope(): PsiElement? = null
|
||||||
|
|
||||||
|
private class ConstructorMethod(owner: PsiClass) : LightMethodBuilder(owner, JavaLanguage.INSTANCE) {
|
||||||
|
init {
|
||||||
|
isConstructor = true
|
||||||
|
setModifiers(PsiModifier.PUBLIC)
|
||||||
|
|
||||||
|
val projectScope = GlobalSearchScope.allScope(manager.project)
|
||||||
|
addParameter("first", PsiType.getJavaLangString(manager, projectScope))
|
||||||
|
addParameter("second", PsiType.INT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GetterMethod(owner: PsiClass) : LightMethodBuilder(owner.manager, "getResult") {
|
||||||
|
init {
|
||||||
|
containingClass = owner
|
||||||
|
setModifiers(PsiModifier.PUBLIC)
|
||||||
|
setMethodReturnType(PsiType.BOOLEAN)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTypeParameterList(): PsiTypeParameterList? {
|
||||||
|
interruptAnalysis()
|
||||||
|
return super.getTypeParameterList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTypeParameters(): Array<PsiTypeParameter> {
|
||||||
|
interruptAnalysis()
|
||||||
|
return super.getTypeParameters()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.low.level.api.fir.resolve;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.TestDataPath;
|
||||||
|
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||||
|
import org.jetbrains.kotlin.test.TestMetadata;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("analysis/low-level-api-fir/testdata/errorResistance")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class ErrorResistanceTestGenerated extends AbstractErrorResistanceTest {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInErrorResistance() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/errorResistance"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("builderInference.kt")
|
||||||
|
public void testBuilderInference() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/errorResistance/builderInference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("propertyDelegate.kt")
|
||||||
|
public void testPropertyDelegate() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/errorResistance/propertyDelegate.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("propertyInitializer.kt")
|
||||||
|
public void testPropertyInitializer() throws Exception {
|
||||||
|
runTest("analysis/low-level-api-fir/testdata/errorResistance/propertyInitializer.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
+237
@@ -0,0 +1,237 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.analysis.low.level.api.fir.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.StateKeeper
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.entity
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.entityList
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.stateKeeper
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class StateKeeperTest {
|
||||||
|
@Test
|
||||||
|
fun testSimple() {
|
||||||
|
class Foo(private var value: String) {
|
||||||
|
fun getValue() = value
|
||||||
|
fun setValue(newValue: String) {
|
||||||
|
value = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val keeper: StateKeeper<Foo> = stateKeeper {
|
||||||
|
add(Foo::getValue, Foo::setValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
val foo = Foo("Foo")
|
||||||
|
|
||||||
|
keeper.withRestoration(foo) {
|
||||||
|
assertEquals("Foo", foo.getValue())
|
||||||
|
foo.setValue("Bar")
|
||||||
|
assertEquals("Bar", foo.getValue())
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Foo", foo.getValue())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testProperty() {
|
||||||
|
class Foo(var value: String)
|
||||||
|
|
||||||
|
val keeper: StateKeeper<Foo> = stateKeeper {
|
||||||
|
add(Foo::value::get, Foo::value::set)
|
||||||
|
}
|
||||||
|
|
||||||
|
val foo = Foo("Foo")
|
||||||
|
|
||||||
|
keeper.withRestoration(foo) {
|
||||||
|
assertEquals("Foo", foo.value)
|
||||||
|
foo.value = "Bar"
|
||||||
|
assertEquals("Bar", foo.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Foo", foo.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testArranger() {
|
||||||
|
class Foo(var value: String)
|
||||||
|
|
||||||
|
val keeper: StateKeeper<Foo> = stateKeeper {
|
||||||
|
add(Foo::value::get, Foo::value::set) { "Baz" }
|
||||||
|
}
|
||||||
|
|
||||||
|
val foo = Foo("Foo")
|
||||||
|
|
||||||
|
keeper.withRestoration(foo) {
|
||||||
|
assertEquals("Baz", foo.value)
|
||||||
|
foo.value = "Bar"
|
||||||
|
assertEquals("Bar", foo.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Foo", foo.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testInclusion() {
|
||||||
|
open class Foo(var one: String)
|
||||||
|
class Bar(one: String, var two: Int) : Foo(one)
|
||||||
|
|
||||||
|
val fooKeeper: StateKeeper<Foo> = stateKeeper {
|
||||||
|
add(Foo::one::get, Foo::one::set)
|
||||||
|
}
|
||||||
|
|
||||||
|
val barKeeper: StateKeeper<Bar> = stateKeeper {
|
||||||
|
add(fooKeeper)
|
||||||
|
add(Bar::two::get, Bar::two::set)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bar = Bar("Foo", 1)
|
||||||
|
|
||||||
|
barKeeper.withRestoration(bar) {
|
||||||
|
assertEquals("Foo", bar.one)
|
||||||
|
assertEquals(1, bar.two)
|
||||||
|
bar.one = "Bar"
|
||||||
|
bar.two = 2
|
||||||
|
assertEquals("Bar", bar.one)
|
||||||
|
assertEquals(2, bar.two)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Foo", bar.one)
|
||||||
|
assertEquals(1, bar.two)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testEntity() {
|
||||||
|
data class Foo(var value: Int)
|
||||||
|
class Bar(var one: String, var foo: Foo)
|
||||||
|
|
||||||
|
val barKeeper: StateKeeper<Bar> = stateKeeper { bar ->
|
||||||
|
add(Bar::one::get, Bar::one::set)
|
||||||
|
entity(bar.foo) {
|
||||||
|
add(Foo::value::get, Foo::value::set)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val foo = Foo(1)
|
||||||
|
val bar = Bar("Foo", foo)
|
||||||
|
|
||||||
|
barKeeper.withRestoration(bar) {
|
||||||
|
assertEquals("Foo", bar.one)
|
||||||
|
assertEquals(1, bar.foo.value)
|
||||||
|
|
||||||
|
bar.one = "Bar"
|
||||||
|
bar.foo.value = 2
|
||||||
|
|
||||||
|
assertEquals("Bar", bar.one)
|
||||||
|
assertEquals(2, bar.foo.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Foo", bar.one)
|
||||||
|
assertEquals(1, bar.foo.value)
|
||||||
|
assert(bar.foo === foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testEntityInclusion() {
|
||||||
|
data class Foo(var value: Int)
|
||||||
|
class Bar(var one: String, var foo: Foo)
|
||||||
|
|
||||||
|
val fooKeeper: StateKeeper<Foo> = stateKeeper {
|
||||||
|
add(Foo::value::get, Foo::value::set)
|
||||||
|
}
|
||||||
|
|
||||||
|
val barKeeper: StateKeeper<Bar> = stateKeeper { bar ->
|
||||||
|
add(Bar::one::get, Bar::one::set)
|
||||||
|
entity(bar.foo, fooKeeper)
|
||||||
|
}
|
||||||
|
|
||||||
|
val foo = Foo(1)
|
||||||
|
val bar = Bar("Foo", foo)
|
||||||
|
|
||||||
|
barKeeper.withRestoration(bar) {
|
||||||
|
assertEquals("Foo", bar.one)
|
||||||
|
assertEquals(1, bar.foo.value)
|
||||||
|
|
||||||
|
bar.one = "Bar"
|
||||||
|
bar.foo.value = 2
|
||||||
|
|
||||||
|
assertEquals("Bar", bar.one)
|
||||||
|
assertEquals(2, bar.foo.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Foo", bar.one)
|
||||||
|
assertEquals(1, bar.foo.value)
|
||||||
|
assert(bar.foo === foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testEntityList() {
|
||||||
|
data class Foo(var value: Int)
|
||||||
|
class Bar(var one: String, var foos: List<Foo>)
|
||||||
|
|
||||||
|
val barKeeper: StateKeeper<Bar> = stateKeeper { bar ->
|
||||||
|
add(Bar::one::get, Bar::one::set)
|
||||||
|
entityList(bar.foos) {
|
||||||
|
add(Foo::value::get, Foo::value::set) { it + 1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val foo0 = Foo(1)
|
||||||
|
val foo1 = Foo(2)
|
||||||
|
val bar = Bar("Foo", listOf(foo0, foo1))
|
||||||
|
|
||||||
|
barKeeper.withRestoration(bar) {
|
||||||
|
assertEquals("Foo", bar.one)
|
||||||
|
assertEquals(2, bar.foos[0].value) // +1 because of the arranger
|
||||||
|
assertEquals(3, bar.foos[1].value)
|
||||||
|
|
||||||
|
bar.one = "Bar"
|
||||||
|
bar.foos[0].value = 100
|
||||||
|
bar.foos[1].value = 200
|
||||||
|
|
||||||
|
assertEquals("Bar", bar.one)
|
||||||
|
assertEquals(100, bar.foos[0].value)
|
||||||
|
assertEquals(200, bar.foos[1].value)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Foo", bar.one)
|
||||||
|
assertEquals(1, bar.foos[0].value)
|
||||||
|
assertEquals(2, bar.foos[1].value)
|
||||||
|
assert(bar.foos[0] === foo0)
|
||||||
|
assert(bar.foos[1] === foo1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testPostProcess() {
|
||||||
|
class Foo(var value: String)
|
||||||
|
|
||||||
|
val keeper: StateKeeper<Foo> = stateKeeper { foo ->
|
||||||
|
add(Foo::value::get, Foo::value::set) { "Baz" }
|
||||||
|
|
||||||
|
postProcess {
|
||||||
|
foo.value = "Boo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val foo = Foo("Foo")
|
||||||
|
|
||||||
|
keeper.withRestoration(foo) {
|
||||||
|
assertEquals("Boo", foo.value)
|
||||||
|
foo.value = "Bar"
|
||||||
|
assertEquals("Bar", foo.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("Foo", foo.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T : Any> StateKeeper<T>.withRestoration(owner: T, block: () -> Unit) {
|
||||||
|
val state = prepare(owner)
|
||||||
|
state.postProcess()
|
||||||
|
block()
|
||||||
|
state.restore()
|
||||||
|
}
|
||||||
+1
-1
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtModuleFa
|
|||||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtSourceModuleFactory
|
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtSourceModuleFactory
|
||||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||||
|
|
||||||
class AnalysisApiFirSourceTestConfigurator(
|
open class AnalysisApiFirSourceTestConfigurator(
|
||||||
analyseInDependentSession: Boolean
|
analyseInDependentSession: Boolean
|
||||||
) : AnalysisApiFirSourceLikeTestConfigurator(analyseInDependentSession) {
|
) : AnalysisApiFirSourceLikeTestConfigurator(analyseInDependentSession) {
|
||||||
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
|
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
|
||||||
|
|||||||
+5
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostic.compiler.based
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostic.compiler.based.AbstractLLFirPreresolvedReversedDiagnosticCompilerTestDataTest
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostic.compiler.based.AbstractLLFirPreresolvedReversedDiagnosticCompilerTestDataTest
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.AbstractOutOfContentRootFileStructureTest
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.AbstractOutOfContentRootFileStructureTest
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.AbstractSourceFileStructureTest
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.AbstractSourceFileStructureTest
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.AbstractErrorResistanceTest
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.AbstractOutOfContentRootInnerDeclarationsResolvePhaseTest
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.AbstractOutOfContentRootInnerDeclarationsResolvePhaseTest
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.AbstractSourceInnerDeclarationsResolvePhaseTest
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.AbstractSourceInnerDeclarationsResolvePhaseTest
|
||||||
import org.jetbrains.kotlin.generators.TestGroup
|
import org.jetbrains.kotlin.generators.TestGroup
|
||||||
@@ -52,6 +53,10 @@ internal fun TestGroupSuite.generateFirLowLevelApiTests() {
|
|||||||
model("lazyResolve")
|
model("lazyResolve")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractErrorResistanceTest> {
|
||||||
|
model("errorResistance")
|
||||||
|
}
|
||||||
|
|
||||||
testClass<AbstractSourceFileStructureTest> {
|
testClass<AbstractSourceFileStructureTest> {
|
||||||
model("fileStructure")
|
model("fileStructure")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user