[FIR] Make FirDeclaration an abstract class

This commit is contained in:
Dmitriy Novozhilov
2021-06-20 15:23:25 +03:00
parent b3e5c6e079
commit 1324e9223f
142 changed files with 997 additions and 758 deletions
@@ -35,26 +35,26 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val typeParameter = element("TypeParameter", Declaration, typeParameterRef, annotatedDeclaration)
val typeParameterRefsOwner = sealedElement("TypeParameterRefsOwner", Declaration)
val typeParametersOwner = sealedElement("TypeParametersOwner", Declaration, typeParameterRefsOwner)
val memberDeclaration = sealedElement("MemberDeclaration", Declaration, annotatedDeclaration, typeParameterRefsOwner)
val callableMemberDeclaration = sealedElement("CallableMemberDeclaration", Declaration, callableDeclaration, memberDeclaration)
val statusOwner = sealedElement("StatusOwner", Declaration, typeParameterRefsOwner)
val callableMemberDeclaration = sealedElement("CallableMemberDeclaration", Declaration, callableDeclaration, statusOwner)
val variable = sealedElement("Variable", Declaration, callableDeclaration, annotatedDeclaration, statement)
val variable = sealedElement("Variable", Declaration, callableMemberDeclaration, statement)
val valueParameter = element("ValueParameter", Declaration, variable, controlFlowGraphOwner)
val property = element("Property", Declaration, variable, typeParametersOwner, controlFlowGraphOwner, callableMemberDeclaration)
val field = element("Field", Declaration, variable, typeParametersOwner, callableMemberDeclaration)
val enumEntry = element("EnumEntry", Declaration, variable, callableMemberDeclaration)
val property = element("Property", Declaration, variable, typeParametersOwner, controlFlowGraphOwner)
val field = element("Field", Declaration, variable)
val enumEntry = element("EnumEntry", Declaration, variable)
val classLikeDeclaration = sealedElement("ClassLikeDeclaration", Declaration, annotatedDeclaration, statement)
val klass = sealedElement("Class", Declaration, classLikeDeclaration, statement, typeParameterRefsOwner)
val regularClass = element("RegularClass", Declaration, memberDeclaration, typeParameterRefsOwner, controlFlowGraphOwner, klass)
val typeAlias = element("TypeAlias", Declaration, classLikeDeclaration, memberDeclaration, typeParametersOwner)
val regularClass = element("RegularClass", Declaration, klass, statusOwner, controlFlowGraphOwner)
val typeAlias = element("TypeAlias", Declaration, classLikeDeclaration, statusOwner, typeParametersOwner)
val function = sealedElement("Function", Declaration, callableDeclaration, targetElement, typeParameterRefsOwner, controlFlowGraphOwner, statement)
val function = sealedElement("Function", Declaration, callableMemberDeclaration, targetElement, controlFlowGraphOwner, statement)
val contractDescriptionOwner = sealedElement("ContractDescriptionOwner", Declaration)
val simpleFunction = element("SimpleFunction", Declaration, function, callableMemberDeclaration, contractDescriptionOwner, typeParametersOwner)
val propertyAccessor = element("PropertyAccessor", Declaration, function, callableMemberDeclaration, contractDescriptionOwner, typeParametersOwner)
val constructor = element("Constructor", Declaration, function, callableMemberDeclaration, typeParameterRefsOwner)
val simpleFunction = element("SimpleFunction", Declaration, function, contractDescriptionOwner, typeParametersOwner)
val propertyAccessor = element("PropertyAccessor", Declaration, function, contractDescriptionOwner, typeParametersOwner)
val constructor = element("Constructor", Declaration, function, typeParameterRefsOwner)
val file = element("File", Declaration, annotatedDeclaration)
val anonymousFunction = element("AnonymousFunction", Declaration, function, typeParametersOwner)
@@ -103,8 +103,8 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val arraySetCall = element("AugmentedArraySetCall", Expression, statement)
val classReferenceExpression = element("ClassReferenceExpression", Expression, expression)
val errorExpression = element("ErrorExpression", Expression, expression, diagnosticHolder)
val errorFunction = element("ErrorFunction", Declaration, function, diagnosticHolder, typeParametersOwner)
val errorProperty = element("ErrorProperty", Declaration, variable, diagnosticHolder, typeParametersOwner)
val errorFunction = element("ErrorFunction", Declaration, function, diagnosticHolder)
val errorProperty = element("ErrorProperty", Declaration, variable, diagnosticHolder)
val qualifiedAccessExpression = element("QualifiedAccessExpression", Expression, expression, qualifiedAccess)
val functionCall = element("FunctionCall", Expression, qualifiedAccessExpression, call)
val implicitInvokeCall = element("ImplicitInvokeCall", Expression, functionCall)
@@ -500,6 +500,30 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
}
noImpl(argumentList)
val implementationsWithoutStatusAndTypeParameters = listOf(
"FirAnonymousFunctionImpl",
"FirValueParameterImpl",
"FirDefaultSetterValueParameter",
"FirErrorPropertyImpl",
"FirErrorFunctionImpl"
)
configureFieldInAllImplementations(
"status",
implementationPredicate = { it.type in implementationsWithoutStatusAndTypeParameters }
) {
default(it, "FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS")
useTypes(resolvedDeclarationStatusImplType)
}
configureFieldInAllImplementations(
"typeParameters",
implementationPredicate = { it.type != "FirAnonymousFunctionImpl" && it.type in implementationsWithoutStatusAndTypeParameters }
) {
defaultEmptyList(it)
useTypes(resolvedDeclarationStatusImplType)
}
}
private fun configureAllImplementations() {
@@ -13,7 +13,7 @@ import java.io.File
fun main(args: Array<String>) {
val generationPath = args.firstOrNull()?.let { File(it) }
?: File("compiler/fir/tree/gen").absoluteFile
?: File("../../tree/gen").canonicalFile
NodeConfigurator.configureFields()
detectBaseTransformerTypes(FirTreeBuilder)
@@ -82,6 +82,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
+field("resolvePhase", resolvePhaseType, withReplace = true).apply { isMutable = true }
+field("origin", declarationOriginType)
+field("attributes", declarationAttributesType)
shouldBeAbstractClass()
}
annotatedDeclaration.configure {
@@ -105,14 +106,13 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
callableMemberDeclaration.configure {
withArg("E", "FirCallableMemberDeclaration<E>")
parentArg(callableDeclaration, "E", "E")
parentArg(memberDeclaration, "E", "E")
+field("containerSource", type(DeserializedContainerSource::class), nullable = true)
+field("dispatchReceiverType", coneKotlinTypeType, nullable = true)
}
function.configure {
withArg("E", "FirFunction<E>")
parentArg(callableDeclaration, "E", "E")
parentArg(callableMemberDeclaration, "E", "E")
+symbol("FirFunctionSymbol", "E")
+fieldList(valueParameter, withReplace = true).withTransform()
+body(nullable = true, withReplace = true).withTransform()
@@ -124,10 +124,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
+typeParameters
}
memberDeclaration.configure {
withArg("E", "FirMemberDeclaration<E>")
parentArg(annotatedDeclaration, "E", "E")
+typeParameterRefs
statusOwner.configure {
+status.withTransform()
}
@@ -269,7 +266,6 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
regularClass.configure {
parentArg(klass, "E", regularClass)
parentArg(memberDeclaration, "E", regularClass)
+name
+symbol("FirRegularClassSymbol")
+field("companionObject", regularClass, nullable = true).withTransform()
@@ -289,7 +285,6 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
typeAlias.configure {
+typeParameters
parentArg(classLikeDeclaration, "E", typeAlias)
parentArg(memberDeclaration, "E", typeAlias)
+name
+symbol("FirTypeAliasSymbol")
+field("expandedTypeRef", typeRef, withReplace = true).withTransform()
@@ -327,7 +322,6 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
simpleFunction.configure {
parentArg(function, "E", simpleFunction)
parentArg(callableMemberDeclaration, "E", simpleFunction)
+name
+symbol("FirNamedFunctionSymbol")
+annotations
@@ -340,16 +334,14 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
property.configure {
parentArg(variable, "E", property)
parentArg(callableMemberDeclaration, "E", property)
+symbol("FirPropertySymbol")
+field("backingFieldSymbol", backingFieldSymbolType)
+booleanField("isLocal")
+status
+typeParameters
}
propertyAccessor.configure {
parentArg(function, "E", propertyAccessor)
parentArg(callableMemberDeclaration, "E", propertyAccessor)
+symbol("FirPropertyAccessorSymbol")
+booleanField("isGetter")
+booleanField("isSetter")
@@ -374,7 +366,6 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
constructor.configure {
parentArg(function, "E", constructor)
parentArg(callableMemberDeclaration, "E", constructor)
+annotations
+symbol("FirConstructorSymbol")
+field("delegatedConstructor", delegatedConstructorCall, nullable = true).withTransform()
@@ -397,8 +388,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
variable.configure {
withArg("E", variable)
parentArg(callableDeclaration, "E", "E")
parentArg(annotatedDeclaration, "E", "E")
parentArg(callableMemberDeclaration, "E", "E")
+name
+symbol("FirVariableSymbol", "E")
+initializer.withTransform().withReplace()
@@ -418,12 +408,10 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
enumEntry.configure {
parentArg(variable, "E", enumEntry)
parentArg(callableMemberDeclaration, "E", enumEntry)
}
field.configure {
parentArg(variable, "E", field)
parentArg(callableMemberDeclaration, "E", field)
}
anonymousInitializer.configure {
@@ -91,3 +91,5 @@ val exhaustivenessStatusType = generatedType("expressions", "ExhaustivenessStatu
val callableReferenceMappedArgumentsType = type("fir.resolve.calls", "CallableReferenceMappedArguments")
val functionCallOrigin = type("fir.expressions", "FirFunctionCallOrigin")
val resolvedDeclarationStatusImplType = type("fir.declarations.impl", "FirResolvedDeclarationStatusImpl")
@@ -76,6 +76,10 @@ abstract class AbstractFieldConfigurator<T : AbstractFirTreeBuilder>(private val
fun shouldBeAnInterface() {
element.kind = Implementation.Kind.Interface
}
fun shouldBeAbstractClass() {
element.kind = Implementation.Kind.AbstractClass
}
}
fun Element.configure(block: ConfigureContext.() -> Unit) {
@@ -74,13 +74,13 @@ class Implementation(val element: Element, val name: String?) : FieldContainer,
val fieldsWithoutDefault by lazy { allFields.filter { it.defaultValueInImplementation == null } }
val fieldsWithDefault by lazy { allFields.filter { it.defaultValueInImplementation != null } }
enum class Kind(val title: String, val hasLeafBuilder: Boolean) {
Interface("interface", false),
FinalClass("class", true),
OpenClass("open class", true),
AbstractClass("abstract class", false),
SealedClass("sealed class", false),
SealedInterface("sealed interface", false),
Object("object", false)
enum class Kind(val title: String, val hasLeafBuilder: Boolean, val isInterface: Boolean) {
Interface("interface", hasLeafBuilder = false, isInterface = true),
FinalClass("class", hasLeafBuilder = true, isInterface = false),
OpenClass("open class", hasLeafBuilder = true, isInterface = false),
AbstractClass("abstract class", hasLeafBuilder = false, isInterface = false),
SealedClass("sealed class", hasLeafBuilder = false, isInterface = false),
SealedInterface("sealed interface", hasLeafBuilder = false, isInterface = true),
Object("object", hasLeafBuilder = false, isInterface = false),
}
}
@@ -11,6 +11,17 @@ import org.jetbrains.kotlin.fir.tree.generator.model.Implementation
import org.jetbrains.kotlin.fir.tree.generator.model.ImplementationWithArg
import org.jetbrains.kotlin.fir.tree.generator.model.KindOwner
/*
* Assume that we have element `E` with parents `P1, P2`
*
* Introduce variables E, P1, P2. If variable `X` is true then `X` is class, otherwise it is interface
*
* Build 2SAT function for it: (E || !P1) && (E || !P2) && (!P1 || !P2)
* Simple explanation:
* if `P1` is a class then `E` also should be a class
* if `P1` is a class then `P2` can not be a class (because both of them a parents of E`
*/
fun configureInterfacesAndAbstractClasses(builder: AbstractFirTreeBuilder) {
val elements = collectElements(builder)
val elementMapping = ElementMapping(elements)
@@ -21,7 +32,7 @@ fun configureInterfacesAndAbstractClasses(builder: AbstractFirTreeBuilder) {
updateSealedKinds(elements)
}
private class ElementMapping(elements: Collection<KindOwner>) {
private class ElementMapping(val elements: Collection<KindOwner>) {
private val varToElements: Map<Int, KindOwner> = elements.mapIndexed { index, element -> 2 * index to element.origin }.toMap() +
elements.mapIndexed { index, element -> 2 * index + 1 to element }.toMap()
private val elementsToVar: Map<KindOwner, Int> = elements.mapIndexed { index, element -> element.origin to index }.toMap()
@@ -89,17 +100,38 @@ private fun updateSealedKinds(elements: Collection<KindOwner>) {
}
private fun processRequirementsFromConfig(solution: MutableList<Boolean>, elementMapping: ElementMapping) {
fun processParents(element: KindOwner) {
fun forceParentsToBeInterfaces(element: KindOwner) {
val origin = element.origin
solution[elementMapping[origin]] = false
origin.allParents.forEach { processParents(it) }
val index = elementMapping[origin]
if (!solution[index]) return
solution[index] = false
origin.allParents.forEach { forceParentsToBeInterfaces(it) }
}
fun forceInheritorsToBeClasses(element: KindOwner) {
val queue = ArrayDeque<KindOwner>()
queue.add(element)
while (queue.isNotEmpty()) {
val e = queue.removeFirst().origin
val index = elementMapping[e]
if (solution[index]) continue
solution[index] = true
for (inheritor in elementMapping.elements) {
if (e in inheritor.allParents.map { it.origin }) {
queue.add(inheritor)
}
}
}
}
for (index in solution.indices) {
val element = elementMapping[index * 2]
if (element.kind != Implementation.Kind.Interface) continue
if (!solution[index]) continue
processParents(element)
val kind = element.kind ?: continue
if (kind.isInterface) {
forceParentsToBeInterfaces(element)
} else {
forceInheritorsToBeClasses(element)
}
}
}