[FIR] Create CFG for files to track top-level property initialization
In order to properly analyze top-level property initialization, a control-flow graph must be created for FirFiles. This change adds the foundation for the file CFG and updates body resolve to create the CFG. Checking the CFG for proper initialization is separated into a following change to ease code review. KT-56683
This commit is contained in:
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.FirPackageDirective
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFileSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.fir.declarations.ResolveStateAccess
|
||||
@@ -22,12 +23,13 @@ import org.jetbrains.kotlin.fir.declarations.ResolveStateAccess
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
abstract class FirFile : FirDeclaration() {
|
||||
abstract class FirFile : FirDeclaration(), FirControlFlowGraphOwner {
|
||||
abstract override val source: KtSourceElement?
|
||||
abstract override val annotations: List<FirAnnotation>
|
||||
abstract override val moduleData: FirModuleData
|
||||
abstract override val origin: FirDeclarationOrigin
|
||||
abstract override val attributes: FirDeclarationAttributes
|
||||
abstract override val controlFlowGraphReference: FirControlFlowGraphReference?
|
||||
abstract val annotationsContainer: FirFileAnnotationsContainer?
|
||||
abstract val packageDirective: FirPackageDirective
|
||||
abstract val imports: List<FirImport>
|
||||
@@ -45,6 +47,8 @@ abstract class FirFile : FirDeclaration() {
|
||||
|
||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||
|
||||
abstract override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?)
|
||||
|
||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirFile
|
||||
|
||||
abstract fun <D> transformAnnotationsContainer(transformer: FirTransformer<D>, data: D): FirFile
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.fir.declarations.ResolveStateAccess
|
||||
import org.jetbrains.kotlin.fir.declarations.asResolveState
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirFileImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFileSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolveState
|
||||
import org.jetbrains.kotlin.fir.declarations.asResolveState
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFileSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.fir.MutableOrEmptyList
|
||||
@@ -49,6 +50,7 @@ internal class FirFileImpl(
|
||||
override val symbol: FirFileSymbol,
|
||||
) : FirFile() {
|
||||
override val annotations: List<FirAnnotation> get() = annotationsContainer?.annotations ?: emptyList()
|
||||
override var controlFlowGraphReference: FirControlFlowGraphReference? = null
|
||||
|
||||
init {
|
||||
symbol.bind(this)
|
||||
@@ -57,6 +59,7 @@ internal class FirFileImpl(
|
||||
}
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
controlFlowGraphReference?.accept(visitor, data)
|
||||
annotationsContainer?.accept(visitor, data)
|
||||
packageDirective.accept(visitor, data)
|
||||
imports.forEach { it.accept(visitor, data) }
|
||||
@@ -64,6 +67,7 @@ internal class FirFileImpl(
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirFileImpl {
|
||||
controlFlowGraphReference = controlFlowGraphReference?.transform(transformer, data)
|
||||
transformAnnotationsContainer(transformer, data)
|
||||
packageDirective = packageDirective.transform(transformer, data)
|
||||
transformImports(transformer, data)
|
||||
@@ -91,4 +95,8 @@ internal class FirFileImpl(
|
||||
}
|
||||
|
||||
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {}
|
||||
|
||||
override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) {
|
||||
controlFlowGraphReference = newControlFlowGraphReference
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,8 +192,6 @@ abstract class FirDefaultVisitor<out R, in D> : FirVisitor<R, D>() {
|
||||
|
||||
override fun visitRegularClass(regularClass: FirRegularClass, data: D): R = visitClass(regularClass, data)
|
||||
|
||||
override fun visitFile(file: FirFile, data: D): R = visitDeclaration(file, data)
|
||||
|
||||
override fun visitScript(script: FirScript, data: D): R = visitDeclaration(script, data)
|
||||
|
||||
override fun visitCodeFragment(codeFragment: FirCodeFragment, data: D): R = visitDeclaration(codeFragment, data)
|
||||
|
||||
@@ -192,8 +192,6 @@ abstract class FirDefaultVisitorVoid : FirVisitorVoid() {
|
||||
|
||||
override fun visitRegularClass(regularClass: FirRegularClass) = visitClass(regularClass)
|
||||
|
||||
override fun visitFile(file: FirFile) = visitDeclaration(file)
|
||||
|
||||
override fun visitScript(script: FirScript) = visitDeclaration(script)
|
||||
|
||||
override fun visitCodeFragment(codeFragment: FirCodeFragment) = visitDeclaration(codeFragment)
|
||||
|
||||
Reference in New Issue
Block a user