diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt index 0ebdd6433a9..26b534048e1 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt @@ -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.FirOuterClassTypeParameterRef 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.RenderMode.Companion.Normal import org.jetbrains.kotlin.fir.resolve.getContainingClass import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable @@ -583,7 +585,11 @@ internal class KtSymbolByFirBuilder constructor( returns() implies 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}" } } } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt index 93d251ccf96..fd0b517ed05 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt @@ -160,7 +160,10 @@ internal class KtFirTypeProvider( ?: this.typeArguments.mapNotNull { it.type }) 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." } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/firSymbolUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/firSymbolUtils.kt index 0d84efbfb05..b9a6ea152a1 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/firSymbolUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/firSymbolUtils.kt @@ -21,8 +21,9 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner 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.RenderMode.Companion.Normal import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.symbols.impl.* @@ -32,10 +33,14 @@ import org.jetbrains.kotlin.psi.KtDeclaration internal fun FirCallableSymbol<*>.invalidModalityError(): Nothing { + // TODO: renderWithTypes!!! + val rendered = FirRenderer().with( + declarationRenderer = FirDeclarationRendererWithResolvePhase() + ).renderElementAsString(fir) error( """|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() ) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/pointerUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/pointerUtils.kt index 0ed5d126cd7..d82dd4ecbca 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/pointerUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/symbols/pointers/pointerUtils.kt @@ -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.declarations.FirDeclaration 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.scopes.FirScope import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol @@ -54,7 +54,7 @@ internal fun FirBasedSymbol<*>.createSignature(): IdSignature = internal fun FirDeclaration.createSignature(): IdSignature { val signatureComposer = moduleData.session.ideSessionComponents.signatureComposer 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) = diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirLazyDeclarationResolveTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirLazyDeclarationResolveTest.kt index 2827acae0f2..aee2bdad628 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirLazyDeclarationResolveTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirLazyDeclarationResolveTest.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirResolvePhase 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.symbols.ensureResolved import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid @@ -51,8 +51,8 @@ abstract class AbstractFirLazyDeclarationResolveTest : AbstractLowLevelApiSingle } override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) { - val rendererOption = FirRenderer.RenderMode.WithDeclarationAttributes.copy(renderDeclarationResolvePhase = true) val resultBuilder = StringBuilder() + val renderer = FirRenderer(resultBuilder).with(declarationRenderer = FirDeclarationRendererWithAttributesAndResolvePhase()) resolveWithClearCaches(ktFile) { firResolveSession -> check(firResolveSession is LLFirSourceResolveSession) val declarationToResolve = firResolveSession @@ -63,7 +63,7 @@ abstract class AbstractFirLazyDeclarationResolveTest : AbstractLowLevelApiSingle declarationToResolve.ensureResolved(currentPhase) val firFile = firResolveSession.getOrBuildFirFile(ktFile) 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) firFile.ensureResolved(FirResolvePhase.BODY_RESOLVE) resultBuilder.append("\nFILE RAW TO BODY:\n") - resultBuilder.append(firFile.render(rendererOption)) + renderer.renderElementAsString(firFile) } testServices.assertions.assertEqualsToTestDataFileSibling(resultBuilder.toString()) diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirOnAirResolveTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirOnAirResolveTest.kt index 2c06ffbe7d7..cd113464c04 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirOnAirResolveTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractFirOnAirResolveTest.kt @@ -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.state.LLFirSourceResolveSession 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.RenderMode.Companion.Normal import org.jetbrains.kotlin.psi.KtAnnotated import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile @@ -35,7 +36,9 @@ abstract class AbstractFirOnAirResolveTest : AbstractLowLevelApiSingleFileTest() resolveWithClearCaches(ktFile) { firResolveSession -> check(firResolveSession is LLFirSourceResolveSession) 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) } } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractGetOrBuildFirTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractGetOrBuildFirTest.kt index f06528a14ed..5d82a6abf28 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractGetOrBuildFirTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractGetOrBuildFirTest.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerPro import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.declarations.FirImport import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.renderer.FirPackageDirectiveRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile @@ -59,13 +60,9 @@ abstract class AbstractGetOrBuildFirTest : AbstractLowLevelApiSingleFileTest() { private fun render(firElement: FirElement?): String = when (firElement) { null -> "null" 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() { val LOOK_UP_FOR_ELEMENT_OF_TYPE by stringDirective("LOOK_UP_FOR_ELEMENT_OF_TYPE") } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/AbstractInnerDeclarationsResolvePhaseTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/AbstractInnerDeclarationsResolvePhaseTest.kt index 50bd8ce6594..6183e3617e4 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/AbstractInnerDeclarationsResolvePhaseTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/AbstractInnerDeclarationsResolvePhaseTest.kt @@ -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.test.base.AbstractLowLevelApiSingleFileTest 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.RenderMode.Companion.Normal import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.services.TestModuleStructure import org.jetbrains.kotlin.test.services.TestServices @@ -20,7 +21,9 @@ abstract class AbstractInnerDeclarationsResolvePhaseTest : AbstractLowLevelApiSi override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) { resolveWithClearCaches(ktFile) { firResolveSession -> val firFile = ktFile.getOrBuildFirOfType(firResolveSession) - val actual = firFile.render(FirRenderer.RenderMode.WithResolvePhases) + val actual = FirRenderer().with( + declarationRenderer = FirDeclarationRendererWithResolvePhase() + ).renderElementAsString(firFile) testServices.assertions.assertEqualsToTestDataFileSibling(actual, extension = ".fir.txt") } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt index 970e796d9a4..45d584a867d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt @@ -14,7 +14,11 @@ import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.declarations.utils.* 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.RenderMode.Companion.WithFqNames import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.* @@ -27,7 +31,14 @@ object FirDiagnosticRenderers { val SYMBOL = Renderer { symbol: FirBasedSymbol<*> -> when (symbol) { 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() else -> "???" } @@ -94,7 +105,9 @@ object FirDiagnosticRenderers { val FQ_NAMES_IN_TYPES = Renderer { symbol: FirBasedSymbol<*> -> @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> -> diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRenderer.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRenderer.kt index b0d5da0ce5b..6013500745c 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRenderer.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRenderer.kt @@ -11,7 +11,13 @@ import org.jetbrains.kotlin.name.ClassId import kotlin.contracts.ExperimentalContracts 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( type: ConeKotlinType, renderType: ConeTypeProjection.() -> Unit = { render() } diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererForDebugging.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererForDebugging.kt index 45340d2d04b..394db4a3ffc 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererForDebugging.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererForDebugging.kt @@ -8,7 +8,12 @@ package org.jetbrains.kotlin.fir.renderer import org.jetbrains.kotlin.fir.types.ConeKotlinType 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) { builder.append("R|") super.renderAsPossibleFunctionType(type, renderType) diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererWithFqNames.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererWithFqNames.kt index 756db8f3e9d..50cc9d8aedc 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererWithFqNames.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/renderer/ConeTypeRendererWithFqNames.kt @@ -7,7 +7,12 @@ package org.jetbrains.kotlin.fir.renderer 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() { builder.append(asString()) } diff --git a/compiler/fir/raw-fir/light-tree2fir/tests/org/jetbrains/kotlin/fir/lightTree/AbstractLightTree2FirConverterTestCase.kt b/compiler/fir/raw-fir/light-tree2fir/tests/org/jetbrains/kotlin/fir/lightTree/AbstractLightTree2FirConverterTestCase.kt index cfb7d07d797..27d4fe1c8eb 100644 --- a/compiler/fir/raw-fir/light-tree2fir/tests/org/jetbrains/kotlin/fir/lightTree/AbstractLightTree2FirConverterTestCase.kt +++ b/compiler/fir/raw-fir/light-tree2fir/tests/org/jetbrains/kotlin/fir/lightTree/AbstractLightTree2FirConverterTestCase.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lightTree import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider 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.session.FirSessionFactory import org.jetbrains.kotlin.test.KotlinTestUtils @@ -23,7 +24,7 @@ abstract class AbstractLightTree2FirConverterTestCase : AbstractRawFirBuilderTes scopeProvider = StubFirScopeProvider, diagnosticsReporter = null ).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")) KotlinTestUtils.assertEqualsToFile(expectedFile, firDump) diff --git a/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderTestCase.kt b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderTestCase.kt index 67db1b6c65f..cf233c6a813 100644 --- a/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderTestCase.kt +++ b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderTestCase.kt @@ -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.FirStubStatement 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.session.FirSessionFactory import org.jetbrains.kotlin.fir.types.FirTypeProjection @@ -65,7 +66,7 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase( protected open fun doRawFirTest(filePath: String) { val file = createKtFile(filePath) 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") KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump) } diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt index 6fb148a8c98..8a53b22deba 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt @@ -39,26 +39,26 @@ fun CFGNode<*>.render(): String = is LoopConditionExitNode -> "Exit loop condition" 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 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 JumpNode -> "Jump: ${fir.render()}" 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 VariableDeclarationNode -> "Variable declaration: ${ - FirRenderer(mode = CfgRenderMode).renderAsCallableDeclarationString(fir) + CfgRenderer.renderAsCallableDeclarationString(fir) }" - is VariableAssignmentNode -> "Assignment: ${fir.lValue.render(CfgRenderMode)}" - is FunctionCallNode -> "Function call: ${fir.render(CfgRenderMode)}" - is DelegatedConstructorCallNode -> "Delegated constructor call: ${fir.render(CfgRenderMode)}" - is StringConcatenationCallNode -> "String concatenation call: ${fir.render(CfgRenderMode)}" - is ThrowExceptionNode -> "Throw: ${fir.render(CfgRenderMode)}" + is VariableAssignmentNode -> "Assignment: ${CfgRenderer.renderElementAsString(fir.lValue)}" + is FunctionCallNode -> "Function call: ${CfgRenderer.renderElementAsString(fir)}" + is DelegatedConstructorCallNode -> "Delegated constructor call: ${CfgRenderer.renderElementAsString(fir)}" + is StringConcatenationCallNode -> "String concatenation call: ${CfgRenderer.renderElementAsString(fir)}" + is ThrowExceptionNode -> "Throw: ${CfgRenderer.renderElementAsString(fir)}" is TryExpressionEnterNode -> "Try expression enter" is TryMainBlockEnterNode -> "Try main block enter" @@ -123,7 +123,7 @@ fun CFGNode<*>.render(): String = is ElvisRhsEnterNode -> "Enter rhs of ?:" is ElvisExitNode -> "Exit ?:" - is CallableReferenceNode -> "Callable reference: ${fir.render(CfgRenderMode)}" + is CallableReferenceNode -> "Callable reference: ${CfgRenderer.renderElementAsString(fir)}" is GetClassCallNode -> "::class call" is AbstractBinaryExitNode -> throw IllegalStateException() @@ -131,12 +131,14 @@ fun CFGNode<*>.render(): String = ) } -private val CfgRenderMode = FirRenderer.RenderMode( - renderCallArguments = false, - renderCallableFqNames = false, - renderDeclarationResolvePhase = false, - renderAnnotation = false, -) +// NB: renderer has a state, so we have to create it each time +private val CfgRenderer + get() = FirRenderer( + mode = FirRenderer.RenderMode( + renderCallArguments = false, + renderCallableFqNames = false, + ) + ).with(annotationRenderer = null) private fun FirFunction.name(): String = when (this) { is FirSimpleFunction -> name.asString() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAnnotationRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAnnotationRenderer.kt index c3746ed332c..70ee6236a61 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAnnotationRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAnnotationRenderer.kt @@ -12,7 +12,12 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.references.FirErrorNamedReference 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) { renderAnnotations(annotationContainer.annotations) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAnnotationWithArgumentsRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAnnotationWithArgumentsRenderer.kt index 96da3bb37c8..6d95538f04c 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAnnotationWithArgumentsRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAnnotationWithArgumentsRenderer.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.name.Name -class FirAnnotationWithArgumentsRenderer internal constructor(components: FirRendererComponents) : FirAnnotationRenderer(components) { +class FirAnnotationWithArgumentsRenderer() : FirAnnotationRenderer() { override fun FirAnnotation.renderArgumentMapping() { printer.print("(") argumentMapping.mapping.renderSeparated() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirBodyRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirBodyRenderer.kt index d0be2c62e94..8ab7762a527 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirBodyRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirBodyRenderer.kt @@ -7,10 +7,17 @@ package org.jetbrains.kotlin.fir.renderer import org.jetbrains.kotlin.fir.declarations.FirFunction 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.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) { 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() + } + } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirClassMemberRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirClassMemberRenderer.kt new file mode 100644 index 00000000000..b9c92c9bda9 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirClassMemberRenderer.kt @@ -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) { + printer.renderInBraces { + for (declaration in declarations) { + declaration.accept(visitor) + printer.println() + } + } + } +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRenderer.kt index d400f67154f..718ef18cd30 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRenderer.kt @@ -7,7 +7,11 @@ package org.jetbrains.kotlin.fir.renderer 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) { with(declaration) { renderDeclarationResolvePhase() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithAttributes.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithAttributes.kt index f26186bbbab..d13976b923c 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithAttributes.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithAttributes.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import kotlin.reflect.KClass -open class FirDeclarationRendererWithAttributes internal constructor(components: FirRendererComponents) : FirDeclarationRenderer(components) { +open class FirDeclarationRendererWithAttributes : FirDeclarationRenderer() { override fun FirDeclaration.renderDeclarationAttributes() { if (attributes.isNotEmpty()) { val attributes = getAttributesWithValues().mapNotNull { (klass, value) -> diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithAttributesAndResolvePhase.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithAttributesAndResolvePhase.kt index 09b57828f46..de9719a4791 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithAttributesAndResolvePhase.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithAttributesAndResolvePhase.kt @@ -7,9 +7,7 @@ package org.jetbrains.kotlin.fir.renderer import org.jetbrains.kotlin.fir.declarations.FirDeclaration -class FirDeclarationRendererWithAttributesAndResolvePhase internal constructor( - components: FirRendererComponents -) : FirDeclarationRendererWithAttributes(components) { +class FirDeclarationRendererWithAttributesAndResolvePhase : FirDeclarationRendererWithAttributes() { override fun FirDeclaration.renderDeclarationResolvePhase() { printer.print("[${resolvePhase}] ") } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithResolvePhase.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithResolvePhase.kt index a0acc07ec06..3ccc6f35463 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithResolvePhase.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirDeclarationRendererWithResolvePhase.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.renderer import org.jetbrains.kotlin.fir.declarations.FirDeclaration -class FirDeclarationRendererWithResolvePhase internal constructor(components: FirRendererComponents) : FirDeclarationRenderer(components) { +class FirDeclarationRendererWithResolvePhase : FirDeclarationRenderer() { override fun FirDeclaration.renderDeclarationResolvePhase() { printer.print("[${resolvePhase}] ") } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirNoClassMemberRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirNoClassMemberRenderer.kt new file mode 100644 index 00000000000..746cf5be456 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirNoClassMemberRenderer.kt @@ -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) { + } +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirPackageDirectiveRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirPackageDirectiveRenderer.kt index 2d3bec72610..05af91542d5 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirPackageDirectiveRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirPackageDirectiveRenderer.kt @@ -7,7 +7,12 @@ package org.jetbrains.kotlin.fir.renderer 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) { if (!packageDirective.packageFqName.isRoot) { printer.println("package ${packageDirective.packageFqName.asString()}") diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt index 74231ae4ef7..3cf771b85a7 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRenderer.kt @@ -34,9 +34,15 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.util.* open class FirRenderer private constructor( - builder: StringBuilder, + private val builder: StringBuilder, 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) { 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()) + 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 { element.accept(visitor) return toString() @@ -69,6 +124,8 @@ open class FirRenderer private constructor( override var packageDirectiveRenderer: FirPackageDirectiveRenderer? = null + override lateinit var classMemberRenderer: FirClassMemberRenderer + override lateinit var declarationRenderer: FirDeclarationRenderer override lateinit var typeRenderer: ConeTypeRenderer @@ -81,118 +138,37 @@ open class FirRenderer private constructor( data class RenderMode( val renderCallArguments: Boolean, val renderCallableFqNames: Boolean, - val renderDeclarationResolvePhase: Boolean, - val renderAnnotation: Boolean, - val renderBodies: Boolean = true, val renderPropertyAccessors: Boolean = true, - val renderDeclarationAttributes: Boolean = false, - val renderPackageDirective: Boolean = false, - val renderNestedDeclarations: Boolean = true, val renderDefaultParameterValues: Boolean = true, - val renderDetailedTypeReferences: Boolean = true, val renderAllModifiers: Boolean = true, ) { companion object { val Normal = RenderMode( renderCallArguments = true, renderCallableFqNames = false, - renderDeclarationResolvePhase = false, - renderAnnotation = true, ) val WithFqNames = RenderMode( renderCallArguments = 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( renderCallArguments = false, renderCallableFqNames = false, - renderDeclarationResolvePhase = false, - renderAnnotation = false, - renderBodies = false, renderPropertyAccessors = false, ) val DeclarationHeader = RenderMode( renderCallArguments = false, renderCallableFqNames = false, - renderDeclarationResolvePhase = false, - renderAnnotation = true, - renderBodies = false, renderPropertyAccessors = false, - renderDeclarationAttributes = false, - renderPackageDirective = false, - renderNestedDeclarations = false, renderDefaultParameterValues = false, - renderDetailedTypeReferences = 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.renderSeparated() { for ((index, element) in this.withIndex()) { if (index > 0) { @@ -291,15 +267,6 @@ open class FirRenderer private constructor( } } - protected fun List.renderDeclarations() { - renderInBraces { - for (declaration in this) { - declaration.accept(visitor) - println() - } - } - } - fun renderSupertypes(regularClass: FirRegularClass) { if (regularClass.superTypeRefs.isNotEmpty()) { print(" : ") @@ -312,9 +279,7 @@ open class FirRenderer private constructor( } protected open fun renderClassDeclarations(regularClass: FirRegularClass) { - if (mode.renderNestedDeclarations) { - regularClass.declarations.renderDeclarations() - } + classMemberRenderer.render(regularClass) } private fun visitAssignment(operation: FirOperation, rValue: FirExpression) { @@ -526,7 +491,7 @@ open class FirRenderer private constructor( annotationRenderer?.render(anonymousObject) print("object : ") anonymousObject.superTypeRefs.renderSeparated() - anonymousObject.declarations.renderDeclarations() + classMemberRenderer.render(anonymousObject.declarations) } override fun visitVariable(variable: FirVariable) { @@ -614,15 +579,8 @@ open class FirRenderer private constructor( constructor.returnTypeRef.accept(this) val body = constructor.body val delegatedConstructor = constructor.delegatedConstructor - if (body == null && mode.renderBodies) { - if (delegatedConstructor != null) { - renderInBraces { - delegatedConstructor.accept(this) - println() - } - } else { - println() - } + if (body == null) { + bodyRenderer?.renderDelegatedConstructor(delegatedConstructor) } bodyRenderer?.renderBody(body, listOfNotNull(delegatedConstructor)) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRendererComponents.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRendererComponents.kt index 56c388798b8..3464efd0e45 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRendererComponents.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirRendererComponents.kt @@ -11,6 +11,7 @@ internal interface FirRendererComponents { val declarationRenderer: FirDeclarationRenderer val annotationRenderer: FirAnnotationRenderer? val bodyRenderer: FirBodyRenderer? + val classMemberRenderer: FirClassMemberRenderer val packageDirectiveRenderer: FirPackageDirectiveRenderer? val typeRenderer: ConeTypeRenderer } \ No newline at end of file diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirDumpHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirDumpHandler.kt index ed6cdf9b891..6a2fdf30a5d 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirDumpHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirDumpHandler.kt @@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.backend.createFilesWithGeneratedDeclarations import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.extensions.generatedMembers 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.test.directives.FirDiagnosticsDirectives import org.jetbrains.kotlin.test.directives.model.DirectivesContainer @@ -37,7 +39,10 @@ class FirDumpHandler( addAll(info.session.createFilesWithGeneratedDeclarations()) } - val renderer = FirRendererWithGeneratedDeclarations(info.session, builderForModule) + val renderer = FirRenderer(builderForModule).with( + packageDirectiveRenderer = FirPackageDirectiveRenderer(), + classMemberRenderer = FirClassMemberRendererWithGeneratedDeclarations(info.session) + ) allFiles.forEach { renderer.renderElementAsString(it) } @@ -52,21 +57,14 @@ class FirDumpHandler( assertions.assertEqualsToFile(expectedFile, actualText, message = { "Content is not equal" }) } - private class FirRendererWithGeneratedDeclarations( - val session: FirSession, - builder: StringBuilder, - ) : FirRenderer(builder, modeWithPackageDirective) { - companion object { - val modeWithPackageDirective = RenderMode.Normal.copy(renderPackageDirective = true) - } - - override fun renderClassDeclarations(regularClass: FirRegularClass) { + private class FirClassMemberRendererWithGeneratedDeclarations(val session: FirSession) : FirClassMemberRenderer() { + override fun render(regularClass: FirRegularClass) { val allDeclarations = buildList { addAll(regularClass.declarations) addAll(regularClass.generatedMembers(session)) addAll(regularClass.generatedNestedClassifiers(session)) } - allDeclarations.renderDeclarations() + render(allDeclarations) } } } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirScopeDumpHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirScopeDumpHandler.kt index a67e9262c63..a788f7734f7 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirScopeDumpHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/handlers/FirScopeDumpHandler.kt @@ -136,7 +136,10 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS private fun SmartPrinter.printInfo(declaration: FirCallableDeclaration, scope: FirTypeScope, counter: SymbolCounter) { 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") println(" [id: ${counter.getIndex(declaration.symbol)}]") }