[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:
+1
-1
@@ -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 }
|
||||
|
||||
+28
-1
@@ -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))
|
||||
|
||||
+1
-3
@@ -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) {
|
||||
|
||||
-1
@@ -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 +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)
|
||||
}
|
||||
|
||||
+1
-1
@@ -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|
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
class FooBar {
|
||||
fun <T> functionWithTAndAnyValue(otherVal: T & Any) {}
|
||||
}
|
||||
Vendored
+8
@@ -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|
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtConstructor
|
||||
class FooBar {
|
||||
val p: String
|
||||
|
||||
constructor(p: String) {
|
||||
this.p = p
|
||||
}
|
||||
|
||||
fun doSmth() {}
|
||||
}
|
||||
+8
@@ -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|
|
||||
+21
-15
@@ -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() {
|
||||
|
||||
+73
@@ -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")
|
||||
}
|
||||
}
|
||||
+41
@@ -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))
|
||||
}
|
||||
}
|
||||
+80
@@ -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");
|
||||
}
|
||||
}
|
||||
+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;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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
|
||||
+1
-1
@@ -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
|
||||
|
||||
+8
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user