FIR IDE: add test which check that every declaration is visited single time during diagnostic collection
This commit is contained in:
+4
-2
@@ -68,13 +68,15 @@ abstract class AbstractDiagnosticCollector(
|
||||
componentsInitialized = true
|
||||
}
|
||||
|
||||
protected open fun beforeCollecting() {}
|
||||
protected open fun beforeRunningAllComponentsOnElement(element: FirElement) {}
|
||||
protected open fun beforeRunningSingleComponentOnElement(element: FirElement) {}
|
||||
|
||||
private inner class Visitor : FirDefaultVisitor<Unit, Nothing?>() {
|
||||
private fun <T : FirElement> T.runComponents() {
|
||||
if (currentAction.checkInCurrentDeclaration) {
|
||||
beforeRunningAllComponentsOnElement(this)
|
||||
components.forEach {
|
||||
beforeCollecting()
|
||||
beforeRunningSingleComponentOnElement(this)
|
||||
this.accept(it, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirLazyDeclarationRes
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirLazyResolveTest
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirMultiModuleLazyResolveTest
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirMultiModuleResolveTest
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.AbstractDiagnosticTraversalCounterTest
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.AbstractFileStructureAndOutOfBlockModificationTrackerConsistencyTest
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.AbstractFileStructureTest
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.AbstractSessionsInvalidationTest
|
||||
@@ -1073,6 +1074,9 @@ fun main(args: Array<String>) {
|
||||
testClass<AbstractFileStructureTest> {
|
||||
model("fileStructure")
|
||||
}
|
||||
testClass<AbstractDiagnosticTraversalCounterTest> {
|
||||
model("diagnosticTraversalCounter")
|
||||
}
|
||||
testClass<AbstractSessionsInvalidationTest> {
|
||||
model("sessionInvalidation", recursive = false, extension = null)
|
||||
}
|
||||
|
||||
+11
-4
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionProviderStorage
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.trackers.KotlinFirOutOfBlockModificationTrackerFactory
|
||||
import org.jetbrains.kotlin.idea.util.cachedValue
|
||||
import org.jetbrains.kotlin.idea.util.getValue
|
||||
import org.jetbrains.kotlin.trackers.createProjectWideOutOfBlockModificationTracker
|
||||
@@ -39,12 +39,13 @@ internal class FirIdeResolveStateService(project: Project) {
|
||||
|
||||
internal fun createResolveStateFor(
|
||||
moduleInfo: IdeaModuleInfo,
|
||||
sessionProviderStorage: FirIdeSessionProviderStorage
|
||||
sessionProviderStorage: FirIdeSessionProviderStorage,
|
||||
configureSession: (FirIdeSession.() -> Unit)? = null,
|
||||
): FirModuleResolveStateImpl {
|
||||
if (moduleInfo !is ModuleSourceInfo) {
|
||||
error("Creating FirModuleResolveState is not yet supported for $moduleInfo")
|
||||
}
|
||||
val sessionProvider = sessionProviderStorage.getSessionProvider(moduleInfo)
|
||||
val sessionProvider = sessionProviderStorage.getSessionProvider(moduleInfo, configureSession)
|
||||
val firFileBuilder = sessionProvider.rootModuleSession.firFileBuilder
|
||||
return FirModuleResolveStateImpl(
|
||||
moduleInfo.project,
|
||||
@@ -60,6 +61,12 @@ internal class FirIdeResolveStateService(project: Project) {
|
||||
@TestOnly
|
||||
fun createResolveStateForNoCaching(
|
||||
moduleInfo: IdeaModuleInfo,
|
||||
): FirModuleResolveState = FirIdeResolveStateService.createResolveStateFor(moduleInfo, FirIdeSessionProviderStorage(moduleInfo.project!!))
|
||||
configureSession: (FirIdeSession.() -> Unit)? = null,
|
||||
): FirModuleResolveState =
|
||||
FirIdeResolveStateService.createResolveStateFor(
|
||||
moduleInfo = moduleInfo,
|
||||
sessionProviderStorage = FirIdeSessionProviderStorage(moduleInfo.project!!),
|
||||
configureSession = configureSession
|
||||
)
|
||||
|
||||
|
||||
|
||||
+9
-1
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.SessionConfiguration
|
||||
import org.jetbrains.kotlin.fir.analysis.CheckersComponent
|
||||
@@ -41,6 +42,9 @@ internal abstract class AbstractFirIdeDiagnosticsCollector(
|
||||
::FirIdeDesignatedBodyResolveTransformerForReturnTypeCalculator
|
||||
)
|
||||
) {
|
||||
private val beforeElementDiagnosticCollectionHandler: BeforeElementDiagnosticCollectionHandler? =
|
||||
session.beforeElementDiagnosticCollectionHandler
|
||||
|
||||
init {
|
||||
val declarationCheckers = CheckersFactory.createDeclarationCheckers(useExtendedCheckers)
|
||||
val expressionCheckers = CheckersFactory.createExpressionCheckers(useExtendedCheckers)
|
||||
@@ -70,10 +74,14 @@ internal abstract class AbstractFirIdeDiagnosticsCollector(
|
||||
reporter = Reporter()
|
||||
}
|
||||
|
||||
override fun beforeCollecting() {
|
||||
override fun beforeRunningSingleComponentOnElement(element: FirElement) {
|
||||
checkCanceled()
|
||||
}
|
||||
|
||||
override fun beforeRunningAllComponentsOnElement(element: FirElement) {
|
||||
beforeElementDiagnosticCollectionHandler?.beforeCollectingForElement(element)
|
||||
}
|
||||
|
||||
override fun getCollectedDiagnostics(): List<FirDiagnostic<*>> {
|
||||
// Not necessary in IDE
|
||||
return emptyList()
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||
|
||||
abstract class BeforeElementDiagnosticCollectionHandler: FirSessionComponent {
|
||||
abstract fun beforeCollectingForElement(element: FirElement)
|
||||
}
|
||||
|
||||
val FirSession.beforeElementDiagnosticCollectionHandler: BeforeElementDiagnosticCollectionHandler? by FirSession.nullableSessionComponentAccessor()
|
||||
+11
-2
@@ -58,6 +58,7 @@ internal object FirIdeSessionFactory {
|
||||
isRootModule: Boolean,
|
||||
librariesCache: LibrariesCache,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
configureSession: (FirIdeSession.() -> Unit)? = null
|
||||
): FirIdeSourcesSession {
|
||||
sessionsCache[moduleInfo]?.let { return it }
|
||||
val scopeProvider = KotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
@@ -108,7 +109,8 @@ internal object FirIdeSessionFactory {
|
||||
project,
|
||||
builtinsAndCloneableSession,
|
||||
builtinTypes,
|
||||
librariesCache
|
||||
librariesCache,
|
||||
configureSession = configureSession,
|
||||
).symbolProvider
|
||||
)
|
||||
dependentModules
|
||||
@@ -123,6 +125,7 @@ internal object FirIdeSessionFactory {
|
||||
sessionsCache,
|
||||
isRootModule = false,
|
||||
librariesCache,
|
||||
configureSession = configureSession,
|
||||
).symbolProvider
|
||||
}
|
||||
}
|
||||
@@ -137,6 +140,8 @@ internal object FirIdeSessionFactory {
|
||||
registerExtendedCommonCheckers()
|
||||
}
|
||||
}.configure()
|
||||
|
||||
configureSession?.invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +152,7 @@ internal object FirIdeSessionFactory {
|
||||
builtinTypes: BuiltinTypes,
|
||||
librariesCache: LibrariesCache,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
configureSession: (FirIdeSession.() -> Unit)?,
|
||||
): FirIdeLibrariesSession = librariesCache.cached(moduleInfo) {
|
||||
checkCanceled()
|
||||
val searchScope = ModuleLibrariesSearchScope(moduleInfo.module)
|
||||
@@ -191,13 +197,15 @@ internal object FirIdeSessionFactory {
|
||||
)
|
||||
)
|
||||
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
||||
configureSession?.invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun createBuiltinsAndCloneableSession(
|
||||
project: Project,
|
||||
builtinTypes: BuiltinTypes,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
configureSession: (FirIdeSession.() -> Unit)? = null,
|
||||
): FirIdeBuiltinsAndCloneableSession {
|
||||
return FirIdeBuiltinsAndCloneableSession(project, builtinTypes).apply {
|
||||
registerIdeComponents()
|
||||
@@ -215,6 +223,7 @@ internal object FirIdeSessionFactory {
|
||||
)
|
||||
)
|
||||
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
||||
configureSession?.invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -26,7 +26,10 @@ internal class FirIdeSessionProviderStorage(private val project: Project) {
|
||||
|
||||
private val librariesCache by cachedValue(project, LibraryModificationTracker.getInstance(project)) { LibrariesCache() }
|
||||
|
||||
fun getSessionProvider(rootModule: ModuleSourceInfo): FirIdeSessionProvider {
|
||||
fun getSessionProvider(
|
||||
rootModule: ModuleSourceInfo,
|
||||
configureSession: (FirIdeSession.() -> Unit)? = null
|
||||
): FirIdeSessionProvider {
|
||||
val firPhaseRunner = FirPhaseRunner()
|
||||
|
||||
val builtinTypes = BuiltinTypes()
|
||||
@@ -45,6 +48,7 @@ internal class FirIdeSessionProviderStorage(private val project: Project) {
|
||||
sessions,
|
||||
isRootModule = true,
|
||||
librariesCache,
|
||||
configureSession = configureSession,
|
||||
)
|
||||
}
|
||||
sessions to session
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
fun foo(f: Float.(Int, String) -> Boolean) {
|
||||
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
class A(val x: Int = 10, val b: String) {
|
||||
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo() {
|
||||
fun local() = 0
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
fun foo() {
|
||||
fun local() {
|
||||
println("local")
|
||||
}
|
||||
}
|
||||
idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/memberFunctions.kt
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
fun foo1() = 10
|
||||
|
||||
fun foo2() {
|
||||
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
fun foo1() = 10
|
||||
|
||||
fun foo2() {
|
||||
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class A {
|
||||
|
||||
}
|
||||
|
||||
class B {
|
||||
|
||||
}
|
||||
|
||||
class C {
|
||||
|
||||
}
|
||||
|
||||
class D {
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fun foo1() = 1
|
||||
|
||||
fun foo2() = 2
|
||||
|
||||
fun foo3() = 3
|
||||
|
||||
fun foo4() = 4
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
fun foo1() {
|
||||
println("foo1")
|
||||
}
|
||||
|
||||
fun foo2() {
|
||||
println("foo2")
|
||||
}
|
||||
|
||||
fun foo3() {
|
||||
println("foo3")
|
||||
}
|
||||
|
||||
fun foo4() {
|
||||
println("foo4")
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
class A {
|
||||
class B {
|
||||
|
||||
}
|
||||
|
||||
object C {
|
||||
class D {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
var withGetterAndSetter: Int = 42
|
||||
get() = field
|
||||
set(value) {
|
||||
field = value
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class A(val x: Int = 10, val b: String) {
|
||||
constructor(i: Int) : this(x = 1, b = i.toString())
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.SessionConfiguration
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter
|
||||
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.createResolveStateForNoCaching
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.BeforeElementDiagnosticCollectionHandler
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.renderWithClassName
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Check that every declaration is visited exactly one time during diagnostic collection
|
||||
*/
|
||||
abstract class AbstractDiagnosticTraversalCounterTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
override fun isFirPlugin(): Boolean = true
|
||||
|
||||
fun doTest(path: String) {
|
||||
val testDataFile = File(path)
|
||||
val ktFile = myFixture.configureByText(testDataFile.name, FileUtil.loadFile(testDataFile)) as KtFile
|
||||
|
||||
val handler = BeforeElementTestDiagnosticCollectionHandler()
|
||||
|
||||
@OptIn(SessionConfiguration::class)
|
||||
val resolveState = createResolveStateForNoCaching(ktFile.getModuleInfo()) {
|
||||
register(BeforeElementDiagnosticCollectionHandler::class, handler)
|
||||
}
|
||||
|
||||
// we should get diagnostics before we resolve the whole file by ktFile.getOrBuildFir
|
||||
ktFile.collectDiagnosticsForFile(resolveState, DiagnosticCheckerFilter.ONLY_COMMON_CHECKERS)
|
||||
|
||||
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
|
||||
|${zeroElements.joinToString(separator = "\n\n") { it.first.renderWithClassName() }}
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
if (nonZeroElements.isNotEmpty()) {
|
||||
appendLine(
|
||||
""" |The following elements were visited more than one time
|
||||
|${nonZeroElements.joinToString(separator = "\n\n") { it.second.toString() + " times " + it.first.renderWithClassName() }}
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
}
|
||||
fail(message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectErrorElements(
|
||||
firFile: FirElement,
|
||||
handler: BeforeElementTestDiagnosticCollectionHandler
|
||||
): List<Pair<FirElement, Int>> {
|
||||
val errorElements = mutableListOf<Pair<FirElement, Int>>()
|
||||
val nonDuplicatingElements = findNonDuplicatingFirElements(firFile)
|
||||
firFile.accept(object : FirVisitorVoid() {
|
||||
override fun visitElement(element: FirElement) {
|
||||
if (element !in nonDuplicatingElements) return
|
||||
val visitedTimes = handler.visitedTimes[element] ?: 0
|
||||
if (visitedTimes != 1) {
|
||||
errorElements += element to visitedTimes
|
||||
}
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
})
|
||||
return errorElements
|
||||
}
|
||||
|
||||
private fun findNonDuplicatingFirElements(
|
||||
firFile: FirElement,
|
||||
): Set<FirElement> {
|
||||
val elementUsageCount = mutableMapOf<FirElement, Int>()
|
||||
firFile.accept(object : FirVisitorVoid() {
|
||||
override fun visitElement(element: FirElement) {
|
||||
elementUsageCount.compute(element) { _, count -> (count ?: 0) + 1 }
|
||||
}
|
||||
})
|
||||
return elementUsageCount.filterValues { it == 1 }.keys
|
||||
}
|
||||
|
||||
|
||||
class BeforeElementTestDiagnosticCollectionHandler : BeforeElementDiagnosticCollectionHandler() {
|
||||
val visitedTimes = mutableMapOf<FirElement, Int>()
|
||||
override fun beforeCollectingForElement(element: FirElement) {
|
||||
if (!visitedTimes.containsKey(element)) {
|
||||
visitedTimes[element] = 1
|
||||
} else {
|
||||
visitedTimes.compute(element) { _, count -> (count ?: 0) + 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class DiagnosticTraversalCounterTestGenerated extends AbstractDiagnosticTraversalCounterTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDiagnosticTraversalCounter() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/constructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("functionalType.kt")
|
||||
public void testFunctionalType() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/functionalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localFunctionWithImplicitType.kt")
|
||||
public void testLocalFunctionWithImplicitType() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/localFunctionWithImplicitType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localUnitFunction.kt")
|
||||
public void testLocalUnitFunction() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/localUnitFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("memberFunctions.kt")
|
||||
public void testMemberFunctions() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/memberFunctions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("memberProperties.kt")
|
||||
public void testMemberProperties() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/memberProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleTopLevelClasses.kt")
|
||||
public void testMultipleTopLevelClasses() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/multipleTopLevelClasses.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleTopLevelFunctionsWithImplicitTypes.kt")
|
||||
public void testMultipleTopLevelFunctionsWithImplicitTypes() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/multipleTopLevelFunctionsWithImplicitTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleTopLevelUnitFunctions.kt")
|
||||
public void testMultipleTopLevelUnitFunctions() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/multipleTopLevelUnitFunctions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClases.kt")
|
||||
public void testNestedClases() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/nestedClases.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyWithGetterAndSetter.kt")
|
||||
public void testPropertyWithGetterAndSetter() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/propertyWithGetterAndSetter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructor.kt")
|
||||
public void testSecondaryConstructor() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/diagnosticTraversalCounter/secondaryConstructor.kt");
|
||||
}
|
||||
}
|
||||
+6
@@ -9,6 +9,9 @@ import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.trackers.KotlinFirModificationTrackerService
|
||||
@@ -21,6 +24,9 @@ inline fun resolveWithClearCaches(context: KtElement, action: (FirModuleResolveS
|
||||
action(resolveState)
|
||||
}
|
||||
|
||||
internal fun FirElement.renderWithClassName(renderMode: FirRenderer.RenderMode = FirRenderer.RenderMode.Normal): String =
|
||||
"${this::class.simpleName} `${render(renderMode)}`"
|
||||
|
||||
internal fun Module.incModificationTracker() {
|
||||
project.service<KotlinFirModificationTrackerService>().increaseModificationCountForModule(this)
|
||||
}
|
||||
Reference in New Issue
Block a user