[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:
Brian Norman
2023-07-25 10:23:22 -05:00
committed by Space Team
parent 0b7eb32064
commit b55fda0c55
127 changed files with 19565 additions and 18746 deletions
@@ -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)