[AA] AbstractSymbolTest: add assertion on redundant directive
^KT-54311
This commit is contained in:
committed by
Space Team
parent
3c2e0cb3b9
commit
119f6858cd
+48
-15
@@ -7,21 +7,26 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtDeclarationRendererOptions
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTestDirectives.DO_NOT_CHECK_SYMBOL_RESTORE
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTestDirectives.DO_NOT_CHECK_SYMBOL_RESTORE_K1
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.SymbolTestDirectives.DO_NOT_CHECK_SYMBOL_RESTORE_K2
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.DebugSymbolRenderer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest
|
||||
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind
|
||||
import org.jetbrains.kotlin.analysis.test.framework.utils.executeOnPooledThreadInReadAction
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.directives.model.DirectiveApplicability
|
||||
import org.jetbrains.kotlin.test.directives.model.Directive
|
||||
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.assertions
|
||||
import kotlin.test.fail
|
||||
|
||||
abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
|
||||
private val renderingOptions = KtDeclarationRendererOptions.DEFAULT
|
||||
@@ -38,27 +43,35 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
|
||||
abstract fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): SymbolsData
|
||||
|
||||
override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) {
|
||||
val createPointers = SymbolTestDirectives.DO_NOT_CHECK_SYMBOL_RESTORE !in module.directives
|
||||
val directives = module.directives
|
||||
val directiveToIgnore = DO_NOT_CHECK_SYMBOL_RESTORE.takeIf { it in directives }
|
||||
?: DO_NOT_CHECK_SYMBOL_RESTORE_K1.takeIf { configurator.frontendKind == FrontendKind.Fe10 && it in directives }
|
||||
?: DO_NOT_CHECK_SYMBOL_RESTORE_K2.takeIf { configurator.frontendKind == FrontendKind.Fir && it in directives }
|
||||
|
||||
val prettyRenderOptions = when (prettyRenderMode) {
|
||||
PrettyRenderingMode.RENDER_SYMBOLS_LINE_BY_LINE -> renderingOptions
|
||||
PrettyRenderingMode.RENDER_SYMBOLS_NESTED -> renderingOptions.copy(renderClassMembers = true)
|
||||
}
|
||||
|
||||
fun KtSymbol.safePointer(): KtSymbolPointer<KtSymbol>? {
|
||||
val result = kotlin.runCatching { createPointer() }
|
||||
return if (directiveToIgnore == null) result.getOrThrow() else result.getOrNull()
|
||||
}
|
||||
|
||||
val pointersWithRendered = executeOnPooledThreadInReadAction {
|
||||
analyseForTest(ktFile) {
|
||||
val (symbols, symbolForPrettyRendering) = collectSymbols(ktFile, testServices)
|
||||
|
||||
val pointerWithRenderedSymbol = symbols.map { symbol ->
|
||||
PointerWithRenderedSymbol(
|
||||
if (createPointers) symbol.createPointer() else null,
|
||||
symbol.safePointer(),
|
||||
renderSymbolForComparison(symbol),
|
||||
)
|
||||
}
|
||||
|
||||
val pointerWithPrettyRenderedSymbol = symbolForPrettyRendering.map { symbol ->
|
||||
PointerWithRenderedSymbol(
|
||||
if (createPointers) symbol.createPointer() else null,
|
||||
symbol.safePointer(),
|
||||
when (symbol) {
|
||||
is KtDeclarationSymbol -> symbol.render(prettyRenderOptions)
|
||||
is KtFileSymbol -> prettyPrint {
|
||||
@@ -80,9 +93,7 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
|
||||
|
||||
configurator.doOutOfBlockModification(ktFile)
|
||||
|
||||
if (createPointers) {
|
||||
restoreSymbolsInOtherReadActionAndCompareResults(ktFile, pointersWithRendered.pointers, testServices)
|
||||
}
|
||||
restoreSymbolsInOtherReadActionAndCompareResults(directiveToIgnore, ktFile, pointersWithRendered.pointers, testServices)
|
||||
}
|
||||
|
||||
private fun compareResults(
|
||||
@@ -104,20 +115,35 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
|
||||
else joinToString(separator = "\n\n")
|
||||
|
||||
private fun restoreSymbolsInOtherReadActionAndCompareResults(
|
||||
directiveToIgnore: Directive?,
|
||||
ktFile: KtFile,
|
||||
pointersWithRendered: List<PointerWithRenderedSymbol>,
|
||||
testServices: TestServices,
|
||||
) {
|
||||
val restored = analyseForTest(ktFile) {
|
||||
pointersWithRendered.map { (pointer, expectedRender) ->
|
||||
val restored = pointer!!.restoreSymbol()
|
||||
?: error("Symbol $expectedRender was not restored")
|
||||
var failed = false
|
||||
try {
|
||||
val restored = analyseForTest(ktFile) {
|
||||
pointersWithRendered.map { (pointer, expectedRender) ->
|
||||
val restored = pointer!!.restoreSymbol() ?: error("Symbol $expectedRender was not restored")
|
||||
|
||||
renderSymbolForComparison(restored)
|
||||
renderSymbolForComparison(restored)
|
||||
}
|
||||
}
|
||||
val actual = restored.renderAsDeclarations()
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||
} catch (e: Throwable) {
|
||||
if (directiveToIgnore == null) throw e
|
||||
failed = true
|
||||
}
|
||||
val actual = restored.renderAsDeclarations()
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||
|
||||
if (failed || directiveToIgnore == null) return
|
||||
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(
|
||||
actual = ktFile.text.lines().filterNot { it == "// ${directiveToIgnore.name}" }.joinToString(separator = "\n"),
|
||||
extension = "kt",
|
||||
)
|
||||
|
||||
fail("Redundant // ${directiveToIgnore.name} directive")
|
||||
}
|
||||
|
||||
protected open fun KtAnalysisSession.renderSymbolForComparison(symbol: KtSymbol): String {
|
||||
@@ -128,7 +154,14 @@ abstract class AbstractSymbolTest : AbstractAnalysisApiSingleFileTest() {
|
||||
object SymbolTestDirectives : SimpleDirectivesContainer() {
|
||||
val DO_NOT_CHECK_SYMBOL_RESTORE by directive(
|
||||
description = "Symbol restoring for some symbols in current test is not supported yet",
|
||||
applicability = DirectiveApplicability.Global
|
||||
)
|
||||
|
||||
val DO_NOT_CHECK_SYMBOL_RESTORE_K1 by directive(
|
||||
description = "Symbol restoring for some symbols in current test is not supported yet in K1",
|
||||
)
|
||||
|
||||
val DO_NOT_CHECK_SYMBOL_RESTORE_K2 by directive(
|
||||
description = "Symbol restoring for some symbols in current test is not supported yet in K2",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user