From 76d5d3a2ecd46fbde077bdff6ce3023b79e69751 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 8 Jul 2022 12:02:08 +0200 Subject: [PATCH] Extract separate FirModifierRenderer --- ...legatedConstructorCall_this_unresolved.txt | 2 +- .../resolveCall/hiddenConstructor.txt | 2 +- .../singleCandidate/hiddenConstructor.txt | 2 +- .../diagnostics/FirDiagnosticRenderers.kt | 1 + .../fir/renderer/FirAllModifierRenderer.kt | 99 ++++++++++++ .../fir/renderer/FirModifierRenderer.kt | 82 ++++++++++ .../renderer/FirPartialModifierRenderer.kt | 60 +++++++ .../kotlin/fir/renderer/FirRenderer.kt | 147 ++---------------- .../fir/renderer/FirRendererComponents.kt | 1 + 9 files changed, 261 insertions(+), 135 deletions(-) create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAllModifierRenderer.kt create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirModifierRenderer.kt create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirPartialModifierRenderer.kt diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/delegatedConstructorCall_this_unresolved.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/delegatedConstructorCall_this_unresolved.txt index 741361f9057..2d36533bfbb 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/delegatedConstructorCall_this_unresolved.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/delegatedConstructorCall_this_unresolved.txt @@ -47,4 +47,4 @@ KtErrorCallInfo: typeArgumentsMapping = {} argumentMapping = {} ] - diagnostic = ERROR \ No newline at end of file + diagnostic = ERROR \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenConstructor.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenConstructor.txt index cbde5b2772e..8da3015e509 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenConstructor.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenConstructor.txt @@ -14,4 +14,4 @@ KtErrorCallInfo: typeArgumentsMapping = {} argumentMapping = {} ] - diagnostic = ERROR \ No newline at end of file + diagnostic = ERROR \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/hiddenConstructor.txt b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/hiddenConstructor.txt index 18f680bdd58..95fe3573fda 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/hiddenConstructor.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/hiddenConstructor.txt @@ -1,5 +1,5 @@ KtInapplicableCallCandidateInfo: - diagnostic = ERROR + diagnostic = ERROR candidate = KtSimpleFunctionCall: isImplicitInvoke = false partiallyAppliedSymbol = KtPartiallyAppliedSymbol: 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 d0754e5c978..2b727dd1c1e 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 @@ -35,6 +35,7 @@ object FirDiagnosticRenderers { classMemberRenderer = FirNoClassMemberRenderer(), bodyRenderer = null, callArgumentsRenderer = FirCallNoArgumentsRenderer(), + modifierRenderer = FirPartialModifierRenderer(), ).renderElementAsString(symbol.fir) is FirTypeParameterSymbol -> symbol.name.asString() else -> "???" diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAllModifierRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAllModifierRenderer.kt new file mode 100644 index 00000000000..8e656ce351a --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirAllModifierRenderer.kt @@ -0,0 +1,99 @@ +/* + * 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.descriptors.ClassKind +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.* + +class FirAllModifierRenderer : FirModifierRenderer() { + override fun renderModifiers(memberDeclaration: FirMemberDeclaration) { + if (memberDeclaration !is FirProperty || !memberDeclaration.isLocal) { + renderModifier(memberDeclaration.visibility.asString()) + renderModifier(memberDeclaration.modalityAsString()) + } + if (memberDeclaration.isExpect) { + renderModifier("expect") + } + if (memberDeclaration.isActual) { + renderModifier("actual") + } + if (memberDeclaration.isExternal) { + renderModifier("external") + } + if (memberDeclaration.isOverride) { + renderModifier("override") + } + if (memberDeclaration.isStatic) { + renderModifier("static") + } + if (memberDeclaration.isInner) { + renderModifier("inner") + } + + // `companion/data/fun` modifiers are only valid for FirRegularClass, but we render them to make sure they are not + // incorrectly loaded for other declarations during deserialization. + if (memberDeclaration.status.isCompanion) { + renderModifier("companion") + } + if (memberDeclaration.status.isData) { + renderModifier("data") + } + // All Java interfaces are considered `fun` (functional interfaces) for resolution purposes + // (see JavaSymbolProvider.createFirJavaClass). Don't render `fun` for Java interfaces; it's not a modifier in Java. + val isJavaInterface = + memberDeclaration is FirRegularClass && memberDeclaration.classKind == ClassKind.INTERFACE && memberDeclaration.isJava + if (memberDeclaration.status.isFun && !isJavaInterface) { + renderModifier("fun") + } + + if (memberDeclaration.isInline) { + renderModifier("inline") + } + if (memberDeclaration.isOperator) { + renderModifier("operator") + } + if (memberDeclaration.isInfix) { + renderModifier("infix") + } + if (memberDeclaration.isTailRec) { + renderModifier("tailrec") + } + if (memberDeclaration.isSuspend) { + renderModifier("suspend") + } + if (memberDeclaration.isConst) { + renderModifier("const") + } + if (memberDeclaration.isLateInit) { + renderModifier("lateinit") + } + } + + override fun renderModifiers(backingField: FirBackingField) { + renderModifier(backingField.visibility.asString()) + } + + override fun renderModifiers(constructor: FirConstructor) { + renderModifier(constructor.visibility.asString()) + if (constructor.isExpect) { + renderModifier("expect") + } + if (constructor.isActual) { + renderModifier("actual") + } + } + + override fun renderModifiers(propertyAccessor: FirPropertyAccessor) { + renderModifier(propertyAccessor.visibility.asString()) + if (propertyAccessor.isInline) { + renderModifier("inline") + } + if (propertyAccessor.isExternal) { + renderModifier("external") + } + } +} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirModifierRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirModifierRenderer.kt new file mode 100644 index 00000000000..4b1e500591d --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirModifierRenderer.kt @@ -0,0 +1,82 @@ +/* + * 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.descriptors.EffectiveVisibility +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.isOverride +import org.jetbrains.kotlin.fir.declarations.utils.modality +import org.jetbrains.kotlin.fir.types.FirFunctionTypeRef +import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly + +abstract class FirModifierRenderer { + internal lateinit var components: FirRendererComponents + protected val printer get() = components.printer + + abstract fun renderModifiers(memberDeclaration: FirMemberDeclaration) + abstract fun renderModifiers(backingField: FirBackingField) + abstract fun renderModifiers(constructor: FirConstructor) + abstract fun renderModifiers(propertyAccessor: FirPropertyAccessor) + open fun renderModifiers(valueParameter: FirValueParameter) { + if (valueParameter.isCrossinline) { + renderModifier("crossinline") + } + if (valueParameter.isNoinline) { + renderModifier("noinline") + } + if (valueParameter.isVararg) { + renderModifier("vararg") + } + } + + open fun renderModifiers(typeParameter: FirTypeParameter) { + if (typeParameter.isReified) { + renderModifier("reified") + } + } + + open fun renderModifiers(functionTypeRef: FirFunctionTypeRef) { + if (functionTypeRef.isSuspend) { + renderModifier("suspend") + } + } + + protected open fun renderModifier(modifier: String) { + printer.print("$modifier ") + } + + protected open fun Visibility.asString(effectiveVisibility: EffectiveVisibility? = null): String { + val itself = when (this) { + Visibilities.Unknown -> return "public?" + else -> toString() + } + if (effectiveVisibility == null) return itself + val effectiveAsVisibility = effectiveVisibility.toVisibility() + if (effectiveAsVisibility == this) return itself + if (effectiveAsVisibility == Visibilities.Private && this == Visibilities.PrivateToThis) return itself + if (this !in visibilitiesToRenderEffectiveSet) return itself + return itself + "[${effectiveVisibility.name}]" + } + + protected open fun FirMemberDeclaration.modalityAsString(): String { + return modality?.name?.toLowerCaseAsciiOnly() ?: run { + if (this is FirCallableDeclaration && this.isOverride) { + "open?" + } else { + "final?" + } + } + } + + companion object { + private val visibilitiesToRenderEffectiveSet = setOf( + Visibilities.Private, Visibilities.PrivateToThis, Visibilities.Internal, + Visibilities.Protected, Visibilities.Public, Visibilities.Local + ) + } +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirPartialModifierRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirPartialModifierRenderer.kt new file mode 100644 index 00000000000..a108a995d43 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/renderer/FirPartialModifierRenderer.kt @@ -0,0 +1,60 @@ +/* + * 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.descriptors.ClassKind +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.utils.* + +class FirPartialModifierRenderer : FirModifierRenderer() { + override fun renderModifiers(memberDeclaration: FirMemberDeclaration) { + if (memberDeclaration.isExpect) { + renderModifier("expect") + } + if (memberDeclaration.isActual) { + renderModifier("actual ") + } + if (memberDeclaration.isStatic) { + renderModifier("static ") + } + if (memberDeclaration.isInner) { + renderModifier("inner ") + } + // `companion/data/fun` modifiers are only valid for FirRegularClass, but we render them to make sure they are not + // incorrectly loaded for other declarations during deserialization. + if (memberDeclaration.status.isCompanion) { + renderModifier("companion ") + } + if (memberDeclaration.status.isData) { + renderModifier("data ") + } + // All Java interfaces are considered `fun` (functional interfaces) for resolution purposes + // (see JavaSymbolProvider.createFirJavaClass). Don't render `fun` for Java interfaces; it's not a modifier in Java. + val isJavaInterface = + memberDeclaration is FirRegularClass && memberDeclaration.classKind == ClassKind.INTERFACE && memberDeclaration.isJava + if (memberDeclaration.status.isFun && !isJavaInterface) { + renderModifier("fun ") + } + if (memberDeclaration.isSuspend) { + renderModifier("suspend") + } + } + + override fun renderModifiers(backingField: FirBackingField) { + } + + override fun renderModifiers(constructor: FirConstructor) { + if (constructor.isExpect) { + renderModifier("expect") + } + if (constructor.isActual) { + renderModifier("actual") + } + } + + override fun renderModifiers(propertyAccessor: FirPropertyAccessor) { + } +} 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 02607a99c57..d8e2741966d 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 @@ -5,10 +5,6 @@ package org.jetbrains.kotlin.fir.renderer -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.EffectiveVisibility -import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.contracts.* import org.jetbrains.kotlin.fir.contracts.description.ConeContractRenderer @@ -42,17 +38,11 @@ open class FirRenderer private constructor( private val callArgumentsRenderer: FirCallArgumentsRenderer, private val classMemberRenderer: FirClassMemberRenderer, private val declarationRenderer: FirDeclarationRenderer, + private val modifierRenderer: FirModifierRenderer, private val packageDirectiveRenderer: FirPackageDirectiveRenderer?, private val typeRenderer: ConeTypeRenderer ) : FirPrinter(builder) { - companion object { - private val visibilitiesToRenderEffectiveSet = setOf( - Visibilities.Private, Visibilities.PrivateToThis, Visibilities.Internal, - Visibilities.Protected, Visibilities.Public, Visibilities.Local - ) - } - private val visitor = Visitor() init { @@ -62,6 +52,7 @@ open class FirRenderer private constructor( components.callArgumentsRenderer = callArgumentsRenderer components.classMemberRenderer = classMemberRenderer components.declarationRenderer = declarationRenderer + components.modifierRenderer = modifierRenderer components.packageDirectiveRenderer = packageDirectiveRenderer components.typeRenderer = typeRenderer @Suppress("LeakingThis") @@ -71,6 +62,7 @@ open class FirRenderer private constructor( callArgumentsRenderer.components = components classMemberRenderer.components = components declarationRenderer.components = components + modifierRenderer.components = components packageDirectiveRenderer?.components = components typeRenderer.builder = builder } @@ -88,6 +80,7 @@ open class FirRenderer private constructor( FirCallArgumentsRenderer(), FirClassMemberRenderer(), FirDeclarationRenderer(), + FirAllModifierRenderer(), packageDirectiveRenderer = null, ConeTypeRendererForDebugging(), ) @@ -100,12 +93,13 @@ open class FirRenderer private constructor( callArgumentsRenderer: FirCallArgumentsRenderer = this.callArgumentsRenderer, classMemberRenderer: FirClassMemberRenderer = this.classMemberRenderer, declarationRenderer: FirDeclarationRenderer = this.declarationRenderer, + modifierRenderer: FirModifierRenderer = this.modifierRenderer, packageDirectiveRenderer: FirPackageDirectiveRenderer? = this.packageDirectiveRenderer, typeRenderer: ConeTypeRenderer = this.typeRenderer ): FirRenderer = FirRenderer( builder, mode, FirComponentsImpl(), annotationRenderer, bodyRenderer, callArgumentsRenderer, classMemberRenderer, - declarationRenderer, packageDirectiveRenderer, typeRenderer + declarationRenderer, modifierRenderer, packageDirectiveRenderer, typeRenderer ) fun renderElementAsString(element: FirElement): String { @@ -141,6 +135,8 @@ open class FirRenderer private constructor( override lateinit var declarationRenderer: FirDeclarationRenderer + override lateinit var modifierRenderer: FirModifierRenderer + override lateinit var typeRenderer: ConeTypeRenderer override lateinit var visitor: Visitor @@ -152,7 +148,6 @@ open class FirRenderer private constructor( val renderCallableFqNames: Boolean, val renderPropertyAccessors: Boolean = true, val renderDefaultParameterValues: Boolean = true, - val renderAllModifiers: Boolean = true, ) { companion object { val Normal = RenderMode( @@ -172,7 +167,6 @@ open class FirRenderer private constructor( renderCallableFqNames = false, renderPropertyAccessors = false, renderDefaultParameterValues = false, - renderAllModifiers = false, ) } } @@ -217,29 +211,6 @@ open class FirRenderer private constructor( popIndent() } - private fun Visibility.asString(effectiveVisibility: EffectiveVisibility? = null): String { - val itself = when (this) { - Visibilities.Unknown -> return "public?" - else -> toString() - } - if (effectiveVisibility == null) return itself - val effectiveAsVisibility = effectiveVisibility.toVisibility() - if (effectiveAsVisibility == this) return itself - if (effectiveAsVisibility == Visibilities.Private && this == Visibilities.PrivateToThis) return itself - if (this !in visibilitiesToRenderEffectiveSet) return itself - return itself + "[${effectiveVisibility.name}]" - } - - private fun FirMemberDeclaration.modalityAsString(): String { - return modality?.name?.toLowerCaseAsciiOnly() ?: run { - if (this is FirCallableDeclaration && this.isOverride) { - "open?" - } else { - "final?" - } - } - } - private fun List.renderTypeParameters() { if (isNotEmpty()) { print("<") @@ -350,73 +321,7 @@ open class FirRenderer private constructor( } override fun visitMemberDeclaration(memberDeclaration: FirMemberDeclaration) { - if (mode.renderAllModifiers && (memberDeclaration !is FirProperty || !memberDeclaration.isLocal)) { - // we can't access session.effectiveVisibilityResolver from here! - // print(memberDeclaration.visibility.asString(memberDeclaration.getEffectiveVisibility(...)) + " ") - print(memberDeclaration.visibility.asString() + " ") - print(memberDeclaration.modalityAsString() + " ") - } - if (memberDeclaration.isExpect) { - print("expect ") - } - if (memberDeclaration.isActual) { - print("actual ") - } - if (mode.renderAllModifiers) { - if (memberDeclaration.isExternal) { - print("external ") - } - if (memberDeclaration.isOverride) { - print("override ") - } - } - if (memberDeclaration.isStatic) { - print("static ") - } - if (memberDeclaration.isInner) { - print("inner ") - } - - // `companion/data/fun` modifiers are only valid for FirRegularClass, but we render them to make sure they are not - // incorrectly loaded for other declarations during deserialization. - if (memberDeclaration.status.isCompanion) { - print("companion ") - } - if (memberDeclaration.status.isData) { - print("data ") - } - // All Java interfaces are considered `fun` (functional interfaces) for resolution purposes - // (see JavaSymbolProvider.createFirJavaClass). Don't render `fun` for Java interfaces; it's not a modifier in Java. - val isJavaInterface = - memberDeclaration is FirRegularClass && memberDeclaration.classKind == ClassKind.INTERFACE && memberDeclaration.isJava - if (memberDeclaration.status.isFun && !isJavaInterface) { - print("fun ") - } - - if (mode.renderAllModifiers) { - if (memberDeclaration.isInline) { - print("inline ") - } - if (memberDeclaration.isOperator) { - print("operator ") - } - if (memberDeclaration.isInfix) { - print("infix ") - } - if (memberDeclaration.isTailRec) { - print("tailrec ") - } - if (memberDeclaration.isSuspend) { - print("suspend ") - } - if (memberDeclaration.isConst) { - print("const ") - } - if (memberDeclaration.isLateInit) { - print("lateinit ") - } - } - + modifierRenderer.renderModifiers(memberDeclaration) visitDeclaration(memberDeclaration as FirDeclaration) when (memberDeclaration) { is FirClassLikeDeclaration -> { @@ -526,7 +431,7 @@ open class FirRenderer private constructor( } override fun visitBackingField(backingField: FirBackingField) { - print(backingField.visibility.asString() + " ") + modifierRenderer.renderModifiers(backingField) print(": ") backingField.returnTypeRef.accept(this) @@ -546,15 +451,7 @@ open class FirRenderer private constructor( override fun visitConstructor(constructor: FirConstructor) { annotationRenderer?.render(constructor) - // we can't access session.effectiveVisibilityResolver from here! - // print(constructor.visibility.asString(constructor.getEffectiveVisibility(...)) + " ") - print(constructor.visibility.asString() + " ") - if (constructor.isExpect) { - print("expect ") - } - if (constructor.isActual) { - print("actual ") - } + modifierRenderer.renderModifiers(constructor) declarationRenderer.render(constructor) constructor.dispatchReceiverType?.let { @@ -577,9 +474,7 @@ open class FirRenderer private constructor( override fun visitPropertyAccessor(propertyAccessor: FirPropertyAccessor) { declarationRenderer.render(propertyAccessor) annotationRenderer?.render(propertyAccessor) - print(propertyAccessor.visibility.asString() + " ") - print(if (propertyAccessor.isInline) "inline " else "") - print(if (propertyAccessor.isExternal) "external " else "") + modifierRenderer.renderModifiers(propertyAccessor) print(if (propertyAccessor.isGetter) "get" else "set") propertyAccessor.valueParameters.renderParameters() print(": ") @@ -648,9 +543,7 @@ open class FirRenderer private constructor( override fun visitTypeParameter(typeParameter: FirTypeParameter) { annotationRenderer?.render(typeParameter) - if (typeParameter.isReified) { - print("reified ") - } + modifierRenderer.renderModifiers(typeParameter) typeParameter.variance.renderVariance() print(typeParameter.name) @@ -681,15 +574,7 @@ open class FirRenderer private constructor( override fun visitValueParameter(valueParameter: FirValueParameter) { declarationRenderer.render(valueParameter) annotationRenderer?.render(valueParameter) - if (valueParameter.isCrossinline) { - print("crossinline ") - } - if (valueParameter.isNoinline) { - print("noinline ") - } - if (valueParameter.isVararg) { - print("vararg ") - } + modifierRenderer.renderModifiers(valueParameter) if (valueParameter.name != SpecialNames.NO_NAME_PROVIDED) { print(valueParameter.name.toString() + ": ") } @@ -974,9 +859,7 @@ open class FirRenderer private constructor( annotationRenderer?.renderAnnotations(functionTypeRef.annotations.dropExtensionFunctionAnnotation()) print("( ") - if (functionTypeRef.isSuspend) { - print("suspend ") - } + modifierRenderer.renderModifiers(functionTypeRef) functionTypeRef.receiverTypeRef?.let { it.accept(this) print(".") 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 e10af84fcdc..a35269adba4 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 @@ -13,6 +13,7 @@ internal interface FirRendererComponents { val bodyRenderer: FirBodyRenderer? val callArgumentsRenderer: FirCallArgumentsRenderer val classMemberRenderer: FirClassMemberRenderer + val modifierRenderer: FirModifierRenderer val packageDirectiveRenderer: FirPackageDirectiveRenderer? val typeRenderer: ConeTypeRenderer } \ No newline at end of file