FirRenderer: partially get rid of RenderMode

This commit is contained in:
Mikhail Glukhikh
2022-07-06 17:03:09 +02:00
committed by Space
parent 9890066b72
commit 7c27e6f843
29 changed files with 254 additions and 169 deletions
@@ -27,7 +27,9 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirFieldImpl import org.jetbrains.kotlin.fir.declarations.impl.FirFieldImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.renderer.FirDeclarationRendererWithResolvePhase
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.renderer.FirRenderer.RenderMode.Companion.Normal
import org.jetbrains.kotlin.fir.resolve.getContainingClass import org.jetbrains.kotlin.fir.resolve.getContainingClass
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
@@ -583,7 +585,11 @@ internal class KtSymbolByFirBuilder constructor(
returns() implies requirement returns() implies requirement
} }
require(requirement) { require(requirement) {
"Cannot build ${S::class.simpleName} for ${firSymbol.fir.renderWithType(FirRenderer.RenderMode.WithResolvePhases)}" // TODO: renderWithTypes!!!
val renderedSymbol = FirRenderer().with(
declarationRenderer = FirDeclarationRendererWithResolvePhase()
).renderElementAsString(firSymbol.fir)
"Cannot build ${S::class.simpleName} for $renderedSymbol}"
} }
} }
} }
@@ -160,7 +160,10 @@ internal class KtFirTypeProvider(
?: this.typeArguments.mapNotNull { it.type }) ?: this.typeArguments.mapNotNull { it.type })
require(typeParameterSymbols.size == argumentTypes.size) { require(typeParameterSymbols.size == argumentTypes.size) {
"'${symbol.fir.render(FirRenderer.RenderMode.NoBodies)}' expects '${typeParameterSymbols.size}' type arguments " + val renderedSymbol = FirRenderer(mode = FirRenderer.RenderMode.NoBodies).with(
annotationRenderer = null, bodyRenderer = null
).renderElementAsString(symbol.fir)
"'$renderedSymbol' expects '${typeParameterSymbols.size}' type arguments " +
"but type '${this.renderForDebugging()}' has ${argumentTypes.size} type arguments." "but type '${this.renderForDebugging()}' has ${argumentTypes.size} type arguments."
} }
@@ -21,8 +21,9 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.renderer.FirDeclarationRendererWithResolvePhase
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.renderer.FirRenderer.RenderMode.Companion.Normal
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -32,10 +33,14 @@ import org.jetbrains.kotlin.psi.KtDeclaration
internal fun FirCallableSymbol<*>.invalidModalityError(): Nothing { internal fun FirCallableSymbol<*>.invalidModalityError(): Nothing {
// TODO: renderWithTypes!!!
val rendered = FirRenderer().with(
declarationRenderer = FirDeclarationRendererWithResolvePhase()
).renderElementAsString(fir)
error( error(
"""|Symbol modality should not be null, looks like the FIR symbol was not properly resolved """|Symbol modality should not be null, looks like the FIR symbol was not properly resolved
| |
|${fir.renderWithType(FirRenderer.RenderMode.WithResolvePhases)} |$rendered
| |
|${(fir.psi as? KtDeclaration)?.getElementTextInContext()}""".trimMargin() |${(fir.psi as? KtDeclaration)?.getElementTextInContext()}""".trimMargin()
) )
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.ideSessionComponents
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer.RenderMode.Companion.Normal
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -54,7 +54,7 @@ internal fun FirBasedSymbol<*>.createSignature(): IdSignature =
internal fun FirDeclaration.createSignature(): IdSignature { internal fun FirDeclaration.createSignature(): IdSignature {
val signatureComposer = moduleData.session.ideSessionComponents.signatureComposer val signatureComposer = moduleData.session.ideSessionComponents.signatureComposer
return signatureComposer.composeSignature(this) return signatureComposer.composeSignature(this)
?: error("Could not compose signature for ${this.renderWithType(FirRenderer.RenderMode.WithResolvePhases)}, looks like it is private or local") ?: error("Could not compose signature for ${this.renderWithType(Normal)}, looks like it is private or local")
} }
internal fun KtFirAnalysisSession.getClassLikeSymbol(classId: ClassId) = internal fun KtFirAnalysisSession.getClassLikeSymbol(classId: ClassId) =
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.realPsi import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.renderer.FirDeclarationRendererWithAttributesAndResolvePhase
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
@@ -51,8 +51,8 @@ abstract class AbstractFirLazyDeclarationResolveTest : AbstractLowLevelApiSingle
} }
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) { override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
val rendererOption = FirRenderer.RenderMode.WithDeclarationAttributes.copy(renderDeclarationResolvePhase = true)
val resultBuilder = StringBuilder() val resultBuilder = StringBuilder()
val renderer = FirRenderer(resultBuilder).with(declarationRenderer = FirDeclarationRendererWithAttributesAndResolvePhase())
resolveWithClearCaches(ktFile) { firResolveSession -> resolveWithClearCaches(ktFile) { firResolveSession ->
check(firResolveSession is LLFirSourceResolveSession) check(firResolveSession is LLFirSourceResolveSession)
val declarationToResolve = firResolveSession val declarationToResolve = firResolveSession
@@ -63,7 +63,7 @@ abstract class AbstractFirLazyDeclarationResolveTest : AbstractLowLevelApiSingle
declarationToResolve.ensureResolved(currentPhase) declarationToResolve.ensureResolved(currentPhase)
val firFile = firResolveSession.getOrBuildFirFile(ktFile) val firFile = firResolveSession.getOrBuildFirFile(ktFile)
resultBuilder.append("\n${currentPhase.name}:\n") resultBuilder.append("\n${currentPhase.name}:\n")
resultBuilder.append(firFile.render(rendererOption)) renderer.renderElementAsString(firFile)
} }
} }
@@ -72,7 +72,7 @@ abstract class AbstractFirLazyDeclarationResolveTest : AbstractLowLevelApiSingle
val firFile = firResolveSession.getOrBuildFirFile(ktFile) val firFile = firResolveSession.getOrBuildFirFile(ktFile)
firFile.ensureResolved(FirResolvePhase.BODY_RESOLVE) firFile.ensureResolved(FirResolvePhase.BODY_RESOLVE)
resultBuilder.append("\nFILE RAW TO BODY:\n") resultBuilder.append("\nFILE RAW TO BODY:\n")
resultBuilder.append(firFile.render(rendererOption)) renderer.renderElementAsString(firFile)
} }
testServices.assertions.assertEqualsToTestDataFileSibling(resultBuilder.toString()) testServices.assertions.assertEqualsToTestDataFileSibling(resultBuilder.toString())
@@ -8,8 +8,9 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeForResolveOnAir import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeForResolveOnAir
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceResolveSession import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirSourceResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AbstractLowLevelApiSingleFileTest import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.renderer.FirDeclarationRendererWithResolvePhase
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.renderer.FirRenderer.RenderMode.Companion.Normal
import org.jetbrains.kotlin.psi.KtAnnotated import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -35,7 +36,9 @@ abstract class AbstractFirOnAirResolveTest : AbstractLowLevelApiSingleFileTest()
resolveWithClearCaches(ktFile) { firResolveSession -> resolveWithClearCaches(ktFile) { firResolveSession ->
check(firResolveSession is LLFirSourceResolveSession) check(firResolveSession is LLFirSourceResolveSession)
val firElement = LowLevelFirApiFacadeForResolveOnAir.onAirResolveElement(firResolveSession, place, onAir) val firElement = LowLevelFirApiFacadeForResolveOnAir.onAirResolveElement(firResolveSession, place, onAir)
val rendered = firElement.render(FirRenderer.RenderMode.WithResolvePhases) val rendered = FirRenderer().with(
declarationRenderer = FirDeclarationRendererWithResolvePhase()
).renderElementAsString(firElement)
testServices.assertions.assertEqualsToTestDataFileSibling(rendered) testServices.assertions.assertEqualsToTestDataFileSibling(rendered)
} }
} }
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerPro
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirImport import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.renderer.FirPackageDirectiveRenderer
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
@@ -59,13 +60,9 @@ abstract class AbstractGetOrBuildFirTest : AbstractLowLevelApiSingleFileTest() {
private fun render(firElement: FirElement?): String = when (firElement) { private fun render(firElement: FirElement?): String = when (firElement) {
null -> "null" null -> "null"
is FirImport -> "import ${firElement.importedFqName}" is FirImport -> "import ${firElement.importedFqName}"
else -> firElement.render(renderingMode) else -> FirRenderer().with(packageDirectiveRenderer = FirPackageDirectiveRenderer()).renderElementAsString(firElement)
} }
private val renderingMode = FirRenderer.RenderMode.Normal.copy(
renderPackageDirective = true,
)
private object Directives : SimpleDirectivesContainer() { private object Directives : SimpleDirectivesContainer() {
val LOOK_UP_FOR_ELEMENT_OF_TYPE by stringDirective("LOOK_UP_FOR_ELEMENT_OF_TYPE") val LOOK_UP_FOR_ELEMENT_OF_TYPE by stringDirective("LOOK_UP_FOR_ELEMENT_OF_TYPE")
} }
@@ -9,8 +9,9 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirOfType
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolveWithClearCaches import org.jetbrains.kotlin.analysis.low.level.api.fir.resolveWithClearCaches
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AbstractLowLevelApiSingleFileTest import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.renderer.FirDeclarationRendererWithResolvePhase
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.renderer.FirRenderer.RenderMode.Companion.Normal
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.services.TestModuleStructure import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.TestServices
@@ -20,7 +21,9 @@ abstract class AbstractInnerDeclarationsResolvePhaseTest : AbstractLowLevelApiSi
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) { override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
resolveWithClearCaches(ktFile) { firResolveSession -> resolveWithClearCaches(ktFile) { firResolveSession ->
val firFile = ktFile.getOrBuildFirOfType<FirFile>(firResolveSession) val firFile = ktFile.getOrBuildFirOfType<FirFile>(firResolveSession)
val actual = firFile.render(FirRenderer.RenderMode.WithResolvePhases) val actual = FirRenderer().with(
declarationRenderer = FirDeclarationRendererWithResolvePhase()
).renderElementAsString(firFile)
testServices.assertions.assertEqualsToTestDataFileSibling(actual, extension = ".fir.txt") testServices.assertions.assertEqualsToTestDataFileSibling(actual, extension = ".fir.txt")
} }
} }
@@ -14,7 +14,11 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.renderer.ConeTypeRenderer
import org.jetbrains.kotlin.fir.renderer.FirAnnotationRenderer
import org.jetbrains.kotlin.fir.renderer.FirNoClassMemberRenderer
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.renderer.FirRenderer.RenderMode.Companion.WithFqNames
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -27,7 +31,14 @@ object FirDiagnosticRenderers {
val SYMBOL = Renderer { symbol: FirBasedSymbol<*> -> val SYMBOL = Renderer { symbol: FirBasedSymbol<*> ->
when (symbol) { when (symbol) {
is FirClassLikeSymbol<*>, is FirClassLikeSymbol<*>,
is FirCallableSymbol<*> -> symbol.fir.render(FirRenderer.RenderMode.DeclarationHeader) is FirCallableSymbol<*> -> FirRenderer(
mode = FirRenderer.RenderMode.DeclarationHeader
).with(
typeRenderer = ConeTypeRenderer(),
classMemberRenderer = FirNoClassMemberRenderer(),
annotationRenderer = FirAnnotationRenderer(),
bodyRenderer = null,
).renderElementAsString(symbol.fir)
is FirTypeParameterSymbol -> symbol.name.asString() is FirTypeParameterSymbol -> symbol.name.asString()
else -> "???" else -> "???"
} }
@@ -94,7 +105,9 @@ object FirDiagnosticRenderers {
val FQ_NAMES_IN_TYPES = Renderer { symbol: FirBasedSymbol<*> -> val FQ_NAMES_IN_TYPES = Renderer { symbol: FirBasedSymbol<*> ->
@OptIn(SymbolInternals::class) @OptIn(SymbolInternals::class)
symbol.fir.render(mode = FirRenderer.RenderMode.WithFqNamesExceptAnnotationAndBody) FirRenderer(mode = WithFqNames).with(
annotationRenderer = null, bodyRenderer = null
).renderElementAsString(symbol.fir)
} }
val AMBIGUOUS_CALLS = Renderer { candidates: Collection<FirBasedSymbol<*>> -> val AMBIGUOUS_CALLS = Renderer { candidates: Collection<FirBasedSymbol<*>> ->
@@ -11,7 +11,13 @@ import org.jetbrains.kotlin.name.ClassId
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
open class ConeTypeRenderer(protected val builder: StringBuilder) { open class ConeTypeRenderer() {
lateinit var builder: StringBuilder
constructor(builder: StringBuilder) : this() {
this.builder = builder
}
open fun renderAsPossibleFunctionType( open fun renderAsPossibleFunctionType(
type: ConeKotlinType, renderType: ConeTypeProjection.() -> Unit = { render() } type: ConeKotlinType, renderType: ConeTypeProjection.() -> Unit = { render() }
@@ -8,7 +8,12 @@ package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeProjection import org.jetbrains.kotlin.fir.types.ConeTypeProjection
class ConeTypeRendererForDebugging(builder: StringBuilder) : ConeTypeRendererWithFqNames(builder) { class ConeTypeRendererForDebugging() : ConeTypeRendererWithFqNames() {
constructor(builder: StringBuilder) : this() {
this.builder = builder
}
override fun renderAsPossibleFunctionType(type: ConeKotlinType, renderType: ConeTypeProjection.() -> Unit) { override fun renderAsPossibleFunctionType(type: ConeKotlinType, renderType: ConeTypeProjection.() -> Unit) {
builder.append("R|") builder.append("R|")
super.renderAsPossibleFunctionType(type, renderType) super.renderAsPossibleFunctionType(type, renderType)
@@ -7,7 +7,12 @@ package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
open class ConeTypeRendererWithFqNames(builder: StringBuilder) : ConeTypeRenderer(builder) { open class ConeTypeRendererWithFqNames() : ConeTypeRenderer() {
constructor(builder: StringBuilder) : this() {
this.builder = builder
}
override fun ClassId.render() { override fun ClassId.render() {
builder.append(asString()) builder.append(asString())
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lightTree
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.renderer.FirDeclarationRendererWithAttributes
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.session.FirSessionFactory import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
@@ -23,7 +24,7 @@ abstract class AbstractLightTree2FirConverterTestCase : AbstractRawFirBuilderTes
scopeProvider = StubFirScopeProvider, scopeProvider = StubFirScopeProvider,
diagnosticsReporter = null diagnosticsReporter = null
).buildFirFile(Paths.get(filePath)) ).buildFirFile(Paths.get(filePath))
val firDump = firFile.render(mode = FirRenderer.RenderMode.WithDeclarationAttributes) val firDump = FirRenderer().with(declarationRenderer = FirDeclarationRendererWithAttributes()).renderElementAsString(firFile)
val expectedFile = File(filePath.replace(".kt", ".txt")) val expectedFile = File(filePath.replace(".kt", ".txt"))
KotlinTestUtils.assertEqualsToFile(expectedFile, firDump) KotlinTestUtils.assertEqualsToFile(expectedFile, firDump)
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
import org.jetbrains.kotlin.fir.references.impl.FirStubReference import org.jetbrains.kotlin.fir.references.impl.FirStubReference
import org.jetbrains.kotlin.fir.renderer.FirDeclarationRendererWithAttributes
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.session.FirSessionFactory import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.FirTypeProjection
@@ -65,7 +66,7 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
protected open fun doRawFirTest(filePath: String) { protected open fun doRawFirTest(filePath: String) {
val file = createKtFile(filePath) val file = createKtFile(filePath)
val firFile = file.toFirFile(BodyBuildingMode.NORMAL) val firFile = file.toFirFile(BodyBuildingMode.NORMAL)
val firFileDump = FirRenderer(mode = FirRenderer.RenderMode.WithDeclarationAttributes).renderElementAsString(firFile) val firFileDump = FirRenderer().with(declarationRenderer = FirDeclarationRendererWithAttributes()).renderElementAsString(firFile)
val expectedPath = filePath.replace(".kt", ".txt") val expectedPath = filePath.replace(".kt", ".txt")
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump) KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
} }
@@ -39,26 +39,26 @@ fun CFGNode<*>.render(): String =
is LoopConditionExitNode -> "Exit loop condition" is LoopConditionExitNode -> "Exit loop condition"
is LoopExitNode -> "Exit ${fir.type()}loop" is LoopExitNode -> "Exit ${fir.type()}loop"
is QualifiedAccessNode -> "Access variable ${fir.calleeReference.render(CfgRenderMode)}" is QualifiedAccessNode -> "Access variable ${CfgRenderer.renderElementAsString(fir.calleeReference)}"
is ResolvedQualifierNode -> "Access qualifier ${fir.classId}" is ResolvedQualifierNode -> "Access qualifier ${fir.classId}"
is ComparisonExpressionNode -> "Comparison ${fir.operation.operator}" is ComparisonExpressionNode -> "Comparison ${fir.operation.operator}"
is TypeOperatorCallNode -> "Type operator: \"${fir.render(CfgRenderMode)}\"" is TypeOperatorCallNode -> "Type operator: \"${CfgRenderer.renderElementAsString(fir)}\""
is EqualityOperatorCallNode -> "Equality operator ${fir.operation.operator}" is EqualityOperatorCallNode -> "Equality operator ${fir.operation.operator}"
is JumpNode -> "Jump: ${fir.render()}" is JumpNode -> "Jump: ${fir.render()}"
is StubNode -> "Stub" is StubNode -> "Stub"
is CheckNotNullCallNode -> "Check not null: ${fir.render(CfgRenderMode)}" is CheckNotNullCallNode -> "Check not null: ${CfgRenderer.renderElementAsString(fir)}"
is ConstExpressionNode -> "Const: ${fir.render()}" is ConstExpressionNode -> "Const: ${fir.render()}"
is VariableDeclarationNode -> is VariableDeclarationNode ->
"Variable declaration: ${ "Variable declaration: ${
FirRenderer(mode = CfgRenderMode).renderAsCallableDeclarationString(fir) CfgRenderer.renderAsCallableDeclarationString(fir)
}" }"
is VariableAssignmentNode -> "Assignment: ${fir.lValue.render(CfgRenderMode)}" is VariableAssignmentNode -> "Assignment: ${CfgRenderer.renderElementAsString(fir.lValue)}"
is FunctionCallNode -> "Function call: ${fir.render(CfgRenderMode)}" is FunctionCallNode -> "Function call: ${CfgRenderer.renderElementAsString(fir)}"
is DelegatedConstructorCallNode -> "Delegated constructor call: ${fir.render(CfgRenderMode)}" is DelegatedConstructorCallNode -> "Delegated constructor call: ${CfgRenderer.renderElementAsString(fir)}"
is StringConcatenationCallNode -> "String concatenation call: ${fir.render(CfgRenderMode)}" is StringConcatenationCallNode -> "String concatenation call: ${CfgRenderer.renderElementAsString(fir)}"
is ThrowExceptionNode -> "Throw: ${fir.render(CfgRenderMode)}" is ThrowExceptionNode -> "Throw: ${CfgRenderer.renderElementAsString(fir)}"
is TryExpressionEnterNode -> "Try expression enter" is TryExpressionEnterNode -> "Try expression enter"
is TryMainBlockEnterNode -> "Try main block enter" is TryMainBlockEnterNode -> "Try main block enter"
@@ -123,7 +123,7 @@ fun CFGNode<*>.render(): String =
is ElvisRhsEnterNode -> "Enter rhs of ?:" is ElvisRhsEnterNode -> "Enter rhs of ?:"
is ElvisExitNode -> "Exit ?:" is ElvisExitNode -> "Exit ?:"
is CallableReferenceNode -> "Callable reference: ${fir.render(CfgRenderMode)}" is CallableReferenceNode -> "Callable reference: ${CfgRenderer.renderElementAsString(fir)}"
is GetClassCallNode -> "::class call" is GetClassCallNode -> "::class call"
is AbstractBinaryExitNode -> throw IllegalStateException() is AbstractBinaryExitNode -> throw IllegalStateException()
@@ -131,12 +131,14 @@ fun CFGNode<*>.render(): String =
) )
} }
private val CfgRenderMode = FirRenderer.RenderMode( // NB: renderer has a state, so we have to create it each time
renderCallArguments = false, private val CfgRenderer
renderCallableFqNames = false, get() = FirRenderer(
renderDeclarationResolvePhase = false, mode = FirRenderer.RenderMode(
renderAnnotation = false, renderCallArguments = false,
) renderCallableFqNames = false,
)
).with(annotationRenderer = null)
private fun FirFunction.name(): String = when (this) { private fun FirFunction.name(): String = when (this) {
is FirSimpleFunction -> name.asString() is FirSimpleFunction -> name.asString()
@@ -12,7 +12,12 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
open class FirAnnotationRenderer internal constructor(components: FirRendererComponents) : FirRendererComponents by components { open class FirAnnotationRenderer {
internal lateinit var components: FirRendererComponents
protected val visitor get() = components.visitor
protected val printer get() = components.printer
fun render(annotationContainer: FirAnnotationContainer) { fun render(annotationContainer: FirAnnotationContainer) {
renderAnnotations(annotationContainer.annotations) renderAnnotations(annotationContainer.annotations)
} }
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
class FirAnnotationWithArgumentsRenderer internal constructor(components: FirRendererComponents) : FirAnnotationRenderer(components) { class FirAnnotationWithArgumentsRenderer() : FirAnnotationRenderer() {
override fun FirAnnotation.renderArgumentMapping() { override fun FirAnnotation.renderArgumentMapping() {
printer.print("(") printer.print("(")
argumentMapping.mapping.renderSeparated() argumentMapping.mapping.renderSeparated()
@@ -7,10 +7,17 @@ package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.impl.FirLazyBlock import org.jetbrains.kotlin.fir.expressions.impl.FirLazyBlock
class FirBodyRenderer internal constructor(components: FirRendererComponents) : FirRendererComponents by components { class FirBodyRenderer {
internal lateinit var components: FirRendererComponents
private val annotationRenderer get() = components.annotationRenderer
private val visitor get() = components.visitor
private val printer get() = components.printer
fun render(function: FirFunction) { fun render(function: FirFunction) {
renderBody(function.body) renderBody(function.body)
@@ -33,4 +40,15 @@ class FirBodyRenderer internal constructor(components: FirRendererComponents) :
} }
} }
} }
fun renderDelegatedConstructor(delegatedConstructor: FirDelegatedConstructorCall?) {
if (delegatedConstructor != null) {
printer.renderInBraces {
delegatedConstructor.accept(visitor)
printer.println()
}
} else {
printer.println()
}
}
} }
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2022 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.fir.renderer
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
open class FirClassMemberRenderer {
internal lateinit var components: FirRendererComponents
protected val visitor get() = components.visitor
protected val printer get() = components.printer
open fun render(regularClass: FirRegularClass) {
render(regularClass.declarations)
}
open fun render(declarations: List<FirDeclaration>) {
printer.renderInBraces {
for (declaration in declarations) {
declaration.accept(visitor)
printer.println()
}
}
}
}
@@ -7,7 +7,11 @@ package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
open class FirDeclarationRenderer internal constructor(components: FirRendererComponents) : FirRendererComponents by components { open class FirDeclarationRenderer {
internal lateinit var components: FirRendererComponents
protected val printer get() = components.printer
fun render(declaration: FirDeclaration) { fun render(declaration: FirDeclaration) {
with(declaration) { with(declaration) {
renderDeclarationResolvePhase() renderDeclarationResolvePhase()
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import kotlin.reflect.KClass import kotlin.reflect.KClass
open class FirDeclarationRendererWithAttributes internal constructor(components: FirRendererComponents) : FirDeclarationRenderer(components) { open class FirDeclarationRendererWithAttributes : FirDeclarationRenderer() {
override fun FirDeclaration.renderDeclarationAttributes() { override fun FirDeclaration.renderDeclarationAttributes() {
if (attributes.isNotEmpty()) { if (attributes.isNotEmpty()) {
val attributes = getAttributesWithValues().mapNotNull { (klass, value) -> val attributes = getAttributesWithValues().mapNotNull { (klass, value) ->
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
class FirDeclarationRendererWithAttributesAndResolvePhase internal constructor( class FirDeclarationRendererWithAttributesAndResolvePhase : FirDeclarationRendererWithAttributes() {
components: FirRendererComponents
) : FirDeclarationRendererWithAttributes(components) {
override fun FirDeclaration.renderDeclarationResolvePhase() { override fun FirDeclaration.renderDeclarationResolvePhase() {
printer.print("[${resolvePhase}] ") printer.print("[${resolvePhase}] ")
} }
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
class FirDeclarationRendererWithResolvePhase internal constructor(components: FirRendererComponents) : FirDeclarationRenderer(components) { class FirDeclarationRendererWithResolvePhase : FirDeclarationRenderer() {
override fun FirDeclaration.renderDeclarationResolvePhase() { override fun FirDeclaration.renderDeclarationResolvePhase() {
printer.print("[${resolvePhase}] ") printer.print("[${resolvePhase}] ")
} }
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2022 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.fir.renderer
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
class FirNoClassMemberRenderer : FirClassMemberRenderer() {
override fun render(regularClass: FirRegularClass) {
}
override fun render(declarations: List<FirDeclaration>) {
}
}
@@ -7,7 +7,12 @@ package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.fir.FirPackageDirective import org.jetbrains.kotlin.fir.FirPackageDirective
class FirPackageDirectiveRenderer internal constructor(components: FirRendererComponents) : FirRendererComponents by components { class FirPackageDirectiveRenderer {
internal lateinit var components: FirRendererComponents
private val printer get() = components.printer
fun render(packageDirective: FirPackageDirective) { fun render(packageDirective: FirPackageDirective) {
if (!packageDirective.packageFqName.isRoot) { if (!packageDirective.packageFqName.isRoot) {
printer.println("package ${packageDirective.packageFqName.asString()}") printer.println("package ${packageDirective.packageFqName.asString()}")
@@ -34,9 +34,15 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.* import java.util.*
open class FirRenderer private constructor( open class FirRenderer private constructor(
builder: StringBuilder, private val builder: StringBuilder,
protected val mode: RenderMode, protected val mode: RenderMode,
components: FirComponentsImpl components: FirComponentsImpl,
private val annotationRenderer: FirAnnotationRenderer?,
private val bodyRenderer: FirBodyRenderer?,
private val classMemberRenderer: FirClassMemberRenderer,
private val declarationRenderer: FirDeclarationRenderer,
private val packageDirectiveRenderer: FirPackageDirectiveRenderer?,
private val typeRenderer: ConeTypeRenderer
) : FirPrinter(builder) { ) : FirPrinter(builder) {
companion object { companion object {
@@ -46,8 +52,57 @@ open class FirRenderer private constructor(
) )
} }
private val visitor = Visitor()
init {
components.visitor = visitor
components.annotationRenderer = annotationRenderer
components.bodyRenderer = bodyRenderer
components.classMemberRenderer = classMemberRenderer
components.declarationRenderer = declarationRenderer
components.packageDirectiveRenderer = packageDirectiveRenderer
components.typeRenderer = typeRenderer
@Suppress("LeakingThis")
components.printer = this
annotationRenderer?.components = components
bodyRenderer?.components = components
classMemberRenderer.components = components
declarationRenderer.components = components
packageDirectiveRenderer?.components = components
typeRenderer.builder = builder
}
private constructor(
builder: StringBuilder,
mode: RenderMode,
components: FirComponentsImpl,
) : this(
builder,
mode,
components,
FirAnnotationWithArgumentsRenderer(),
FirBodyRenderer(),
FirClassMemberRenderer(),
FirDeclarationRenderer(),
packageDirectiveRenderer = null,
ConeTypeRendererForDebugging(),
)
constructor(builder: StringBuilder = StringBuilder(), mode: RenderMode = RenderMode.Normal) : this(builder, mode, FirComponentsImpl()) constructor(builder: StringBuilder = StringBuilder(), mode: RenderMode = RenderMode.Normal) : this(builder, mode, FirComponentsImpl())
fun with(
annotationRenderer: FirAnnotationRenderer? = this.annotationRenderer,
bodyRenderer: FirBodyRenderer? = this.bodyRenderer,
classMemberRenderer: FirClassMemberRenderer = this.classMemberRenderer,
declarationRenderer: FirDeclarationRenderer = this.declarationRenderer,
packageDirectiveRenderer: FirPackageDirectiveRenderer? = this.packageDirectiveRenderer,
typeRenderer: ConeTypeRenderer = this.typeRenderer
): FirRenderer = FirRenderer(
builder, mode, FirComponentsImpl(),
annotationRenderer, bodyRenderer, classMemberRenderer,
declarationRenderer, packageDirectiveRenderer, typeRenderer
)
fun renderElementAsString(element: FirElement): String { fun renderElementAsString(element: FirElement): String {
element.accept(visitor) element.accept(visitor)
return toString() return toString()
@@ -69,6 +124,8 @@ open class FirRenderer private constructor(
override var packageDirectiveRenderer: FirPackageDirectiveRenderer? = null override var packageDirectiveRenderer: FirPackageDirectiveRenderer? = null
override lateinit var classMemberRenderer: FirClassMemberRenderer
override lateinit var declarationRenderer: FirDeclarationRenderer override lateinit var declarationRenderer: FirDeclarationRenderer
override lateinit var typeRenderer: ConeTypeRenderer override lateinit var typeRenderer: ConeTypeRenderer
@@ -81,118 +138,37 @@ open class FirRenderer private constructor(
data class RenderMode( data class RenderMode(
val renderCallArguments: Boolean, val renderCallArguments: Boolean,
val renderCallableFqNames: Boolean, val renderCallableFqNames: Boolean,
val renderDeclarationResolvePhase: Boolean,
val renderAnnotation: Boolean,
val renderBodies: Boolean = true,
val renderPropertyAccessors: Boolean = true, val renderPropertyAccessors: Boolean = true,
val renderDeclarationAttributes: Boolean = false,
val renderPackageDirective: Boolean = false,
val renderNestedDeclarations: Boolean = true,
val renderDefaultParameterValues: Boolean = true, val renderDefaultParameterValues: Boolean = true,
val renderDetailedTypeReferences: Boolean = true,
val renderAllModifiers: Boolean = true, val renderAllModifiers: Boolean = true,
) { ) {
companion object { companion object {
val Normal = RenderMode( val Normal = RenderMode(
renderCallArguments = true, renderCallArguments = true,
renderCallableFqNames = false, renderCallableFqNames = false,
renderDeclarationResolvePhase = false,
renderAnnotation = true,
) )
val WithFqNames = RenderMode( val WithFqNames = RenderMode(
renderCallArguments = true, renderCallArguments = true,
renderCallableFqNames = true, renderCallableFqNames = true,
renderDeclarationResolvePhase = false,
renderAnnotation = true,
)
val WithFqNamesExceptAnnotationAndBody = RenderMode(
renderCallArguments = true,
renderCallableFqNames = true,
renderDeclarationResolvePhase = false,
renderAnnotation = false,
renderBodies = false,
)
val WithResolvePhases = RenderMode(
renderCallArguments = true,
renderCallableFqNames = false,
renderDeclarationResolvePhase = true,
renderAnnotation = true,
) )
val NoBodies = RenderMode( val NoBodies = RenderMode(
renderCallArguments = false, renderCallArguments = false,
renderCallableFqNames = false, renderCallableFqNames = false,
renderDeclarationResolvePhase = false,
renderAnnotation = false,
renderBodies = false,
renderPropertyAccessors = false, renderPropertyAccessors = false,
) )
val DeclarationHeader = RenderMode( val DeclarationHeader = RenderMode(
renderCallArguments = false, renderCallArguments = false,
renderCallableFqNames = false, renderCallableFqNames = false,
renderDeclarationResolvePhase = false,
renderAnnotation = true,
renderBodies = false,
renderPropertyAccessors = false, renderPropertyAccessors = false,
renderDeclarationAttributes = false,
renderPackageDirective = false,
renderNestedDeclarations = false,
renderDefaultParameterValues = false, renderDefaultParameterValues = false,
renderDetailedTypeReferences = false,
renderAllModifiers = false, renderAllModifiers = false,
) )
val WithDeclarationAttributes = RenderMode(
renderCallArguments = true,
renderCallableFqNames = false,
renderDeclarationResolvePhase = false,
renderAnnotation = true,
renderDeclarationAttributes = true,
)
} }
} }
private val visitor = Visitor()
private val annotationRenderer = when {
mode.renderAnnotation ->
if (mode.renderCallArguments) FirAnnotationWithArgumentsRenderer(components) else FirAnnotationRenderer(components)
else ->
null
}
private val bodyRenderer =
if (mode.renderBodies) FirBodyRenderer(components) else null
private val declarationRenderer = when {
mode.renderDeclarationAttributes && mode.renderDeclarationResolvePhase ->
FirDeclarationRendererWithAttributesAndResolvePhase(components)
mode.renderDeclarationAttributes ->
FirDeclarationRendererWithAttributes(components)
mode.renderDeclarationResolvePhase ->
FirDeclarationRendererWithResolvePhase(components)
else -> FirDeclarationRenderer(components)
}
private val packageDirectiveRenderer = if (mode.renderPackageDirective) FirPackageDirectiveRenderer(components) else null
@Suppress("LeakingThis")
private val typeRenderer =
if (mode.renderDetailedTypeReferences) ConeTypeRendererForDebugging(builder) else ConeTypeRenderer(builder)
init {
components.visitor = visitor
components.annotationRenderer = annotationRenderer
components.bodyRenderer = bodyRenderer
components.declarationRenderer = declarationRenderer
components.packageDirectiveRenderer = packageDirectiveRenderer
components.typeRenderer = typeRenderer
@Suppress("LeakingThis")
components.printer = this
}
private fun List<FirElement>.renderSeparated() { private fun List<FirElement>.renderSeparated() {
for ((index, element) in this.withIndex()) { for ((index, element) in this.withIndex()) {
if (index > 0) { if (index > 0) {
@@ -291,15 +267,6 @@ open class FirRenderer private constructor(
} }
} }
protected fun List<FirDeclaration>.renderDeclarations() {
renderInBraces {
for (declaration in this) {
declaration.accept(visitor)
println()
}
}
}
fun renderSupertypes(regularClass: FirRegularClass) { fun renderSupertypes(regularClass: FirRegularClass) {
if (regularClass.superTypeRefs.isNotEmpty()) { if (regularClass.superTypeRefs.isNotEmpty()) {
print(" : ") print(" : ")
@@ -312,9 +279,7 @@ open class FirRenderer private constructor(
} }
protected open fun renderClassDeclarations(regularClass: FirRegularClass) { protected open fun renderClassDeclarations(regularClass: FirRegularClass) {
if (mode.renderNestedDeclarations) { classMemberRenderer.render(regularClass)
regularClass.declarations.renderDeclarations()
}
} }
private fun visitAssignment(operation: FirOperation, rValue: FirExpression) { private fun visitAssignment(operation: FirOperation, rValue: FirExpression) {
@@ -526,7 +491,7 @@ open class FirRenderer private constructor(
annotationRenderer?.render(anonymousObject) annotationRenderer?.render(anonymousObject)
print("object : ") print("object : ")
anonymousObject.superTypeRefs.renderSeparated() anonymousObject.superTypeRefs.renderSeparated()
anonymousObject.declarations.renderDeclarations() classMemberRenderer.render(anonymousObject.declarations)
} }
override fun visitVariable(variable: FirVariable) { override fun visitVariable(variable: FirVariable) {
@@ -614,15 +579,8 @@ open class FirRenderer private constructor(
constructor.returnTypeRef.accept(this) constructor.returnTypeRef.accept(this)
val body = constructor.body val body = constructor.body
val delegatedConstructor = constructor.delegatedConstructor val delegatedConstructor = constructor.delegatedConstructor
if (body == null && mode.renderBodies) { if (body == null) {
if (delegatedConstructor != null) { bodyRenderer?.renderDelegatedConstructor(delegatedConstructor)
renderInBraces {
delegatedConstructor.accept(this)
println()
}
} else {
println()
}
} }
bodyRenderer?.renderBody(body, listOfNotNull<FirStatement>(delegatedConstructor)) bodyRenderer?.renderBody(body, listOfNotNull<FirStatement>(delegatedConstructor))
} }
@@ -11,6 +11,7 @@ internal interface FirRendererComponents {
val declarationRenderer: FirDeclarationRenderer val declarationRenderer: FirDeclarationRenderer
val annotationRenderer: FirAnnotationRenderer? val annotationRenderer: FirAnnotationRenderer?
val bodyRenderer: FirBodyRenderer? val bodyRenderer: FirBodyRenderer?
val classMemberRenderer: FirClassMemberRenderer
val packageDirectiveRenderer: FirPackageDirectiveRenderer? val packageDirectiveRenderer: FirPackageDirectiveRenderer?
val typeRenderer: ConeTypeRenderer val typeRenderer: ConeTypeRenderer
} }
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.backend.createFilesWithGeneratedDeclarations
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.extensions.generatedMembers import org.jetbrains.kotlin.fir.extensions.generatedMembers
import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers import org.jetbrains.kotlin.fir.extensions.generatedNestedClassifiers
import org.jetbrains.kotlin.fir.renderer.FirClassMemberRenderer
import org.jetbrains.kotlin.fir.renderer.FirPackageDirectiveRenderer
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
@@ -37,7 +39,10 @@ class FirDumpHandler(
addAll(info.session.createFilesWithGeneratedDeclarations()) addAll(info.session.createFilesWithGeneratedDeclarations())
} }
val renderer = FirRendererWithGeneratedDeclarations(info.session, builderForModule) val renderer = FirRenderer(builderForModule).with(
packageDirectiveRenderer = FirPackageDirectiveRenderer(),
classMemberRenderer = FirClassMemberRendererWithGeneratedDeclarations(info.session)
)
allFiles.forEach { allFiles.forEach {
renderer.renderElementAsString(it) renderer.renderElementAsString(it)
} }
@@ -52,21 +57,14 @@ class FirDumpHandler(
assertions.assertEqualsToFile(expectedFile, actualText, message = { "Content is not equal" }) assertions.assertEqualsToFile(expectedFile, actualText, message = { "Content is not equal" })
} }
private class FirRendererWithGeneratedDeclarations( private class FirClassMemberRendererWithGeneratedDeclarations(val session: FirSession) : FirClassMemberRenderer() {
val session: FirSession, override fun render(regularClass: FirRegularClass) {
builder: StringBuilder,
) : FirRenderer(builder, modeWithPackageDirective) {
companion object {
val modeWithPackageDirective = RenderMode.Normal.copy(renderPackageDirective = true)
}
override fun renderClassDeclarations(regularClass: FirRegularClass) {
val allDeclarations = buildList { val allDeclarations = buildList {
addAll(regularClass.declarations) addAll(regularClass.declarations)
addAll(regularClass.generatedMembers(session)) addAll(regularClass.generatedMembers(session))
addAll(regularClass.generatedNestedClassifiers(session)) addAll(regularClass.generatedNestedClassifiers(session))
} }
allDeclarations.renderDeclarations() render(allDeclarations)
} }
} }
} }
@@ -136,7 +136,10 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
private fun SmartPrinter.printInfo(declaration: FirCallableDeclaration, scope: FirTypeScope, counter: SymbolCounter) { private fun SmartPrinter.printInfo(declaration: FirCallableDeclaration, scope: FirTypeScope, counter: SymbolCounter) {
print("[${declaration.origin}]: ") print("[${declaration.origin}]: ")
print(declaration.render(FirRenderer.RenderMode.NoBodies).trim()) val renderedDeclaration = FirRenderer(mode = FirRenderer.RenderMode.NoBodies).with(
annotationRenderer = null, bodyRenderer = null
).renderElementAsString(declaration).trim()
print(renderedDeclaration)
print(" from $scope") print(" from $scope")
println(" [id: ${counter.getIndex(declaration.symbol)}]") println(" [id: ${counter.getIndex(declaration.symbol)}]")
} }