[LL] add tests for FirDeclarationForCompiledElementSearcher

build stub if was not able to load:
expected that in IDE stubs would always be found in the index, for tests -
build from virtual file
This commit is contained in:
Anna Kozlova
2023-06-07 14:56:21 +02:00
committed by teamcity
parent bc306844af
commit 4d97e4c572
39 changed files with 473 additions and 25 deletions
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.analysis.api.fir.test.configurators
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.library.AnalysisApiFirLibraryBinaryTestConfigurator
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirLibraryBinaryTestConfigurator
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.library.AnalysisApiFirLibrarySourceTestConfigurator
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.*
@@ -24,6 +24,7 @@ dependencies {
testImplementation(project(":analysis:symbol-light-classes"))
testImplementation(projectTests(":analysis:decompiled:decompiler-to-file-stubs"))
testImplementation(project(":analysis:decompiled:decompiler-to-file-stubs"))
testImplementation(project(":analysis:decompiled:light-classes-for-decompiled"))
testImplementation(project(":analysis:decompiled:decompiler-to-psi"))
testImplementation(projectTests(":analysis:analysis-test-framework"))
testImplementation(commonDependency("org.jetbrains.kotlin:kotlin-reflect")) { isTransitive = false }
@@ -7,11 +7,16 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.configurators
import com.intellij.mock.MockApplication
import com.intellij.mock.MockProject
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiClass
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.lifetime.KtDefaultLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.lifetime.KtReadActionConfinementDefaultLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory
import org.jetbrains.kotlin.analysis.decompiled.light.classes.ClsJavaStubByVirtualFileCache
import org.jetbrains.kotlin.analysis.decompiled.light.classes.DecompiledLightClassesFactory
import org.jetbrains.kotlin.analysis.decompiler.psi.BuiltInDefinitionFile
import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtClsFile
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProvider
import org.jetbrains.kotlin.analysis.project.structure.KtModuleScopeProviderImpl
import org.jetbrains.kotlin.analysis.providers.*
@@ -19,7 +24,9 @@ import org.jetbrains.kotlin.analysis.providers.impl.*
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
import org.jetbrains.kotlin.analysis.test.framework.services.environmentManager
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtFileClassProvider
import org.jetbrains.kotlin.test.services.TestServices
object AnalysisApiBaseTestServiceRegistrar: AnalysisApiTestServiceRegistrar() {
@@ -30,6 +37,26 @@ object AnalysisApiBaseTestServiceRegistrar: AnalysisApiTestServiceRegistrar() {
project.apply {
registerService(KotlinModificationTrackerFactory::class.java, KotlinStaticModificationTrackerFactory::class.java)
registerService(KtDefaultLifetimeTokenProvider::class.java, KtReadActionConfinementDefaultLifetimeTokenProvider::class.java)
//KotlinClassFileDecompiler is registered as application service so it's available for the tests run in parallel as well
//when the decompiler is registered, for compiled class KtClsFile is created instead of ClsFileImpl
//and KtFile doesn't return any classes in classOwner.getClasses if there is no KtFileClassProvider
//but getClasses is used during java resolve, thus it's required to return some PsiClass for such cases
registerService(KtFileClassProvider::class.java, KtClsFileClassProvider(project))
registerService(ClsJavaStubByVirtualFileCache::class.java, ClsJavaStubByVirtualFileCache())
}
}
class KtClsFileClassProvider(val project: Project) : KtFileClassProvider {
override fun getFileClasses(file: KtFile): Array<PsiClass> {
val virtualFile = file.virtualFile
val classOrObject = file.declarations.filterIsInstance<KtClassOrObject>().singleOrNull()
if (file is KtClsFile && virtualFile != null) {
DecompiledLightClassesFactory.createClsJavaClassFromVirtualFile(file, virtualFile, classOrObject, project)?.let {
return arrayOf(it)
}
}
return PsiClass.EMPTY_ARRAY
}
}
@@ -39,7 +66,7 @@ object AnalysisApiBaseTestServiceRegistrar: AnalysisApiTestServiceRegistrar() {
val roots = StandaloneProjectFactory.getVirtualFilesForLibraryRoots(
moduleStructure.binaryModules.flatMap { binary -> binary.getBinaryRoots() },
testServices.environmentManager.getProjectEnvironment()
)
).distinct()
project.apply {
registerService(KtModuleScopeProvider::class.java, KtModuleScopeProviderImpl())
registerService(KotlinAnnotationsResolverFactory::class.java, KotlinStaticAnnotationsResolverFactory(allKtFiles))
@@ -14,13 +14,11 @@ import com.intellij.psi.FileTypeFileViewProviders
import com.intellij.psi.compiled.ClassFileDecompilers
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInDecompiler
import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinClassFileDecompiler
import org.jetbrains.kotlin.analysis.test.framework.services.disposableProvider
import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache
import org.jetbrains.kotlin.analysis.decompiler.stub.file.FileAttributeService
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
import org.jetbrains.kotlin.test.TestInfrastructureInternals
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.analysis.test.framework.services.disposableProvider
object AnalysisApiLibraryBaseTestServiceRegistrar : AnalysisApiTestServiceRegistrar() {
override fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) {
@@ -35,7 +35,6 @@ public object StandaloneModeTestServiceRegistrar : AnalysisApiTestServiceRegistr
?: emptyList()
val projectEnvironment = testServices.environmentManager.getProjectEnvironment()
project.apply {
registerService(ClsJavaStubByVirtualFileCache::class.java, ClsJavaStubByVirtualFileCache())
registerService(
KotlinPsiDeclarationProviderFactory::class.java,
KotlinStaticPsiDeclarationProviderFactory(
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionCache
@@ -24,6 +25,11 @@ class LLFirResolveSessionService(project: Project) {
return create(module, cache::getSession)
}
@TestOnly
fun getFirResolveSessionForBinaryModule(module: KtModule): LLFirResolveSession {
return create(module) { cache.getSession(it, true) }
}
fun getFirResolveSessionNoCaching(module: KtModule): LLFirResolveSession {
return create(module, cache::getSessionNoCaching)
}
@@ -65,7 +65,7 @@ internal fun <S, T> loadStubByElement(ktElement: T): S? where T : StubBasedPsiEl
val virtualFile = PsiUtilCore.getVirtualFile(ktFile) ?: return null
var stubList = ktFile.getUserData(STUBS_KEY)?.get()
if (stubList == null) {
val stubTree = StubTreeLoader.getInstance().readFromVFile(ktElement.project, virtualFile)
val stubTree = StubTreeLoader.getInstance().readOrBuild(ktElement.project, virtualFile, null)
stubList = stubTree?.plainList ?: emptyList()
ktFile.putUserData(STUBS_KEY, WeakReference(stubList))
}
@@ -0,0 +1,4 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtEnumEntry
enum class FooBar {
Baz;
}
@@ -0,0 +1,8 @@
KT element: KtEnumEntry
KT element text:
Baz;
FIR element: FirEnumEntryImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final static [ResolvedTo(BODY_RESOLVE)] enum entry Baz: R|FooBar|
@@ -0,0 +1,4 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtNamedFunction
class FooBar {
fun <T> functionWithTAndAnyValue(otherVal: T & Any) {}
}
@@ -0,0 +1,8 @@
KT element: KtNamedFunction
KT element text:
public final fun <T> functionWithTAndAnyValue(otherVal: T & Any): kotlin.Unit { /* compiled code */ }
FIR element: FirSimpleFunctionImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final [ResolvedTo(BODY_RESOLVE)] fun <[ResolvedTo(BODY_RESOLVE)] T> functionWithTAndAnyValue([ResolvedTo(BODY_RESOLVE)] otherVal: R|T & Any|): R|kotlin/Unit|
@@ -0,0 +1,2 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtParameter
fun doSmth(p: String) {}
@@ -0,0 +1,8 @@
KT element: KtParameter
KT element text:
p: kotlin.String
FIR element: FirValueParameterImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
[ResolvedTo(BODY_RESOLVE)] p: R|kotlin/String|
@@ -0,0 +1,10 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtConstructor
class FooBar {
val p: String
constructor(p: String) {
this.p = p
}
fun doSmth() {}
}
@@ -0,0 +1,8 @@
KT element: KtSecondaryConstructor
KT element text:
public constructor(p: kotlin.String) { /* compiled code */ }
FIR element: FirConstructorImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public [ResolvedTo(BODY_RESOLVE)] constructor([ResolvedTo(BODY_RESOLVE)] p: R|kotlin/String|): R|FooBar|
@@ -0,0 +1,4 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtClass
class FooBar {
fun doSmth() {}
}
@@ -0,0 +1,15 @@
KT element: KtClass
KT element text:
public final class FooBar public constructor() {
public final fun doSmth(): kotlin.Unit { /* compiled code */ }
}
FIR element: FirRegularClassImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final [ResolvedTo(BODY_RESOLVE)] class FooBar : R|kotlin/Any| {
public final [ResolvedTo(BODY_RESOLVE)] fun doSmth(): R|kotlin/Unit|
public [ResolvedTo(BODY_RESOLVE)] constructor(): R|FooBar|
}
@@ -0,0 +1,4 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtConstructor
class FooBar(val p: String) {
fun doSmth() {}
}
@@ -0,0 +1,8 @@
KT element: KtPrimaryConstructor
KT element text:
public constructor(p: kotlin.String)
FIR element: FirPrimaryConstructor
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public [ResolvedTo(BODY_RESOLVE)] constructor([ResolvedTo(BODY_RESOLVE)] p: R|kotlin/String|): R|FooBar|
@@ -0,0 +1,4 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtNamedFunction
object FooBar {
fun doSmth() {}
}
@@ -0,0 +1,8 @@
KT element: KtNamedFunction
KT element text:
public final fun doSmth(): kotlin.Unit { /* compiled code */ }
FIR element: FirSimpleFunctionImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final [ResolvedTo(BODY_RESOLVE)] fun doSmth(): R|kotlin/Unit|
@@ -0,0 +1,10 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtProperty
class FooBar {
val p: String
constructor(p: String) {
this.p = p
}
fun doSmth() {}
}
@@ -0,0 +1,8 @@
KT element: KtProperty
KT element text:
public final val p: kotlin.String /* compiled code */
FIR element: FirPropertyImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final [ResolvedTo(BODY_RESOLVE)] val p: R|kotlin/String|
@@ -0,0 +1,2 @@
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtNamedFunction
fun doSmth() {}
@@ -0,0 +1,8 @@
KT element: KtNamedFunction
KT element text:
public fun doSmth(): kotlin.Unit { /* compiled code */ }
FIR element: FirSimpleFunctionImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final [ResolvedTo(BODY_RESOLVE)] fun doSmth(): R|kotlin/Unit|
@@ -0,0 +1,8 @@
/*
* 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.
*/
// WITH_STDLIB
val d = empty<caret>Array<String>()
@@ -0,0 +1,6 @@
KT element: KtNamedFunction
FIR element: FirSimpleFunctionImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final inline [ResolvedTo(BODY_RESOLVE)] fun <@R|kotlin/internal/PureReifiable|() reified [ResolvedTo(BODY_RESOLVE)] T> emptyArray(): R|kotlin/Array<T>|
@@ -0,0 +1,8 @@
/*
* 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.
*/
// WITH_STDLIB
val d = arrayOf(arrayOf("1", "2")).fla<caret>tten()
@@ -0,0 +1,6 @@
KT element: KtNamedFunction
FIR element: FirSimpleFunctionImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
public final [ResolvedTo(BODY_RESOLVE)] fun <[ResolvedTo(BODY_RESOLVE)] T> R|kotlin/Array<out kotlin/Array<out T>>|.flatten(): R|kotlin/collections/List<T>|
@@ -0,0 +1,8 @@
/*
* 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.
*/
// WITH_STDLIB
val d = Double.from<caret>Bits(0x400921fb54442d18L)
@@ -0,0 +1,6 @@
KT element: KtNamedFunction
FIR element: FirSimpleFunctionImpl
FIR source kind: KtRealSourceElementKind
FIR element rendered:
@R|kotlin/SinceKotlin|(version = String(1.2)) @R|kotlin/internal/InlineOnly|() public final inline [ResolvedTo(BODY_RESOLVE)] fun @RECEIVER:R|kotlin/SinceKotlin|(version = String(1.2)) @RECEIVER:R|kotlin/internal/InlineOnly|() R|kotlin/Double.Companion|.fromBits([ResolvedTo(BODY_RESOLVE)] bits: R|kotlin/Long|): R|kotlin/Double|
@@ -18,6 +18,9 @@ import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.renderer.FirResolvePhaseRenderer
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
@@ -28,27 +31,30 @@ abstract class AbstractGetOrBuildFirTest : AbstractLowLevelApiSingleFileTest() {
val module = moduleStructure.modules.single()
val selectedElement = testServices.expressionMarkerProvider.getSelectedElementOfTypeByDirective(ktFile, module) as KtElement
val actual = resolveWithClearCaches(ktFile) { state ->
val fir = selectedElement.getOrBuildFir(state)
"""|KT element: ${selectedElement::class.simpleName}
val actual = resolveWithClearCaches(ktFile) { session ->
renderActualFir(selectedElement.getOrBuildFir(session), selectedElement)
}
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
}
}
fun renderActualFir(fir: FirElement?, ktElement: KtElement, renderKtText: Boolean = false): String {
return """|KT element: ${ktElement::class.simpleName}${if (renderKtText) "\nKT element text:\n" + ktElement.text else ""}
|FIR element: ${fir?.let { it::class.simpleName }}
|FIR source kind: ${fir?.source?.kind?.let { it::class.simpleName }}
|
|FIR element rendered:
|${render(fir).trimEnd()}""".trimMargin()
}
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
}
}
private fun render(firElement: FirElement?): String = when (firElement) {
null -> "null"
is FirImport -> "import ${firElement.importedFqName}"
else -> FirRenderer(
fileAnnotationsContainerRenderer = FirFileAnnotationsContainerRenderer(),
packageDirectiveRenderer = FirPackageDirectiveRenderer(),
resolvePhaseRenderer = FirResolvePhaseRenderer(),
).renderElementAsString(firElement)
}
private fun render(firElement: FirElement?): String = when (firElement) {
null -> "null"
is FirImport -> "import ${firElement.importedFqName}"
else -> FirRenderer(
fileAnnotationsContainerRenderer = FirFileAnnotationsContainerRenderer(),
packageDirectiveRenderer = FirPackageDirectiveRenderer(),
resolvePhaseRenderer = FirResolvePhaseRenderer(),
).renderElementAsString(firElement)
}
abstract class AbstractSourceGetOrBuildFirTest : AbstractGetOrBuildFirTest() {
@@ -0,0 +1,73 @@
/*
* 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
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirLibraryBinaryTestConfigurator
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirDeclarationForCompiledElementSearcher
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompiledLibraryProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
import org.jetbrains.kotlin.test.services.service
abstract class AbstractLibraryGetOrBuildFirTest : AbstractLowLevelApiSingleFileTest() {
override val configurator = AnalysisApiFirLibraryBinaryTestConfigurator
override fun configureTest(builder: TestConfigurationBuilder) {
super.configureTest(builder)
with(builder) {
useDirectives(Directives)
useAdditionalServices(service(::CompiledLibraryProvider))
}
}
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
val declaration = getElementToSearch(ktFile, moduleStructure)
val module = ProjectStructureProvider.getModule(ktFile.project, ktFile, contextualModule = null)
val resolveSession = LLFirResolveSessionService.getInstance(ktFile.project).getFirResolveSessionForBinaryModule(module)
val symbolProvider = resolveSession.getSessionFor(module).symbolProvider
val fir = FirDeclarationForCompiledElementSearcher(symbolProvider).findNonLocalDeclaration(declaration)
testServices.assertions.assertEqualsToTestDataFileSibling(renderActualFir(fir, declaration, true))
}
private fun getElementToSearch(ktFile: KtFile, moduleStructure: TestModuleStructure): KtDeclaration {
val expectedType = moduleStructure.allDirectives[Directives.DECLARATION_TYPE].firstOrNull()
?: error("Compiled code should have element type specified")
@Suppress("UNCHECKED_CAST") val expectedClass = Class.forName(expectedType) as Class<PsiElement>
return findFirstDeclaration(ktFile.declarations, expectedClass)!!
}
private fun findFirstDeclaration(
declarations: List<KtDeclaration>,
expectedClass: Class<PsiElement>
): KtDeclaration? {
declarations.filterIsInstance(expectedClass).firstOrNull()?.let { return it as KtDeclaration }
declarations.forEach { decl ->
if (decl is KtDeclarationContainer) {
findFirstDeclaration(decl.declarations, expectedClass)?.let { return it }
}
if (decl is KtFunction) {
findFirstDeclaration(decl.valueParameters, expectedClass)?.let { return it }
}
if (decl is KtClass && expectedClass == KtConstructor::class.java) {
decl.primaryConstructor?.let { return it }
}
}
return null
}
private object Directives : SimpleDirectivesContainer() {
val DECLARATION_TYPE by stringDirective("DECLARATION_TYPE")
}
}
@@ -0,0 +1,41 @@
/*
* 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
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol
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.project.structure.ProjectStructureProvider
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
import org.jetbrains.kotlin.analysis.test.framework.utils.unwrapMultiReferences
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractStdLibBasedGetOrBuildFirTest : AbstractLowLevelApiSingleFileTest() {
override val configurator = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false)
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
val project = ktFile.project
assert(!project.isDisposed) { "$project is disposed" }
val caretPosition = testServices.expressionMarkerProvider.getCaretPosition(ktFile)
val ktReferences = ktFile.findReferenceAt(caretPosition)?.unwrapMultiReferences().orEmpty().filterIsInstance<KtReference>()
if (ktReferences.size != 1) {
testServices.assertions.fail { "No references at caret found" }
}
val declaration =
analyseForTest(ktReferences.first().element) {
ktReferences.first().resolveToSymbol()?.psi as KtDeclaration
}
val module = ProjectStructureProvider.getModule(project, ktFile, contextualModule = null)
val resolveSession = LLFirResolveSessionService.getInstance(project).getFirResolveSession(module)
val fir = declaration.resolveToFirSymbol(resolveSession).fir
testServices.assertions.assertEqualsToTestDataFileSibling(renderActualFir(fir, declaration))
}
}
@@ -0,0 +1,80 @@
/*
* 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;
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/getOrBuildFirBinary")
@TestDataPath("$PROJECT_ROOT")
public class LibraryGetOrBuildFirTestGenerated extends AbstractLibraryGetOrBuildFirTest {
@Test
public void testAllFilesPresentInGetOrBuildFirBinary() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/getOrBuildFirBinary"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("enumEntry.kt")
public void testEnumEntry() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/enumEntry.kt");
}
@Test
@TestMetadata("functionWithDefinitelyNotNullParameter.kt")
public void testFunctionWithDefinitelyNotNullParameter() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/functionWithDefinitelyNotNullParameter.kt");
}
@Test
@TestMetadata("parameter.kt")
public void testParameter() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/parameter.kt");
}
@Test
@TestMetadata("secondaryConstructor.kt")
public void testSecondaryConstructor() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/secondaryConstructor.kt");
}
@Test
@TestMetadata("simpleClass.kt")
public void testSimpleClass() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/simpleClass.kt");
}
@Test
@TestMetadata("simpleConstructor.kt")
public void testSimpleConstructor() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/simpleConstructor.kt");
}
@Test
@TestMetadata("simpleFunction.kt")
public void testSimpleFunction() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/simpleFunction.kt");
}
@Test
@TestMetadata("simpleProperty.kt")
public void testSimpleProperty() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/simpleProperty.kt");
}
@Test
@TestMetadata("topLevelFunction.kt")
public void testTopLevelFunction() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirBinary/topLevelFunction.kt");
}
}
@@ -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;
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/getOrBuildFirForStdLib")
@TestDataPath("$PROJECT_ROOT")
public class StdLibBasedGetOrBuildFirTestGenerated extends AbstractStdLibBasedGetOrBuildFirTest {
@Test
public void testAllFilesPresentInGetOrBuildFirForStdLib() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/getOrBuildFirForStdLib"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("emptyArray.kt")
public void testEmptyArray() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirForStdLib/emptyArray.kt");
}
@Test
@TestMetadata("flattenArray.kt")
public void testFlattenArray() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirForStdLib/flattenArray.kt");
}
@Test
@TestMetadata("fromBits.kt")
public void testFromBits() throws Exception {
runTest("analysis/low-level-api-fir/testdata/getOrBuildFirForStdLib/fromBits.kt");
}
}
@@ -1,9 +1,9 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.api.fir.test.configurators.library
package org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators
import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol.decompiled.test.configurators
import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.library.AnalysisApiFirLibraryBinaryTestConfigurator
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirLibraryBinaryTestConfigurator
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleProjectStructure
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
@@ -92,6 +92,14 @@ internal fun TestGroupSuite.generateFirLowLevelApiTests() {
model("getOrBuildFir")
}
testClass<AbstractLibraryGetOrBuildFirTest> {
model("getOrBuildFirBinary")
}
testClass<AbstractStdLibBasedGetOrBuildFirTest> {
model("getOrBuildFirForStdLib")
}
testClass<AbstractFileBasedKotlinDeclarationProviderTest> {
model("fileBasedDeclarationProvider", pattern = TestGeneratorUtil.KT_OR_KTS)
}