[FIR] CFG: drop redundant edges

Edges from class to its functions and nested classes are redundant
and lead to extra resolution work in lazy resolve mode

^KT-59600 Fixed
This commit is contained in:
Dmitrii Gridin
2023-06-23 18:05:09 +02:00
committed by Space Team
parent df28bd1d79
commit 09ca335b7e
53 changed files with 931 additions and 763 deletions
@@ -63,6 +63,10 @@ internal object FileElementFactory {
val classMembersToResolve = buildList {
for (member in firClass.declarations) {
when {
member is FirSimpleFunction && member.source?.kind == KtFakeSourceElementKind.DataClassGeneratedMembers -> {
add(member)
}
member is FirPrimaryConstructor && member.source?.kind == KtFakeSourceElementKind.ImplicitConstructor -> {
add(member)
}
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataCo
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.FirContractsDslNames
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isUsedInControlFlowGraphBuilderForClass
internal object LLFirBodyLazyResolver : LLFirLazyResolver(FirResolvePhase.BODY_RESOLVE) {
override fun resolve(
@@ -136,10 +137,7 @@ private class LLFirBodyTargetResolver(
transformer.firTowerDataContextCollector?.addDeclarationContext(target, transformer.context.towerDataContext)
for (member in target.declarations) {
if (member is FirCallableDeclaration || member is FirAnonymousInitializer) {
// TODO: Ideally, only properties and init blocks should be resolved here.
// However, dues to changes in the compiler resolution, we temporarily have to resolve all callable members.
// Such additional work might affect incremental analysis performance.
if (member is FirControlFlowGraphOwner && member.isUsedInControlFlowGraphBuilderForClass) {
member.lazyResolveToPhase(resolverPhase.previous)
performResolve(member)
}
@@ -13,12 +13,10 @@ FILE: [ResolvedTo(IMPORTS)] secondaryConstructor.kt
super<R|kotlin/Any|>()
}
public final [ResolvedTo(BODY_RESOLVE)] val value: R|kotlin/String|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=JsQualifier] get(): R|kotlin/String|
public final [ResolvedTo(STATUS)] val value: R|kotlin/String|
public [ResolvedTo(STATUS)] [ContainingClassKey=JsQualifier] get(): R|kotlin/String|
public final [ResolvedTo(BODY_RESOLVE)] fun <no name provided>(): R|kotlin/Unit| {
<Unresolved name: get>#
}
public final [ResolvedTo(STATUS)] fun <no name provided>(): R|kotlin/Unit| { LAZY_BLOCK }
<DANGLING MODIFIER: Top level declaration expected>
}
}
@@ -8,7 +8,7 @@ public final [ResolvedTo(BODY_RESOLVE)] class X : R|kotlin/Any| {
super<R|kotlin/Any|>()
}
public final [ResolvedTo(BODY_RESOLVE)] fun y(): R|kotlin/String|
public final [ResolvedTo(STATUS)] fun y(): R|kotlin/String|
}
@@ -25,8 +25,8 @@ FILE: [ResolvedTo(IMPORTS)] nestedClass.kt
super<R|kotlin/Any|>()
}
public final [ResolvedTo(BODY_RESOLVE)] fun y(): R|kotlin/String|
public final [ResolvedTo(STATUS)] fun y(): R|kotlin/String|
}
}
}
@@ -8,7 +8,7 @@ public final [ResolvedTo(BODY_RESOLVE)] class X : R|kotlin/Any| {
super<R|kotlin/Any|>()
}
public final [ResolvedTo(BODY_RESOLVE)] fun y(): R|kotlin/String|
public final [ResolvedTo(STATUS)] fun y(): R|kotlin/String|
}
@@ -20,6 +20,6 @@ FILE: [ResolvedTo(IMPORTS)] topLevelClass.kt
super<R|kotlin/Any|>()
}
public final [ResolvedTo(BODY_RESOLVE)] fun y(): R|kotlin/String|
public final [ResolvedTo(STATUS)] fun y(): R|kotlin/String|
}
}
@@ -294,8 +294,7 @@ FILE: [ResolvedTo(IMPORTS)] actual.kt
super<R|kotlin/Any|>()
}
public final [ResolvedTo(BODY_RESOLVE)] fun memberFun(): R|kotlin/Unit| {
}
public final [ResolvedTo(STATUS)] fun memberFun(): R|kotlin/Unit| { LAZY_BLOCK }
public final [ResolvedTo(BODY_RESOLVE)] val a: R|kotlin/Int| = Int(1)
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Actual] get(): R|kotlin/Int|
@@ -384,8 +384,7 @@ FILE: [ResolvedTo(IMPORTS)] hierarchyWithOverride.kt
super<R|kotlin/Any|>()
}
public open override [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Unit| {
}
public open override [ResolvedTo(STATUS)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
}
@@ -906,8 +906,7 @@ FILE: [ResolvedTo(IMPORTS)] hierarchyWithOverrideAndNestedClass2.kt
super<R|kotlin/Any|>()
}
public open override [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Unit| {
}
public open override [ResolvedTo(STATUS)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
}
@@ -897,8 +897,7 @@ FILE: [ResolvedTo(IMPORTS)] hierarchyWithOverrideAndNestedClass3.kt
super<R|kotlin/Any|>()
}
public final [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Unit| {
}
public final [ResolvedTo(STATUS)] fun foo(): R|kotlin/Unit| { LAZY_BLOCK }
}
@@ -915,8 +915,7 @@ FILE: [ResolvedTo(IMPORTS)] hierarchyWithOverrideAndNestedClass4.kt
super<R|OuterClass.NestedClass|>()
}
public open override [ResolvedTo(BODY_RESOLVE)] fun bar([ResolvedTo(BODY_RESOLVE)] s: R|kotlin/String|): R|kotlin/Unit| {
}
public open override [ResolvedTo(STATUS)] fun bar([ResolvedTo(STATUS)] s: R|kotlin/String|): R|kotlin/Unit| { LAZY_BLOCK }
}
@@ -310,8 +310,8 @@ FILE: [ResolvedTo(IMPORTS)] nestedClassWithPropertiesOverrides.kt
super<R|kotlin/Any|>()
}
public open override [ResolvedTo(BODY_RESOLVE)] val originalExpressions: R|A|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=ResolveMe] get(): R|A|
public open override [ResolvedTo(STATUS)] val originalExpressions: R|A|
public [ResolvedTo(STATUS)] [ContainingClassKey=ResolveMe] get(): R|A|
}
@@ -194,7 +194,7 @@ BODY_RESOLVE:
FILE: [ResolvedTo(IMPORTS)] simpleLoopInOverride.kt
[ResolvedTo(BODY_RESOLVE)] annotations container
public abstract [ResolvedTo(BODY_RESOLVE)] interface Foo1 : <ERROR TYPE REF: Loop in supertype: /Foo1 -> /Foo2> {
public abstract override [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Unit|
public abstract override [ResolvedTo(STATUS)] fun foo(): R|kotlin/Unit|
}
public? final? [ResolvedTo(SUPER_TYPES)] interface Foo2 : <ERROR TYPE REF: Loop in supertype: /Foo2 -> /Foo3> {
@@ -194,7 +194,7 @@ BODY_RESOLVE:
FILE: [ResolvedTo(IMPORTS)] simpleLoopInOverride2.kt
[ResolvedTo(BODY_RESOLVE)] annotations container
public abstract [ResolvedTo(BODY_RESOLVE)] interface Foo1 : <ERROR TYPE REF: Loop in supertype: /Foo1 -> /Foo2> {
public abstract [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Unit|
public abstract [ResolvedTo(STATUS)] fun foo(): R|kotlin/Unit|
}
public? final? [ResolvedTo(SUPER_TYPES)] interface Foo2 : <ERROR TYPE REF: Loop in supertype: /Foo2 -> /Foo3> {
@@ -762,8 +762,7 @@ FILE: [ResolvedTo(IMPORTS)] nestedCompilerRequiredAnnotations.kt
@R|kotlin/Deprecated|[Types](message = String(constructorProperty)) public final [ResolvedTo(BODY_RESOLVE)] [IsFromPrimaryConstructor=true] val a: R|kotlin/Int| = R|<local>/a|
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=FirstClass] get(): R|kotlin/Int|
@R|kotlin/Deprecated|[Types](message = String(memberFunction)) @R|Anno|[Types](s = String(memberFunction)) public final [ResolvedTo(BODY_RESOLVE)] fun memberFunction(): R|kotlin/Unit| {
}
@R|kotlin/Deprecated|[Types](String(memberFunction)) @R|Anno|[Types](LAZY_EXPRESSION) public final [ResolvedTo(STATUS)] fun memberFunction(): R|kotlin/Unit| { LAZY_BLOCK }
@R|kotlin/Deprecated|[Types](message = String(memberProperty)) @R|Anno|[Types](s = String(memberProperty)) public final [ResolvedTo(BODY_RESOLVE)] val memberProperty: R|kotlin/Int| = Int(32)
public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=FirstClass] get(): R|kotlin/Int|
@@ -150,8 +150,7 @@ FILE: [ResolvedTo(IMPORTS)] typeParameterOfClass.kt
super<R|kotlin/Any|>()
}
public final [ResolvedTo(BODY_RESOLVE)] fun foo([ResolvedTo(BODY_RESOLVE)] t: R|Type|): R|kotlin/Unit| {
}
public final [ResolvedTo(STATUS)] fun foo([ResolvedTo(STATUS)] t: R|Type|): R|kotlin/Unit| { LAZY_BLOCK }
}
@@ -1391,6 +1391,12 @@ public class DiagnosticCompilerTestFirTestdataTestGenerated extends AbstractDiag
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/loops.kt");
}
@Test
@TestMetadata("nestedClass.kt")
public void testNestedClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/nestedClass.kt");
}
@Test
@TestMetadata("postponedLambdaInConstructor.kt")
public void testPostponedLambdaInConstructor() throws Exception {
@@ -1391,6 +1391,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/loops.kt");
}
@Test
@TestMetadata("nestedClass.kt")
public void testNestedClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/nestedClass.kt");
}
@Test
@TestMetadata("postponedLambdaInConstructor.kt")
public void testPostponedLambdaInConstructor() throws Exception {