[FIR] Make FirDeclaration an abstract class
This commit is contained in:
+14
-14
@@ -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)
|
||||
|
||||
+24
@@ -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() {
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+5
-17
@@ -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")
|
||||
|
||||
+4
@@ -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) {
|
||||
|
||||
+8
-8
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
+39
-7
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user