[FIR] Analyze annotations of local class before class itself

This commit is contained in:
Dmitriy Novozhilov
2020-03-30 11:50:03 +03:00
parent 1177a56815
commit b90c8eb8ed
7 changed files with 158 additions and 2 deletions
@@ -0,0 +1,103 @@
digraph annotatedLocalClass_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter function <init>" style="filled" fillcolor=red];
1 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
2 [label="Exit function <init>" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
subgraph cluster_1 {
color=red
3 [label="Enter class Ann" style="filled" fillcolor=red];
4 [label="Exit class Ann" style="filled" fillcolor=red];
}
3 -> {4} [color=green];
subgraph cluster_2 {
color=red
5 [label="Enter function foo" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
6 [label="Enter when"];
subgraph cluster_4 {
color=blue
7 [label="Enter when branch condition "];
8 [label="Access variable R|<local>/b|"];
9 [label="Exit when branch condition"];
}
10 [label="Synthetic else branch"];
11 [label="Enter when branch result"];
subgraph cluster_5 {
color=blue
12 [label="Enter block"];
13 [label="Jump: ^foo Unit"];
14 [label="Stub" style="filled" fillcolor=gray];
15 [label="Exit block" style="filled" fillcolor=gray];
}
16 [label="Exit when branch result" style="filled" fillcolor=gray];
17 [label="Exit when"];
}
subgraph cluster_6 {
color=blue
18 [label="Enter annotation"];
19 [label="Exit annotation"];
}
20 [label="Exit local class foo"];
21 [label="Function call: R|/bar|()"];
22 [label="Exit function foo" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {11 10};
10 -> {17};
11 -> {12};
12 -> {13};
13 -> {22};
13 -> {14} [style=dotted];
14 -> {15} [style=dotted];
15 -> {16} [style=dotted];
16 -> {17} [style=dotted];
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
subgraph cluster_7 {
color=red
23 [label="Enter function <init>" style="filled" fillcolor=red];
24 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
25 [label="Exit function <init>" style="filled" fillcolor=red];
}
23 -> {24};
24 -> {25};
subgraph cluster_8 {
color=red
26 [label="Enter class Local" style="filled" fillcolor=red];
27 [label="Exit class Local" style="filled" fillcolor=red];
}
26 -> {27} [color=green];
subgraph cluster_9 {
color=red
28 [label="Enter function bar" style="filled" fillcolor=red];
29 [label="Exit function bar" style="filled" fillcolor=red];
}
28 -> {29};
}
@@ -0,0 +1,16 @@
// !DUMP_CFG
annotation class Ann
fun foo(b: Boolean) {
if (b) {
return
}
@Ann
class Local()
bar()
}
fun bar() {}
@@ -0,0 +1,25 @@
FILE: annotatedLocalClass.kt
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|Ann| {
super<R|kotlin/Any|>()
}
}
public final fun foo(b: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
R|<local>/b| -> {
^foo Unit
}
}
@R|Ann|() local final class Local : R|kotlin/Any| {
public[local] constructor(): R|Local| {
super<R|kotlin/Any|>()
}
}
R|/bar|()
}
public final fun bar(): R|kotlin/Unit| {
}
@@ -607,6 +607,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/cfg"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("annotatedLocalClass.kt")
public void testAnnotatedLocalClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
}
@TestMetadata("binaryOperations.kt")
public void testBinaryOperations() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/binaryOperations.kt");
@@ -607,6 +607,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/cfg"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("annotatedLocalClass.kt")
public void testAnnotatedLocalClass() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt");
}
@TestMetadata("binaryOperations.kt")
public void testBinaryOperations() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/cfg/binaryOperations.kt");
@@ -276,7 +276,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
context.storeClass(regularClass)
if (regularClass.isLocal && regularClass !in context.targetedLocalClasses) {
return regularClass.runAllPhasesForLocalClass(components, data).compose()
return regularClass.runAllPhasesForLocalClass(transformer, components, data).compose()
}
return withTypeParametersOf(regularClass) {
@@ -315,7 +315,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
data: ResolutionMode
): CompositeTransformResult<FirStatement> {
if (anonymousObject !in context.targetedLocalClasses) {
return anonymousObject.runAllPhasesForLocalClass(components, data).compose()
return anonymousObject.runAllPhasesForLocalClass(transformer, components, data).compose()
}
dataFlowAnalyzer.enterClass()
val type = anonymousObject.defaultType()
@@ -14,10 +14,12 @@ import org.jetbrains.kotlin.fir.resolve.transformers.runTypeResolvePhaseForLocal
import org.jetbrains.kotlin.fir.scopes.impl.createCurrentScopeList
fun <F : FirClass<F>> F.runAllPhasesForLocalClass(
transformer: FirAbstractBodyResolveTransformer,
components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents,
resolutionMode: ResolutionMode
): F {
if (this.resolvePhase > FirResolvePhase.RAW_FIR) return this
this.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
val localClassesNavigationInfo = collectLocalClassesNavigationInfo()
runSupertypeResolvePhaseForLocalClass(
components.session,