FIR IDE: migrate LL API test to the test infrastructure from HL API

This commit is contained in:
Ilya Kirillov
2021-06-21 15:51:55 +02:00
committed by TeamCityServer
parent c19792e7c5
commit c70629c22a
31 changed files with 246 additions and 281 deletions
@@ -9,29 +9,28 @@ import junit.framework.TestCase
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.builder.RawFirBuilderMode
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyBodiesCalculator
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
abstract class AbstractFirLazyBodiesCalculatorTest : FrontendApiSingleTestDataFileTest() {
abstract class AbstractFirLazyBodiesCalculatorTest : AbstractLowLevelApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
resolveWithClearCaches(ktFile) { resolveState ->
val session = resolveState.rootModuleSession
val provider = session.firIdeProvider.kotlinScopeProvider
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
val session = resolveState.rootModuleSession
val provider = session.firIdeProvider.kotlinScopeProvider
val laziedFirFile = RawFirBuilder(session, provider, RawFirBuilderMode.LAZY_BODIES).buildFirFile(ktFile)
FirLazyBodiesCalculator.calculateLazyBodies(laziedFirFile)
val fullFirFile = RawFirBuilder(session, provider, RawFirBuilderMode.NORMAL).buildFirFile(ktFile)
val laziedFirFile = RawFirBuilder(session, provider, RawFirBuilderMode.LAZY_BODIES).buildFirFile(ktFile)
FirLazyBodiesCalculator.calculateLazyBodies(laziedFirFile)
val fullFirFile = RawFirBuilder(session, provider, RawFirBuilderMode.NORMAL).buildFirFile(ktFile)
val laziedFirFileDump = StringBuilder().also { FirRenderer(it).visitFile(laziedFirFile) }.toString()
val fullFirFileDump = StringBuilder().also { FirRenderer(it).visitFile(fullFirFile) }.toString()
val laziedFirFileDump = StringBuilder().also { FirRenderer(it).visitFile(laziedFirFile) }.toString()
val fullFirFileDump = StringBuilder().also { FirRenderer(it).visitFile(fullFirFile) }.toString()
TestCase.assertEquals(laziedFirFileDump, fullFirFileDump)
TestCase.assertEquals(laziedFirFileDump, fullFirFileDump)
}
}
}
@@ -7,22 +7,19 @@ package org.jetbrains.kotlin.idea.fir.low.level.api
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.LowLevelFirApiFacadeForResolveOnAir
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtFileAnnotationList
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.util.findElementByCommentPrefix
abstract class AbstractFirOnAirResolveTest : FrontendApiSingleTestDataFileTest() {
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
abstract class AbstractFirOnAirResolveTest : AbstractLowLevelApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
fun fixUpAnnotations(element: KtElement): KtElement = when (element) {
is KtAnnotated -> element.annotationEntries.firstOrNull() ?: element
is KtFileAnnotationList -> element.annotationEntries.first()
@@ -34,9 +31,11 @@ abstract class AbstractFirOnAirResolveTest : FrontendApiSingleTestDataFileTest()
check(place::class == onAir::class)
check(resolveState is FirModuleResolveStateImpl)
val firElement = LowLevelFirApiFacadeForResolveOnAir.onAirResolveElement(resolveState, place, onAir)
val rendered = firElement.render(FirRenderer.RenderMode.WithResolvePhases)
KotlinTestUtils.assertEqualsToFile(testDataFileSibling(".txt"), rendered)
resolveWithClearCaches(ktFile) { resolveState ->
check(resolveState is FirModuleResolveStateImpl)
val firElement = LowLevelFirApiFacadeForResolveOnAir.onAirResolveElement(resolveState, place, onAir)
val rendered = firElement.render(FirRenderer.RenderMode.WithResolvePhases)
KotlinTestUtils.assertEqualsToFile(testDataFileSibling(".txt"), rendered)
}
}
}
@@ -16,21 +16,19 @@ import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.RawFirNonLocalDeclarationBuilder
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
import kotlin.io.path.readText
abstract class AbstractPartialRawFirBuilderTestCase : FrontendApiSingleTestDataFileTest() {
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
abstract class AbstractPartialRawFirBuilderTestCase : AbstractLowLevelApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
val fileText = testDataPath.readText()
val functionName = InTextDirectivesUtils.findStringWithPrefixes(fileText, FUNCTION_DIRECTIVE)
val propertyName = InTextDirectivesUtils.findStringWithPrefixes(fileText, PROPERTY_DIRECTIVE)
@@ -56,7 +56,7 @@ import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.nameWithoutExtension
abstract class FrontendApiTestWithTestdata : AbstractKotlinCompilerTest() {
abstract class AbstractCompilerBasedTest : AbstractKotlinCompilerTest() {
final override fun TestConfigurationBuilder.configuration() {
globalDefaults {
frontend = FrontendKinds.FIR
@@ -70,13 +70,6 @@ abstract class FrontendApiTestWithTestdata : AbstractKotlinCompilerTest() {
useFrontendFacades(::LowLevelFirFrontendFacade)
}
protected lateinit var testDataPath: Path
protected fun testDataFileSibling(extension: String): Path {
val extensionWithDot = "." + extension.removePrefix(".")
return testDataPath.resolveSibling(testDataPath.nameWithoutExtension + extensionWithDot)
}
open fun TestConfigurationBuilder.configureTest() {}
@@ -102,30 +95,22 @@ abstract class FrontendApiTestWithTestdata : AbstractKotlinCompilerTest() {
registerTestServices(configurator, ktFiles)
}
val resolveState = createResolveStateForNoCaching(moduleInfo, project) { configureSession() }
return getArtifact(module, testServices, ktFiles, resolveState)
?: FirOutputArtifactImpl(
resolveState.rootModuleSession,
emptyMap(),
FirAnalyzerFacade(resolveState.rootModuleSession, configurator.getLanguageVersionSettings(moduleInfo))
)
val resolveState = createResolveStateForNoCaching(moduleInfo, project)
val allFirFiles = ktFiles.map { (testFile, psiFile) ->
testFile to psiFile.getOrBuildFirFile(resolveState)
}.toMap()
val diagnosticCheckerFilter = if (FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS in module.directives) {
DiagnosticCheckerFilter.EXTENDED_AND_COMMON_CHECKERS
} else DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS
val analyzerFacade = LowLevelFirAnalyzerFacade(resolveState, allFirFiles, diagnosticCheckerFilter)
return LowLevelFirOutputArtifact(resolveState.rootModuleSession, analyzerFacade)
}
}
protected open fun FirIdeSession.configureSession() {}
protected abstract fun getArtifact(
module: TestModule,
testServices: TestServices,
ktFiles: Map<TestFile, KtFile>,
resolveState: FirModuleResolveState
): FirOutputArtifact?
override fun runTest(filePath: String) {
testDataPath = Paths.get(filePath)
val configuration = testConfiguration(filePath, configuration)
if (ignoreTest(filePath, configuration)) {
return
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2021 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.idea.fir.low.level.api.compiler.based
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.model.TestFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
import org.jetbrains.kotlin.test.services.getKtFilesForSourceFiles
import org.jetbrains.kotlin.test.services.sourceFileProvider
abstract class FrontendApiSingleTestDataFileTest : FrontendApiTestWithTestdata() {
final override fun getArtifact(
module: TestModule,
testServices: TestServices,
ktFiles: Map<TestFile, KtFile>,
resolveState: FirModuleResolveState
): FirOutputArtifact? {
val singleFile = ktFiles.values.single()
doTest(singleFile, module, resolveState, testServices)
return null
}
abstract fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices)
}
@@ -15,62 +15,62 @@ import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.collectDiagnosticsForFile
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFir
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.BeforeElementDiagnosticCollectionHandler
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.SingleNonLocalDeclarationDiagnosticRetriever
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.fir.PersistentCheckerContextFactory
import org.jetbrains.kotlin.idea.fir.low.level.api.renderWithClassName
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
import org.jetbrains.kotlin.idea.fir.low.level.api.resolveWithClearCaches
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
/**
* Check that every declaration is visited exactly one time during diagnostic collection
*/
abstract class AbstractDiagnosticTraversalCounterTest : FrontendApiSingleTestDataFileTest() {
private var handler: BeforeElementTestDiagnosticCollectionHandler? = null
abstract class AbstractDiagnosticTraversalCounterTest : AbstractLowLevelApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
val handler = BeforeElementTestDiagnosticCollectionHandler()
resolveWithClearCaches(
ktFile,
configureSession = {
@OptIn(SessionConfiguration::class)
register(BeforeElementDiagnosticCollectionHandler::class, handler)
}
) { resolveState ->
// we should get diagnostics before we resolve the whole file by ktFile.getOrBuildFir
ktFile.collectDiagnosticsForFile(resolveState, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
@OptIn(SessionConfiguration::class)
override fun FirIdeSession.configureSession() {
handler = BeforeElementTestDiagnosticCollectionHandler()
register(BeforeElementDiagnosticCollectionHandler::class, handler!!)
}
val firFile = ktFile.getOrBuildFir(resolveState)
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
// we should get diagnostics before we resolve the whole file by ktFile.getOrBuildFir
ktFile.collectDiagnosticsForFile(resolveState, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
val errorElements = collectErrorElements(firFile, handler)
val firFile = ktFile.getOrBuildFir(resolveState)
val errorElements = collectErrorElements(firFile, handler!!)
if (errorElements.isNotEmpty()) {
val zeroElements = errorElements.filter { it.second == 0 }
val nonZeroElements = errorElements.filter { it.second > 1 }
val message = buildString {
if (zeroElements.isNotEmpty()) {
appendLine(
""" |The following elements were not visited
if (errorElements.isNotEmpty()) {
val zeroElements = errorElements.filter { it.second == 0 }
val nonZeroElements = errorElements.filter { it.second > 1 }
val message = buildString {
if (zeroElements.isNotEmpty()) {
appendLine(
""" |The following elements were not visited
|${zeroElements.joinToString(separator = "\n\n") { it.first.source?.kind.toString() + " <> " + it.first.renderWithClassName() }}
""".trimMargin()
)
}
if (nonZeroElements.isNotEmpty()) {
appendLine(
""" |The following elements were visited more than one time
)
}
if (nonZeroElements.isNotEmpty()) {
appendLine(
""" |The following elements were visited more than one time
|${nonZeroElements.joinToString(separator = "\n\n") { it.second.toString() + " times " + it.first.source?.kind.toString() + " <> " + it.first.renderWithClassName() }}
""".trimMargin()
)
)
}
}
testServices.assertions.fail { message }
}
testServices.assertions.fail { message }
}
handler = null
}
private fun collectErrorElements(
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getDiagnostics
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirFile
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.BeforeElementDiagnosticCollectionHandler
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.fir.PersistenceContextCollector
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureElement
@@ -25,32 +24,37 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.NonReanalyzabl
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.ReanalyzableStructureElement
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.RootStructureElement
import org.jetbrains.kotlin.idea.fir.low.level.api.name
import org.jetbrains.kotlin.idea.fir.low.level.api.resolveWithClearCaches
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.AssertionsService
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractFirContextCollectionTest : FrontendApiSingleTestDataFileTest() {
private var handler: BeforeElementTestDiagnosticCollectionHandler? = null
@OptIn(SessionConfiguration::class)
override fun FirIdeSession.configureSession() {
handler = BeforeElementTestDiagnosticCollectionHandler()
register(BeforeElementDiagnosticCollectionHandler::class, handler!!)
}
abstract class AbstractFirContextCollectionTest : AbstractLowLevelApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
val handler = BeforeElementTestDiagnosticCollectionHandler(testServices.assertions)
resolveWithClearCaches(
ktFile,
configureSession = {
@OptIn(SessionConfiguration::class)
register(BeforeElementDiagnosticCollectionHandler::class, handler)
}
) { resolveState ->
check(resolveState is FirModuleResolveStateImpl)
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
check(resolveState is FirModuleResolveStateImpl)
val fileStructure = resolveState.fileStructureCache.getFileStructure(ktFile, resolveState.rootModuleSession.cache)
val allStructureElements = fileStructure.getAllStructureElements()
val fileStructure = resolveState.fileStructureCache.getFileStructure(ktFile, resolveState.rootModuleSession.cache)
val allStructureElements = fileStructure.getAllStructureElements()
handler!!.assertions = testServices.assertions
handler!!.elementsToCheckContext = allStructureElements.map { it.getFirDeclaration() }
handler!!.firFile = ktFile.getOrBuildFirFile(resolveState)
ktFile.getDiagnostics(resolveState, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
handler = null
handler.elementsToCheckContext = allStructureElements.map { it.getFirDeclaration() }
handler.firFile = ktFile.getOrBuildFirFile(resolveState)
ktFile.getDiagnostics(resolveState, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
}
}
private fun FileStructureElement.getFirDeclaration(): FirDeclaration = when (this) {
@@ -60,8 +64,10 @@ abstract class AbstractFirContextCollectionTest : FrontendApiSingleTestDataFileT
}
private class BeforeElementTestDiagnosticCollectionHandler() : BeforeElementDiagnosticCollectionHandler() {
lateinit var assertions: AssertionsService
private class BeforeElementTestDiagnosticCollectionHandler(
private val assertions: AssertionsService
) :
BeforeElementDiagnosticCollectionHandler() {
lateinit var elementsToCheckContext: List<FirDeclaration>
lateinit var firFile: FirFile
@@ -5,12 +5,13 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.compiler.based
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.AbstractCompilerBasedTest
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.addIdeTestIgnoreHandler
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.runners.baseFirDiagnosticTestConfiguration
import org.jetbrains.kotlin.test.runners.baseFirSpecDiagnosticTestConfiguration
abstract class AbstractDiagnosisCompilerTestDataSpecTest : FrontendApiDiagnosticTest() {
abstract class AbstractDiagnosisCompilerTestDataSpecTest : AbstractCompilerBasedTest() {
override fun TestConfigurationBuilder.configureTest() {
baseFirDiagnosticTestConfiguration()
baseFirSpecDiagnosticTestConfiguration()
@@ -5,11 +5,12 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.compiler.based
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.AbstractCompilerBasedTest
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.addIdeTestIgnoreHandler
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.runners.baseFirDiagnosticTestConfiguration
abstract class AbstractDiagnosisCompilerTestDataTest : FrontendApiDiagnosticTest() {
abstract class AbstractDiagnosisCompilerTestDataTest : AbstractCompilerBasedTest() {
override fun TestConfigurationBuilder.configureTest() {
baseFirDiagnosticTestConfiguration()
addIdeTestIgnoreHandler()
@@ -1,42 +0,0 @@
/*
* Copyright 2010-2021 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.idea.fir.low.level.api.diagnostic.compiler.based
import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirFile
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiTestWithTestdata
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.LowLevelFirAnalyzerFacade
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.LowLevelFirOutputArtifact
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
import org.jetbrains.kotlin.test.model.TestFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
import org.jetbrains.kotlin.test.services.getKtFilesForSourceFiles
import org.jetbrains.kotlin.test.services.sourceFileProvider
abstract class FrontendApiDiagnosticTest : FrontendApiTestWithTestdata() {
override fun getArtifact(
module: TestModule,
testServices: TestServices,
ktFiles: Map<TestFile, KtFile>,
resolveState: FirModuleResolveState
): LowLevelFirOutputArtifact {
val allFirFiles = ktFiles.map { (testFile, psiFile) ->
testFile to psiFile.getOrBuildFirFile(resolveState)
}.toMap()
val diagnosticCheckerFilter = if (FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS in module.directives) {
DiagnosticCheckerFilter.EXTENDED_AND_COMMON_CHECKERS
} else DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS
val analyzerFacade = LowLevelFirAnalyzerFacade(resolveState, allFirFiles, diagnosticCheckerFilter)
return LowLevelFirOutputArtifact(resolveState.rootModuleSession, analyzerFacade)
}
}
@@ -10,18 +10,16 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveStateImpl
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
abstract class AbstractFileStructureTest : FrontendApiSingleTestDataFileTest() {
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
abstract class AbstractFileStructureTest : AbstractLowLevelApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
val fileStructure = ktFile.getFileStructure()
val allStructureElements = fileStructure.getAllStructureElements(ktFile)
val declarationToStructureElement = allStructureElements.associateBy { it.psi }
@@ -17,6 +17,11 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousInitializerSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getModuleInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
import org.jetbrains.kotlin.psi.KtElement
internal fun Project.allModules() = ModuleManager.getInstance(this).modules.toList()
@@ -36,4 +41,13 @@ internal fun FirDeclaration.name(): String = when (this) {
is FirSymbolOwner<*> -> symbol.name()
is FirFile -> "<FILE>"
else -> error("unknown declaration ${this::class.simpleName}")
}
internal inline fun <R> resolveWithClearCaches(
context: KtElement,
noinline configureSession: FirIdeSession.() -> Unit = {},
action: (FirModuleResolveState) -> R,
): R {
val resolveState = createResolveStateForNoCaching(context.getModuleInfo(), context.project, configureSession)
return action(resolveState)
}
@@ -8,19 +8,20 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.resolve
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirOfType
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.resolveWithClearCaches
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
abstract class AbstractInnerDeclarationsResolvePhaseTest : FrontendApiSingleTestDataFileTest() {
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
val firFile = ktFile.getOrBuildFirOfType<FirFile>(resolveState)
val actual = firFile.render(FirRenderer.RenderMode.WithResolvePhases)
KotlinTestUtils.assertEqualsToFile(testDataFileSibling(".fir.txt"), actual)
abstract class AbstractInnerDeclarationsResolvePhaseTest : AbstractLowLevelApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
resolveWithClearCaches(ktFile) { resolveState ->
val firFile = ktFile.getOrBuildFirOfType<FirFile>(resolveState)
val actual = firFile.render(FirRenderer.RenderMode.WithResolvePhases)
KotlinTestUtils.assertEqualsToFile(testDataFileSibling(".fir.txt"), actual)
}
}
}
@@ -3,15 +3,15 @@
* 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.idea.fir.test.framework
package org.jetbrains.kotlin.idea.fir.low.level.api.test.base
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
abstract class AbstractKtIdeaTestWithSingleTestFileTest : AbstractKtSingleModuleTest() {
abstract class AbstractLowLevelApiSingleFileTest : AbstractLowLevelApiSingleModuleTest() {
final override fun doTestByFileStructure(ktFiles: List<KtFile>, moduleStructure: TestModuleStructure, testServices: TestServices) {
doTestByFileStructure(ktFiles.first(), moduleStructure, testServices)
doTestByFileStructure(ktFiles.single(), moduleStructure, testServices)
}
abstract fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices)
@@ -3,6 +3,6 @@
* 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.idea.fir.test.framework
package org.jetbrains.kotlin.idea.fir.low.level.api.test.base
abstract class AbstractKtSingleModuleTest : AbstractKtIdeaTest()
abstract class AbstractLowLevelApiSingleModuleTest : AbstractLowLevelApiTest()
@@ -3,7 +3,7 @@
* 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.idea.fir.test.framework
package org.jetbrains.kotlin.idea.fir.low.level.api.test.base
import com.intellij.mock.MockProject
import com.intellij.psi.PsiElementFinder
@@ -12,10 +12,6 @@ import org.jetbrains.kotlin.fir.session.FirModuleInfoBasedModuleData
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FirModuleResolveStateConfiguratorForSingleModuleTestImpl
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.TestModuleInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.registerTestServices
import org.jetbrains.kotlin.idea.fir.test.framework.*
import org.jetbrains.kotlin.idea.frontend.api.InvalidWayOfUsingAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSessionProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSessionProvider
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
@@ -34,7 +30,7 @@ import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.nameWithoutExtension
abstract class AbstractKtIdeaTest {
abstract class AbstractLowLevelApiTest {
private lateinit var testInfo: KotlinTestInfo
private val configure: TestConfigurationBuilder.() -> Unit = {
@@ -56,7 +52,7 @@ abstract class AbstractKtIdeaTest {
configureTest(this)
this.testInfo = this@AbstractKtIdeaTest.testInfo
this.testInfo = this@AbstractLowLevelApiTest.testInfo
}
protected lateinit var testDataPath: Path
@@ -69,7 +65,6 @@ abstract class AbstractKtIdeaTest {
open fun configureTest(builder: TestConfigurationBuilder) {}
@OptIn(InvalidWayOfUsingAnalysisSession::class)
protected fun runTest(path: String) {
testDataPath = Paths.get(path)
val testConfiguration = testConfiguration(path, configure)
@@ -93,13 +88,15 @@ abstract class AbstractKtIdeaTest {
with(project as MockProject) {
registerTestServices(configurator, ktFiles)
registerService(KtAnalysisSessionProvider::class.java, KtFirAnalysisSessionProvider::class.java)
registerServicesForProject(this)
}
doTestByFileStructure(ktFiles.values.toList(), moduleStructure, testServices)
}
abstract fun doTestByFileStructure(ktFiles: List<KtFile>, moduleStructure: TestModuleStructure, testServices: TestServices)
protected open fun registerServicesForProject(project: MockProject) {}
protected abstract fun doTestByFileStructure(ktFiles: List<KtFile>, moduleStructure: TestModuleStructure, testServices: TestServices)
@BeforeEach
fun initTestInfo(testInfo: TestInfo) {
@@ -109,8 +106,6 @@ abstract class AbstractKtIdeaTest {
tags = testInfo.tags
)
}
protected fun getCaretPosition(text: String) = text.indexOfOrNull(KtTest.CARET_SYMBOL)
}
@@ -3,9 +3,10 @@
* 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.idea.fir.test.framework
package org.jetbrains.kotlin.idea.fir.low.level.api.test.base
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline
import org.jetbrains.kotlin.idea.fir.low.level.api.util.parentOfType
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
@@ -52,18 +53,20 @@ internal class ExpressionMarkersSourceFilePreprocessor(testServices: TestService
}
}
internal class ExpressionMarkerProvider(testServices: TestServices) : TestService {
class ExpressionMarkerProvider(testServices: TestServices) : TestService {
private val selected = mutableMapOf<String, TextRange>()
private val atCaret = mutableMapOf<String, Int>()
@PrivateForInline val atCaret = mutableMapOf<String, Int>()
fun addSelectedExpression(file: TestFile, range: TextRange) {
selected[file.relativePath] = range
}
@OptIn(PrivateForInline::class)
fun addCaret(file: TestFile, caret: Int) {
atCaret[file.relativePath] = caret
}
@OptIn(PrivateForInline::class)
inline fun <reified P : KtElement> getElementOfTypAtCaret(file: KtFile): P {
val offset = atCaret[file.name]
?: error("No caret found in file")
@@ -84,4 +87,4 @@ internal class ExpressionMarkerProvider(testServices: TestServices) : TestServic
}
}
internal val TestServices.expressionMarkerProvider: ExpressionMarkerProvider by TestServices.testServiceAccessor()
val TestServices.expressionMarkerProvider: ExpressionMarkerProvider by TestServices.testServiceAccessor()
@@ -1,13 +0,0 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.test.base
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.command.CommandProcessor
internal inline fun <T> runUndoTransparentWriteAction(crossinline runnable: () -> T): T {
var result: T? = null
CommandProcessor.getInstance().runUndoTransparentAction {
ApplicationManager.getApplication().runWriteAction { result = runnable() }
}
@Suppress("UNCHECKED_CAST")
return result as T
}
@@ -6,17 +6,19 @@
package org.jetbrains.kotlin.idea.fir.frontend.api.components
import org.jetbrains.kotlin.idea.fir.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.fir.test.framework.AbstractKtIdeaTestWithSingleTestFileTest
import org.jetbrains.kotlin.idea.fir.test.framework.expressionMarkerProvider
import org.jetbrains.kotlin.idea.fir.frontend.api.test.framework.AbstractHLApiSingleFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.expressionMarkerProvider
import org.jetbrains.kotlin.idea.frontend.api.analyse
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractExpectedExpressionTypeTest : AbstractKtIdeaTestWithSingleTestFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
abstract class AbstractExpectedExpressionTypeTest : AbstractHLApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
val expressionAtCaret = testServices.expressionMarkerProvider.getElementOfTypAtCaret(ktFile) as KtExpression
val actualExpectedTypeText: String? = executeOnPooledThreadInReadAction {
@@ -6,17 +6,19 @@
package org.jetbrains.kotlin.idea.fir.frontend.api.components
import org.jetbrains.kotlin.idea.fir.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.fir.test.framework.AbstractKtIdeaTestWithSingleTestFileTest
import org.jetbrains.kotlin.idea.fir.test.framework.expressionMarkerProvider
import org.jetbrains.kotlin.idea.fir.frontend.api.test.framework.AbstractHLApiSingleFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.expressionMarkerProvider
import org.jetbrains.kotlin.idea.frontend.api.analyse
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractHLExpressionTypeTest : AbstractKtIdeaTestWithSingleTestFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
abstract class AbstractHLExpressionTypeTest : AbstractHLApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
val expression = testServices.expressionMarkerProvider.getSelectedElement(ktFile) as KtExpression
val type = executeOnPooledThreadInReadAction {
analyse(expression) { expression.getKtType().render() }
@@ -6,23 +6,23 @@
package org.jetbrains.kotlin.idea.fir.frontend.api.components
import org.jetbrains.kotlin.idea.fir.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.fir.frontend.api.test.framework.AbstractHLApiSingleModuleTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.expressionMarkerProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.util.parentsOfType
import org.jetbrains.kotlin.idea.fir.test.framework.*
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.analyse
import org.jetbrains.kotlin.idea.frontend.api.components.KtTypeRendererOptions
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSyntheticJavaPropertySymbol
import org.jetbrains.kotlin.idea.frontend.api.components.KtTypeRendererOptions
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractOverriddenDeclarationProviderTest : AbstractKtSingleModuleTest() {
override fun doTestByFileStructure(ktFiles: List<KtFile>, moduleStructure: TestModuleStructure, testServices: TestServices) {
abstract class AbstractOverriddenDeclarationProviderTest : AbstractHLApiSingleModuleTest() {
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
val declaration = testServices.expressionMarkerProvider.getElementOfTypAtCaret<KtDeclaration>(ktFiles.first())
val actual = executeOnPooledThreadInReadAction {
@@ -6,17 +6,19 @@
package org.jetbrains.kotlin.idea.fir.frontend.api.components
import org.jetbrains.kotlin.idea.fir.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.fir.test.framework.AbstractKtIdeaTestWithSingleTestFileTest
import org.jetbrains.kotlin.idea.fir.frontend.api.test.framework.AbstractHLApiSingleFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.idea.frontend.api.analyse
import org.jetbrains.kotlin.idea.frontend.api.components.KtDeclarationRendererOptions
import org.jetbrains.kotlin.idea.frontend.api.components.KtTypeRendererOptions
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractRendererTest : AbstractKtIdeaTestWithSingleTestFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
abstract class AbstractRendererTest : AbstractHLApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
val options = KtDeclarationRendererOptions.DEFAULT.copy(
approximateTypes = true,
renderContainingDeclarations = true,
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.idea.fir.frontend.api.fir
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.fir.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.fir.test.framework.AbstractKtSingleModuleTest
import org.jetbrains.kotlin.idea.fir.test.framework.expressionMarkerProvider
import org.jetbrains.kotlin.idea.fir.frontend.api.test.framework.AbstractHLApiSingleModuleTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.expressionMarkerProvider
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.analyse
import org.jetbrains.kotlin.idea.frontend.api.calls.KtCall
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
import kotlin.reflect.KProperty1
@@ -27,8 +27,8 @@ import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.javaGetter
abstract class AbstractResolveCallTest : AbstractKtSingleModuleTest() {
override fun doTestByFileStructure(ktFiles: List<KtFile>, moduleStructure: TestModuleStructure, testServices: TestServices) {
abstract class AbstractResolveCallTest : AbstractHLApiSingleModuleTest() {
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
val ktFile = ktFiles.first()
val expression = testServices.expressionMarkerProvider.getSelectedElement(ktFile)
@@ -6,18 +6,16 @@
package org.jetbrains.kotlin.idea.fir.frontend.api.scopes
import org.jetbrains.kotlin.idea.fir.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.fir.test.framework.AbstractKtIdeaTestWithSingleTestFileTest
import org.jetbrains.kotlin.idea.fir.frontend.api.test.framework.AbstractHLApiSingleFileTest
import org.jetbrains.kotlin.idea.frontend.api.analyse
import org.jetbrains.kotlin.idea.frontend.api.symbols.DebugSymbolRenderer
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
import java.io.File
abstract class AbstractFileScopeTest : AbstractKtIdeaTestWithSingleTestFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
abstract class AbstractFileScopeTest : AbstractHLApiSingleFileTest() {
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
val actual = executeOnPooledThreadInReadAction {
analyse(ktFile) {
val symbol = ktFile.getFileSymbol()
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.idea.fir.frontend.api.symbols
import org.jetbrains.kotlin.idea.fir.test.framework.expressionMarkerProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.expressionMarkerProvider
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.references.mainReference
@@ -6,20 +6,20 @@
package org.jetbrains.kotlin.idea.fir.frontend.api.symbols
import org.jetbrains.kotlin.idea.fir.analyseOnPooledThreadInReadAction
import org.jetbrains.kotlin.idea.fir.test.framework.AbstractKtIdeaTestWithSingleTestFileTest
import org.jetbrains.kotlin.idea.fir.frontend.api.test.framework.AbstractHLApiSingleFileTest
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.symbols.DebugSymbolRenderer
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractSymbolTest : AbstractKtIdeaTestWithSingleTestFileTest() {
abstract class AbstractSymbolTest : AbstractHLApiSingleFileTest() {
abstract fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): List<KtSymbol>
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
val createPointers = false //TODO !fileStructure.directives.isDirectivePresent(DIRECTIVES.DO_NOT_CHECK_SYMBOL_RESTORE)
val pointersWithRendered = analyseOnPooledThreadInReadAction(ktFile) {
collectSymbols(ktFile, testServices).map { symbol ->
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2021 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.idea.fir.frontend.api.test.framework
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
abstract class AbstractHLApiSingleFileTest : AbstractHLApiSingleModuleTest() {
final override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
val singleFile = ktFiles.single()
doTestByFileStructure(singleFile, module, testServices)
}
protected abstract fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices)
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2021 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.idea.fir.frontend.api.test.framework
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
abstract class AbstractHLApiSingleModuleTest : AbstractHLApiTest() {
final override fun doTestByFileStructure(ktFiles: List<KtFile>, moduleStructure: TestModuleStructure, testServices: TestServices) {
val singleModule = moduleStructure.modules.single()
doTestByFileStructure(ktFiles, singleModule, testServices)
}
protected abstract fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices)
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2021 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.idea.fir.frontend.api.test.framework
import com.intellij.mock.MockProject
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiTest
import org.jetbrains.kotlin.idea.frontend.api.InvalidWayOfUsingAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSessionProvider
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSessionProvider
abstract class AbstractHLApiTest : AbstractLowLevelApiTest() {
@OptIn(InvalidWayOfUsingAnalysisSession::class)
override fun registerServicesForProject(project: MockProject) {
super.registerServicesForProject(project)
project.registerService(KtAnalysisSessionProvider::class.java, KtFirAnalysisSessionProvider::class.java)
}
}
@@ -1,12 +0,0 @@
/*
* Copyright 2010-2021 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.idea.fir.test.framework
object KtTest {
const val CARET_SYMBOL = "<caret>"
const val FILE_DIRECTIVE = "// FILE:"
const val RESULT_DIRECTIVE = "// RESULT"
}