[FIR generator] Factor out element printer to common module

This is a step towards commonizing the code generator between
FIR and IR: KT-61970
This commit is contained in:
Sergej Jaskiewicz
2023-09-07 19:36:41 +02:00
committed by Space Team
parent 84bd12c667
commit 63e9dd588c
70 changed files with 380 additions and 153 deletions
@@ -20,6 +20,7 @@ internal class FirContractElementDeclarationImpl(
override val source: KtSourceElement?,
override val effect: ConeContractDescriptionElement,
) : FirContractElementDeclaration() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirContractElementDeclarationImpl {
@@ -20,6 +20,7 @@ internal class FirEffectDeclarationImpl(
override val source: KtSourceElement?,
override val effect: ConeEffectDeclaration,
) : FirEffectDeclaration() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirEffectDeclarationImpl {
@@ -22,6 +22,7 @@ internal class FirLegacyRawContractDescriptionImpl(
override var contractCall: FirFunctionCall,
override val diagnostic: ConeDiagnostic?,
) : FirLegacyRawContractDescription() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
contractCall.accept(visitor, data)
}
@@ -21,6 +21,7 @@ internal class FirRawContractDescriptionImpl(
override val source: KtSourceElement?,
override val rawEffects: MutableList<FirExpression>,
) : FirRawContractDescription() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
rawEffects.forEach { it.accept(visitor, data) }
}
@@ -25,6 +25,7 @@ internal class FirResolvedContractDescriptionImpl(
override val unresolvedEffects: MutableList<FirContractElementDeclaration>,
override val diagnostic: ConeDiagnostic?,
) : FirResolvedContractDescription() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
effects.forEach { it.accept(visitor, data) }
unresolvedEffects.forEach { it.accept(visitor, data) }
@@ -57,6 +57,7 @@ internal class FirAnonymousFunctionImpl(
override val typeParameters: MutableList<FirTypeParameter>,
override var typeRef: FirTypeRef,
) : FirAnonymousFunction() {
init {
symbol.bind(this)
resolveState = resolvePhase.asResolveState()
@@ -55,6 +55,7 @@ open class FirBackingFieldImpl @FirImplementationDetail constructor(
override val typeParameters: MutableList<FirTypeParameter>,
override var status: FirDeclarationStatus,
) : FirBackingField() {
init {
symbol.bind(this)
resolveState = resolvePhase.asResolveState()
@@ -33,6 +33,7 @@ internal class FirCodeFragmentImpl(
override val symbol: FirCodeFragmentSymbol,
override var block: FirBlock,
) : FirCodeFragment() {
init {
symbol.bind(this)
resolveState = resolvePhase.asResolveState()
@@ -20,6 +20,7 @@ internal class FirConstructedClassTypeParameterRefImpl(
override val source: KtSourceElement?,
override val symbol: FirTypeParameterSymbol,
) : FirConstructedClassTypeParameterRef() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirConstructedClassTypeParameterRefImpl {
@@ -23,6 +23,7 @@ internal class FirContextReceiverImpl(
override val customLabelName: Name?,
override val labelNameFromTypeRef: Name?,
) : FirContextReceiver() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
}
@@ -33,6 +33,7 @@ internal class FirDanglingModifierListImpl(
override val diagnostic: ConeDiagnostic,
override val symbol: FirDanglingModifierSymbol,
) : FirDanglingModifierList() {
init {
symbol.bind(this)
resolveState = resolvePhase.asResolveState()
@@ -24,6 +24,7 @@ internal class FirImportImpl(
override val aliasName: Name?,
override val aliasSource: KtSourceElement?,
) : FirImport() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirImportImpl {
@@ -21,6 +21,7 @@ class FirOuterClassTypeParameterRefImpl @FirImplementationDetail constructor(
override val source: KtSourceElement?,
override val symbol: FirTypeParameterSymbol,
) : FirOuterClassTypeParameterRef() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirOuterClassTypeParameterRefImpl {
@@ -25,6 +25,7 @@ internal class FirReceiverParameterImpl(
override var typeRef: FirTypeRef,
override var annotations: MutableOrEmptyList<FirAnnotation>,
) : FirReceiverParameter() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
annotations.forEach { it.accept(visitor, data) }
@@ -38,6 +38,7 @@ internal class FirScriptImpl(
override var contextReceivers: MutableOrEmptyList<FirContextReceiver>,
override val resultPropertyName: Name?,
) : FirScript() {
init {
symbol.bind(this)
resolveState = resolvePhase.asResolveState()
@@ -38,6 +38,7 @@ internal class FirTypeAliasImpl(
override var expandedTypeRef: FirTypeRef,
override var annotations: MutableOrEmptyList<FirAnnotation>,
) : FirTypeAlias() {
init {
symbol.bind(this)
resolveState = resolvePhase.asResolveState()
@@ -40,6 +40,7 @@ internal class FirTypeParameterImpl(
override val bounds: MutableList<FirTypeRef>,
override var annotations: MutableOrEmptyList<FirAnnotation>,
) : FirTypeParameter() {
init {
symbol.bind(this)
resolveState = resolvePhase.asResolveState()
@@ -30,6 +30,7 @@ internal class FirArrayLiteralImpl(
override var annotations: MutableOrEmptyList<FirAnnotation>,
override var argumentList: FirArgumentList,
) : FirArrayLiteral() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
argumentList.accept(visitor, data)
@@ -28,6 +28,7 @@ internal class FirAssignmentOperatorStatementImpl(
override var leftArgument: FirExpression,
override var rightArgument: FirExpression,
) : FirAssignmentOperatorStatement() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
leftArgument.accept(visitor, data)
@@ -28,6 +28,7 @@ internal class FirAugmentedArraySetCallImpl(
override var calleeReference: FirReference,
override val arrayAccessSource: KtSourceElement?,
) : FirAugmentedArraySetCall() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
lhsGetCall.accept(visitor, data)
@@ -33,6 +33,7 @@ internal class FirBinaryLogicExpressionImpl(
override var rightOperand: FirExpression,
override val kind: LogicOperationKind,
) : FirBinaryLogicExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
leftOperand.accept(visitor, data)
@@ -30,6 +30,7 @@ internal class FirBlockImpl(
override var annotations: MutableOrEmptyList<FirAnnotation>,
override val statements: MutableList<FirStatement>,
) : FirBlock() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
statements.forEach { it.accept(visitor, data) }
@@ -42,6 +42,7 @@ internal class FirCallableReferenceAccessImpl(
override var calleeReference: FirNamedReference,
override var hasQuestionMarkAtLHS: Boolean,
) : FirCallableReferenceAccess() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
contextReceiverArguments.forEach { it.accept(visitor, data) }
@@ -22,6 +22,7 @@ internal class FirCatchImpl(
override var parameter: FirProperty,
override var block: FirBlock,
) : FirCatch() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
parameter.accept(visitor, data)
block.accept(visitor, data)
@@ -32,6 +32,7 @@ internal class FirCheckNotNullCallImpl(
override var argumentList: FirArgumentList,
override var calleeReference: FirReference,
) : FirCheckNotNullCall() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
argumentList.accept(visitor, data)
@@ -31,6 +31,7 @@ internal class FirCheckedSafeCallSubjectImpl(
override var annotations: MutableOrEmptyList<FirAnnotation>,
override val originalReceiverRef: FirExpressionRef<FirExpression>,
) : FirCheckedSafeCallSubject() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
}
@@ -30,6 +30,7 @@ internal class FirClassReferenceExpressionImpl(
override var annotations: MutableOrEmptyList<FirAnnotation>,
override var classTypeRef: FirTypeRef,
) : FirClassReferenceExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
classTypeRef.accept(visitor, data)
@@ -31,6 +31,7 @@ internal class FirConstExpressionImpl<T> (
override var kind: ConstantValueKind<T>,
override val value: T,
) : FirConstExpression<T>() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
}
@@ -31,6 +31,7 @@ internal class FirDesugaredAssignmentValueReferenceExpressionImpl(
override var annotations: MutableOrEmptyList<FirAnnotation>,
override val expressionRef: FirExpressionRef<FirExpression>,
) : FirDesugaredAssignmentValueReferenceExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
}
@@ -29,6 +29,7 @@ internal class FirDoWhileLoopImpl(
override var condition: FirExpression,
override var label: FirLabel?,
) : FirDoWhileLoop() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
block.accept(visitor, data)
@@ -33,6 +33,7 @@ internal class FirElvisExpressionImpl(
override var lhs: FirExpression,
override var rhs: FirExpression,
) : FirElvisExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
calleeReference.accept(visitor, data)
@@ -29,6 +29,7 @@ class FirExpressionStub @FirImplementationDetail constructor(
override var coneTypeOrNull: ConeKotlinType?,
override var annotations: MutableOrEmptyList<FirAnnotation>,
) : FirExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
}
@@ -40,6 +40,7 @@ open class FirFunctionCallImpl @FirImplementationDetail constructor(
override var calleeReference: FirNamedReference,
override val origin: FirFunctionCallOrigin,
) : FirFunctionCall() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
contextReceiverArguments.forEach { it.accept(visitor, data) }
@@ -31,6 +31,7 @@ internal class FirInaccessibleReceiverExpressionImpl(
override var annotations: MutableOrEmptyList<FirAnnotation>,
override var calleeReference: FirThisReference,
) : FirInaccessibleReceiverExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
calleeReference.accept(visitor, data)
@@ -34,6 +34,7 @@ internal class FirIncrementDecrementExpressionImpl(
override var expression: FirExpression,
override val operationSource: KtSourceElement?,
) : FirIncrementDecrementExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
expression.accept(visitor, data)
@@ -40,6 +40,7 @@ internal class FirIntegerLiteralOperatorCallImpl(
override var dispatchReceiver: FirExpression?,
override var extensionReceiver: FirExpression?,
) : FirIntegerLiteralOperatorCall() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
contextReceiverArguments.forEach { it.accept(visitor, data) }
@@ -40,6 +40,7 @@ class FirPropertyAccessExpressionImpl @FirImplementationDetail constructor(
override var source: KtSourceElement?,
override var nonFatalDiagnostics: MutableOrEmptyList<ConeDiagnostic>,
) : FirPropertyAccessExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
calleeReference.accept(visitor, data)
@@ -30,6 +30,7 @@ internal class FirResolvedReifiedParameterReferenceImpl(
override var annotations: MutableOrEmptyList<FirAnnotation>,
override val symbol: FirTypeParameterSymbol,
) : FirResolvedReifiedParameterReference() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
}
@@ -30,6 +30,7 @@ internal class FirSafeCallExpressionImpl(
override val checkedSubjectRef: FirExpressionRef<FirCheckedSafeCallSubject>,
override var selector: FirStatement,
) : FirSafeCallExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
receiver.accept(visitor, data)
@@ -31,6 +31,7 @@ internal class FirTryExpressionImpl(
override val catches: MutableList<FirCatch>,
override var finallyBlock: FirBlock?,
) : FirTryExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
calleeReference.accept(visitor, data)
@@ -32,6 +32,7 @@ internal class FirVarargArgumentsExpressionImpl(
override val arguments: MutableList<FirExpression>,
override var varargElementType: FirTypeRef,
) : FirVarargArgumentsExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
arguments.forEach { it.accept(visitor, data) }
@@ -26,6 +26,7 @@ internal class FirVariableAssignmentImpl(
override var lValue: FirExpression,
override var rValue: FirExpression,
) : FirVariableAssignment() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
lValue.accept(visitor, data)
@@ -22,6 +22,7 @@ internal class FirWhenBranchImpl(
override var condition: FirExpression,
override var result: FirBlock,
) : FirWhenBranch() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
condition.accept(visitor, data)
result.accept(visitor, data)
@@ -34,6 +34,7 @@ internal class FirWhenExpressionImpl(
override var exhaustivenessStatus: ExhaustivenessStatus?,
override val usedAsExpression: Boolean,
) : FirWhenExpression() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
calleeReference.accept(visitor, data)
@@ -29,6 +29,7 @@ internal class FirWhileLoopImpl(
override var condition: FirExpression,
override var block: FirBlock,
) : FirWhileLoop() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
label?.accept(visitor, data)
@@ -32,6 +32,7 @@ internal class FirFileAnnotationsContainerImpl(
override var annotations: MutableOrEmptyList<FirAnnotation>,
override val containingFileSymbol: FirFileSymbol,
) : FirFileAnnotationsContainer() {
init {
resolveState = resolvePhase.asResolveState()
}
@@ -22,6 +22,7 @@ internal class FirFunctionTypeParameterImpl(
override val name: Name?,
override var returnTypeRef: FirTypeRef,
) : FirFunctionTypeParameter() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
returnTypeRef.accept(visitor, data)
}
@@ -19,6 +19,7 @@ internal class FirLabelImpl(
override val source: KtSourceElement?,
override val name: String,
) : FirLabel() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirLabelImpl {
@@ -20,6 +20,7 @@ internal class FirPackageDirectiveImpl(
override val source: KtSourceElement?,
override val packageFqName: FqName,
) : FirPackageDirective() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirPackageDirectiveImpl {
@@ -21,6 +21,7 @@ internal class FirExplicitSuperReference(
override val labelName: String?,
override var superTypeRef: FirTypeRef,
) : FirSuperReference() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
superTypeRef.accept(visitor, data)
}
@@ -20,6 +20,7 @@ internal class FirFromMissingDependenciesNamedReferenceImpl(
override val source: KtSourceElement?,
override val name: Name,
) : FirFromMissingDependenciesNamedReference() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirFromMissingDependenciesNamedReferenceImpl {
@@ -23,6 +23,7 @@ class FirPropertyFromParameterResolvedNamedReference @FirImplementationDetail co
override val name: Name,
override val resolvedSymbol: FirBasedSymbol<*>,
) : FirResolvedNamedReference() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirPropertyFromParameterResolvedNamedReference {
@@ -26,6 +26,7 @@ internal class FirResolvedCallableReferenceImpl(
override val inferredTypeArguments: MutableList<ConeKotlinType>,
override val mappedArguments: CallableReferenceMappedArguments,
) : FirResolvedCallableReference() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirResolvedCallableReferenceImpl {
@@ -24,6 +24,7 @@ internal class FirResolvedErrorReferenceImpl(
override val resolvedSymbol: FirBasedSymbol<*>,
override val diagnostic: ConeDiagnostic,
) : FirResolvedErrorReference() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirResolvedErrorReferenceImpl {
@@ -22,6 +22,7 @@ internal class FirResolvedNamedReferenceImpl(
override val name: Name,
override val resolvedSymbol: FirBasedSymbol<*>,
) : FirResolvedNamedReference() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirResolvedNamedReferenceImpl {
@@ -21,6 +21,7 @@ class FirSimpleNamedReference @FirImplementationDetail constructor(
override val source: KtSourceElement?,
override val name: Name,
) : FirNamedReference() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirSimpleNamedReference {
@@ -24,6 +24,7 @@ internal class FirDynamicTypeRefImpl(
override var annotations: MutableOrEmptyList<FirAnnotation>,
override val isMarkedNullable: Boolean,
) : FirDynamicTypeRef() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
}
@@ -31,6 +31,7 @@ internal class FirFunctionTypeRefImpl(
override val isSuspend: Boolean,
override val contextReceiverTypeRefs: MutableList<FirTypeRef>,
) : FirFunctionTypeRef() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
receiverTypeRef?.accept(visitor, data)
@@ -27,6 +27,7 @@ internal class FirIntersectionTypeRefImpl(
override var leftType: FirTypeRef,
override var rightType: FirTypeRef,
) : FirIntersectionTypeRef() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
leftType.accept(visitor, data)
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitor
internal class FirPlaceholderProjectionImpl(
override val source: KtSourceElement?,
) : FirPlaceholderProjection() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirPlaceholderProjectionImpl {
@@ -28,6 +28,7 @@ class FirResolvedTypeRefImpl @FirImplementationDetail constructor(
override val type: ConeKotlinType,
override var delegatedTypeRef: FirTypeRef?,
) : FirResolvedTypeRef() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
annotations.forEach { it.accept(visitor, data) }
}
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitor
internal class FirStarProjectionImpl(
override val source: KtSourceElement?,
) : FirStarProjection() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirStarProjectionImpl {
@@ -22,6 +22,7 @@ internal class FirTypeProjectionWithVarianceImpl(
override var typeRef: FirTypeRef,
override val variance: Variance,
) : FirTypeProjectionWithVariance() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
typeRef.accept(visitor, data)
}
@@ -77,7 +77,7 @@ class Element(override val name: String, override val propertyName: String, kind
get() = emptyList() // Use Implementation#transformableChildren instead
var baseTransformerType: Element? = null
val transformerType: Element get() = baseTransformerType ?: this
val transformerClass: Element get() = baseTransformerType ?: this
override val visitFunctionName: String
get() = "visit$name"
@@ -13,140 +13,81 @@ import org.jetbrains.kotlin.fir.tree.generator.util.get
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.*
import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent
import java.io.File
fun Element.generateCode(generationPath: File): GeneratedFile =
printGeneratedType(generationPath, TREE_GENERATOR_README, packageName, this.typeName) {
println()
printElement(this@generateCode)
}
private class ElementPrinter(printer: SmartPrinter) : AbstractElementPrinter<Element, Field>(printer) {
private class ElementFieldPrinter(printer: SmartPrinter) : AbstractFieldPrinter<Field>(printer)
override fun makeFieldPrinter(printer: SmartPrinter) = object : AbstractFieldPrinter<Field>(printer) {}
context(ImportCollector)
fun SmartPrinter.printElement(element: Element) {
with(element) {
val isInterface = kind == ImplementationKind.Interface || kind == ImplementationKind.SealedInterface
fun abstract() {
if (!isInterface) {
print("abstract ")
}
}
context(ImportCollector)
override fun SmartPrinter.printAdditionalMethods(element: Element) {
val kind = element.kind ?: error("Expected non-null element kind")
with(element) {
// TODO: Add a kDoc for `accept`
printAcceptMethod(element, firVisitorType, hasImplementation = true, kDoc = null)
fun override() {
if (!isRootElement) {
print("override ")
}
}
printKDoc(element.extendedKDoc())
print("${kind!!.title} $typeName")
print(params.typeParameters())
val parentRefs = element.parentRefs
if (parentRefs.isNotEmpty()) {
print(
parentRefs.sortedBy { it.typeKind }.joinToString(prefix = " : ") { parent ->
parent.render() + parent.inheritanceClauseParenthesis()
}
// TODO: Add a kDoc for `transform`
printTransformMethod(
element = element,
transformerClass = firTransformerType,
implementation = "transformer.transform${element.name}(this, data)",
returnType = TypeVariable("E", listOf(AbstractFirTreeBuilder.baseFirElement)),
kDoc = null,
)
}
print(params.multipleUpperBoundsList())
println(" {")
withIndent {
val fieldPrinter = ElementFieldPrinter(this@printElement)
allFields.forEach { field ->
if (field.isFinal && field.fromParent || field.isParameter) return@forEach
fieldPrinter.printField(field, override = field.fromParent) {
if (!field.isFinal) {
abstract()
}
}
}
if (hasAcceptMethod) {
if (allFields.isNotEmpty()) {
println()
}
override()
println("fun <R, D> accept(visitor: ${firVisitorType.render()}<R, D>, data: D): R =")
withIndent {
println("visitor.visit${element.name}(this, data)")
}
}
if (hasTransformMethod) {
println()
println("@Suppress(\"UNCHECKED_CAST\")")
override()
println(
"fun <E : ",
AbstractFirTreeBuilder.baseFirElement.render(),
", D> transform(transformer: ",
firTransformerType.render(),
"<D>, data: D): E ="
)
withIndent {
println("transformer.transform$name(this, data) as E")
}
}
fun Field.replaceDeclaration(override: Boolean, overridenType: TypeRefWithNullability? = null, forceNullable: Boolean = false) {
println()
if (name == "source") {
println("@${firImplementationDetailType.render()}")
println("@", firImplementationDetailType.render())
}
abstract()
if (override) print("override ")
println(replaceFunctionDeclaration(overridenType, forceNullable))
replaceFunctionDeclaration(this, override, kind, overridenType, forceNullable)
println()
}
allFields.filter { it.withReplace }.forEach {
val override = overridenFields[it, it] &&
!(it.name == "source" && element == FirTreeBuilder.qualifiedAccessExpression)
val override = overridenFields[it, it] && !(it.name == "source" && element == FirTreeBuilder.qualifiedAccessExpression)
it.replaceDeclaration(override, forceNullable = it.useNullableForReplace)
for (overridenType in it.overridenTypes) {
it.replaceDeclaration(true, overridenType)
for (overriddenType in it.overridenTypes) {
it.replaceDeclaration(true, overriddenType)
}
}
for (field in allFields) {
if (!field.needsSeparateTransform) continue
println()
abstract()
if (field.fromParent && field.parentHasSeparateTransform) {
print("override ")
}
println(field.transformFunctionDeclaration(element))
transformFunctionDeclaration(field, element, override = field.fromParent && field.parentHasSeparateTransform, kind)
println()
}
if (needTransformOtherChildren) {
println()
abstract()
if (element.elementParents.any { it.element.needTransformOtherChildren }) {
print("override ")
}
println(transformFunctionDeclaration("OtherChildren", element))
transformOtherChildrenFunctionDeclaration(
element,
override = element.elementParents.any { it.element.needTransformOtherChildren },
kind,
)
println()
}
if (element.isRootElement) {
require(isInterface) {
"$element must be an interface"
}
println()
println("fun accept(visitor: ${firVisitorVoidType.render()}) = accept(visitor, null)")
if (element.hasAcceptChildrenMethod) {
println()
println("fun <R, D> acceptChildren(visitor: ${firVisitorType.render()}<R, D>, data: D)")
}
println("fun accept(visitor: ", firVisitorVoidType.render(), ") = accept(visitor, null)")
// TODO: Add a kDoc for `acceptChildren`
printAcceptChildrenMethod(element, firVisitorType, visitorResultType = TypeVariable("R"), kDoc = null)
println()
println()
println("fun acceptChildren(visitor: ", firVisitorVoidType.render(), ") = acceptChildren(visitor, null)")
// TODO: Add a kDoc for `transformChildren`
printTransformChildrenMethod(element, firTransformerType, returnType = AbstractFirTreeBuilder.baseFirElement, kDoc = null)
println()
println("fun acceptChildren(visitor: ${firVisitorVoidType.render()}) = acceptChildren(visitor, null)")
if (element.hasTransformChildrenMethod) {
println()
println("fun <D> transformChildren(transformer: ${firTransformerType.render()}<D>, data: D): FirElement")
}
}
}
println("}")
}
}
fun Element.generateCode(generationPath: File): GeneratedFile =
printGeneratedType(generationPath, TREE_GENERATOR_README, packageName, typeName) {
println()
ElementPrinter(this).printElement(element)
}
@@ -9,10 +9,8 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.tree.generator.*
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.GeneratedFile
import org.jetbrains.kotlin.generators.tree.printer.*
import org.jetbrains.kotlin.generators.tree.printer.braces
import org.jetbrains.kotlin.generators.tree.printer.printGeneratedType
import org.jetbrains.kotlin.generators.tree.printer.typeParameters
import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
import org.jetbrains.kotlin.utils.withIndent
@@ -86,12 +84,6 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
val isInterface = kind == ImplementationKind.Interface || kind == ImplementationKind.SealedInterface
val isAbstract = kind == ImplementationKind.AbstractClass || kind == ImplementationKind.SealedClass
fun abstract() {
if (isAbstract) {
print("abstract ")
}
}
val fieldPrinter = ImplementationFieldPrinter(this@printImplementation)
if (!isInterface && !isAbstract && fieldsWithoutDefault.isNotEmpty()) {
@@ -128,9 +120,6 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
fieldsWithDefault.forEach {
fieldPrinter.printField(it, override = true)
}
if (fieldsWithDefault.isNotEmpty()) {
println()
}
}
@@ -146,6 +135,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
val customCalls = fieldsWithoutDefault.filter { it.customInitializationCall != null }
if (bindingCalls.isNotEmpty() || customCalls.isNotEmpty()) {
println()
println("init {")
withIndent {
for (symbolField in bindingCalls) {
@@ -158,12 +148,13 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
}
}
println("}")
println()
}
fun Field.acceptString(): String = "${name}${call()}accept(visitor, data)"
if (hasAcceptChildrenMethod) {
print("override fun <R, D> acceptChildren(visitor: ${firVisitorType.render()}<R, D>, data: D) {")
printAcceptChildrenMethod(this, firVisitorType, TypeVariable("R"), override = true, kDoc = null)
print(" {")
val walkableFields = walkableChildren
if (walkableFields.isNotEmpty()) {
@@ -223,16 +214,16 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
}
}
println("}")
println()
}
if (hasTransformChildrenMethod) {
abstract()
print(
"override fun <D> transformChildren(transformer: ",
firTransformerType.render(),
"<D>, data: D): ",
render(),
printTransformChildrenMethod(
this,
firTransformerType,
this,
modality = Modality.ABSTRACT.takeIf { isAbstract },
override = true,
kDoc = null,
)
if (!isInterface && !isAbstract) {
println(" {")
@@ -286,17 +277,15 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
}
println("return this")
}
println("}")
} else {
println()
print("}")
}
println()
}
for (field in allFields) {
if (!field.needsSeparateTransform) continue
println()
abstract()
print("override ${field.transformFunctionDeclaration(this)}")
transformFunctionDeclaration(field, this, override = true, kind!!)
if (isInterface || isAbstract) {
println()
continue
@@ -327,13 +316,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
if (element.needTransformOtherChildren) {
println()
abstract()
print(
"override fun <D> transformOtherChildren(transformer: ",
firTransformerType.render(),
"<D>, data: D): ",
render(),
)
transformOtherChildrenFunctionDeclaration(this, override = true, kind!!)
if (isInterface || isAbstract) {
println()
} else {
@@ -364,8 +347,7 @@ fun SmartPrinter.printImplementation(implementation: Implementation) {
if (field.name == "source") {
println("@${firImplementationDetailType.render()}")
}
abstract()
print("override ${field.replaceFunctionDeclaration(overridenType, forceNullable)}")
replaceFunctionDeclaration(field, override = true, kind!!, overridenType, forceNullable)
if (isInterface || isAbstract) {
println()
return
@@ -37,7 +37,7 @@ private class TransformerPrinter(
override val visitorDataType: TypeRef
get() = dataTypeVariable
override fun visitMethodReturnType(element: Element) = element.transformerType
override fun visitMethodReturnType(element: Element) = element.transformerClass
override val allowTypeParametersInVisitorMethods: Boolean
get() = true
@@ -5,30 +5,77 @@
package org.jetbrains.kotlin.fir.tree.generator.printer
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.tree.generator.firTransformerType
import org.jetbrains.kotlin.fir.tree.generator.model.*
import org.jetbrains.kotlin.generators.tree.*
import org.jetbrains.kotlin.generators.tree.printer.FunctionParameter
import org.jetbrains.kotlin.generators.tree.printer.printFunctionDeclaration
import org.jetbrains.kotlin.utils.SmartPrinter
context(ImportCollector)
fun Field.transformFunctionDeclaration(returnType: TypeRef): String {
return transformFunctionDeclaration(name.replaceFirstChar(Char::uppercaseChar), returnType)
fun SmartPrinter.transformFunctionDeclaration(
field: Field,
returnType: TypeRef,
override: Boolean,
implementationKind: ImplementationKind,
) {
transformFunctionDeclaration(field.name.replaceFirstChar(Char::uppercaseChar), returnType, override, implementationKind)
}
context(ImportCollector)
fun transformFunctionDeclaration(transformName: String, returnType: TypeRef): String {
return "fun <D> transform$transformName(transformer: ${firTransformerType.render()}<D>, data: D): " +
returnType.render()
fun SmartPrinter.transformOtherChildrenFunctionDeclaration(
element: TypeRef,
override: Boolean,
implementationKind: ImplementationKind,
) {
transformFunctionDeclaration("OtherChildren", element, override, implementationKind)
}
context(ImportCollector)
fun Field.replaceFunctionDeclaration(
overridenType: TypeRefWithNullability? = null,
private fun SmartPrinter.transformFunctionDeclaration(
transformName: String,
returnType: TypeRef,
override: Boolean,
implementationKind: ImplementationKind,
) {
val dataTP = TypeVariable("D")
printFunctionDeclaration(
name = "transform$transformName",
parameters = listOf(
FunctionParameter("transformer", firTransformerType.withArgs(dataTP)),
FunctionParameter("data", dataTP),
),
returnType = returnType,
typeParameters = listOf(dataTP),
modality = Modality.ABSTRACT.takeIf {
implementationKind == ImplementationKind.AbstractClass || implementationKind == ImplementationKind.SealedClass
},
override = override,
)
}
context(ImportCollector)
fun SmartPrinter.replaceFunctionDeclaration(
field: Field,
override: Boolean,
implementationKind: ImplementationKind,
overriddenType: TypeRefWithNullability? = null,
forceNullable: Boolean = false,
): String {
val capName = name.replaceFirstChar(Char::uppercaseChar)
val type = overridenType ?: typeRef
) {
val capName = field.name.replaceFirstChar(Char::uppercaseChar)
val type = overriddenType ?: field.typeRef
val typeWithNullable = if (forceNullable) type.copy(nullable = true) else type
return "fun replace$capName(new$capName: ${typeWithNullable.render()})"
printFunctionDeclaration(
name = "replace$capName",
parameters = listOf(FunctionParameter("new$capName", typeWithNullable)),
returnType = StandardTypes.unit,
modality = Modality.ABSTRACT.takeIf {
implementationKind == ImplementationKind.AbstractClass || implementationKind == ImplementationKind.SealedClass
},
override = override,
)
}
fun Field.getMutableType(forBuilder: Boolean = false): TypeRefWithNullability = when (this) {
@@ -0,0 +1,78 @@
/*
* Copyright 2010-2023 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.generators.tree
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.generators.tree.printer.*
import org.jetbrains.kotlin.utils.SmartPrinter
import org.jetbrains.kotlin.utils.withIndent
/**
* A common class for printing FIR or IR tree elements.
*/
abstract class AbstractElementPrinter<Element : AbstractElement<Element, Field>, Field : AbstractField>(
private val printer: SmartPrinter,
) {
protected abstract fun makeFieldPrinter(printer: SmartPrinter): AbstractFieldPrinter<Field>
context(ImportCollector)
protected abstract fun SmartPrinter.printAdditionalMethods(element: Element)
protected open fun defaultElementKDoc(element: Element): String? = null
protected open val separateFieldsWithBlankLine: Boolean
get() = false
context(ImportCollector)
fun printElement(element: Element) {
printer.run {
val kind = element.kind ?: error("Expected non-null element kind")
printKDoc(element.extendedKDoc(defaultElementKDoc(element)))
print(kind.title, " ", element.typeName)
print(element.params.typeParameters())
val parentRefs = element.parentRefs
if (parentRefs.isNotEmpty()) {
print(
parentRefs.sortedBy { it.typeKind }.joinToString(prefix = " : ") { parent ->
parent.render() + parent.inheritanceClauseParenthesis()
}
)
}
print(element.params.multipleUpperBoundsList())
val body = SmartPrinter(StringBuilder()).apply {
val fieldPrinter = makeFieldPrinter(this)
withIndent {
for (field in element.allFields) {
if (
!field.withGetter && field.defaultValueInImplementation == null && field.isFinal && field.fromParent ||
field.isParameter
) {
continue
}
if (separateFieldsWithBlankLine) println()
fieldPrinter.printField(
field,
override = field.fromParent,
modality = Modality.ABSTRACT.takeIf { !field.isFinal && !kind.isInterface },
)
}
printAdditionalMethods(element)
}
}.toString()
if (body.isNotEmpty()) {
println(" {")
print(body)
print("}")
}
println()
}
}
}
@@ -146,4 +146,120 @@ fun SmartPrinter.printFunctionDeclaration(
print(": ", returnType.render())
}
print(typeParameters.multipleUpperBoundsList())
}
}
private val dataTP = TypeVariable("D")
private val dataParameter = FunctionParameter("data", dataTP)
context(ImportCollector)
fun SmartPrinter.printAcceptMethod(
element: AbstractElement<*, *>,
visitorClass: ClassRef<PositionTypeParameterRef>,
hasImplementation: Boolean,
kDoc: String?,
) {
if (!element.hasAcceptMethod) return
println()
printKDoc(kDoc)
val resultTP = TypeVariable("R")
printFunctionDeclaration(
name = "accept",
parameters = listOf(
FunctionParameter("visitor", visitorClass.withArgs(resultTP, dataTP)),
dataParameter,
),
returnType = resultTP,
typeParameters = listOf(resultTP, dataTP),
override = !element.isRootElement,
)
if (hasImplementation) {
println(" =")
withIndent {
print("visitor.", element.visitFunctionName, "(this, ", dataParameter.name, ")")
}
}
println()
}
context(ImportCollector)
fun SmartPrinter.printTransformMethod(
element: AbstractElement<*, *>,
transformerClass: ClassRef<PositionTypeParameterRef>,
implementation: String?,
returnType: TypeRefWithNullability,
kDoc: String?,
) {
if (!element.hasTransformMethod) return
println()
printKDoc(kDoc)
if (returnType is TypeParameterRef && implementation != null) {
println("@Suppress(\"UNCHECKED_CAST\")")
}
printFunctionDeclaration(
name = "transform",
parameters = listOf(
FunctionParameter("transformer", transformerClass.withArgs(dataTP)),
dataParameter,
),
returnType = returnType,
typeParameters = listOfNotNull(returnType as? TypeVariable, dataTP),
override = !element.isRootElement,
)
if (implementation != null) {
println(" =")
withIndent {
print(implementation, " as ", returnType.render())
}
}
println()
}
context(ImportCollector)
fun SmartPrinter.printAcceptChildrenMethod(
element: FieldContainer,
visitorClass: ClassRef<PositionTypeParameterRef>,
visitorResultType: TypeRef,
modality: Modality? = null,
override: Boolean = false,
kDoc: String?,
) {
if (!element.hasAcceptChildrenMethod) return
println()
printKDoc(kDoc)
printFunctionDeclaration(
name = "acceptChildren",
parameters = listOf(
FunctionParameter("visitor", visitorClass.withArgs(visitorResultType, dataTP)),
dataParameter,
),
returnType = StandardTypes.unit,
typeParameters = listOfNotNull(visitorResultType as? TypeVariable, dataTP),
modality = modality,
override = override,
)
}
context(ImportCollector)
fun SmartPrinter.printTransformChildrenMethod(
element: FieldContainer,
transformerClass: ClassRef<PositionTypeParameterRef>,
returnType: TypeRef,
modality: Modality? = null,
override: Boolean = false,
kDoc: String?,
) {
if (!element.hasTransformChildrenMethod) return
println()
printKDoc(kDoc)
printFunctionDeclaration(
name = "transformChildren",
parameters = listOf(
FunctionParameter("transformer", transformerClass.withArgs(dataTP)),
dataParameter,
),
returnType = returnType,
typeParameters = listOf(dataTP),
modality = modality,
override = override,
)
}