From b90c8eb8ed6a2ac6b3e2e3e90dec2a501b56c633 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 30 Mar 2020 11:50:03 +0300 Subject: [PATCH] [FIR] Analyze annotations of local class before class itself --- .../resolve/cfg/annotatedLocalClass.dot | 103 ++++++++++++++++++ .../resolve/cfg/annotatedLocalClass.kt | 16 +++ .../resolve/cfg/annotatedLocalClass.txt | 25 +++++ .../fir/FirDiagnosticsTestGenerated.java | 5 + ...DiagnosticsWithLightTreeTestGenerated.java | 5 + .../FirDeclarationsResolveTransformer.kt | 4 +- .../body/resolve/LocalClassesResolution.kt | 2 + 7 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.dot create mode 100644 compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.dot new file mode 100644 index 00000000000..ede20da077a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.dot @@ -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 " style="filled" fillcolor=red]; + 1 [label="Delegated constructor call: super()"]; + 2 [label="Exit function " 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|/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 " style="filled" fillcolor=red]; + 24 [label="Delegated constructor call: super()"]; + 25 [label="Exit function " 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}; + +} diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt new file mode 100644 index 00000000000..75a77b82182 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.kt @@ -0,0 +1,16 @@ +// !DUMP_CFG + +annotation class Ann + +fun foo(b: Boolean) { + if (b) { + return + } + + @Ann + class Local() + + bar() +} + +fun bar() {} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.txt b/compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.txt new file mode 100644 index 00000000000..62b9f33a9b1 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/annotatedLocalClass.txt @@ -0,0 +1,25 @@ +FILE: annotatedLocalClass.kt + public final annotation class Ann : R|kotlin/Annotation| { + public constructor(): R|Ann| { + super() + } + + } + public final fun foo(b: R|kotlin/Boolean|): R|kotlin/Unit| { + when () { + R|/b| -> { + ^foo Unit + } + } + + @R|Ann|() local final class Local : R|kotlin/Any| { + public[local] constructor(): R|Local| { + super() + } + + } + + R|/bar|() + } + public final fun bar(): R|kotlin/Unit| { + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index 87ad42ed7f4..0ceda08c643 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -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"); diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 09818c5fafb..6c4a13fdc1b 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -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"); diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 6f395d8170a..26a2a8f77fb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.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 { if (anonymousObject !in context.targetedLocalClasses) { - return anonymousObject.runAllPhasesForLocalClass(components, data).compose() + return anonymousObject.runAllPhasesForLocalClass(transformer, components, data).compose() } dataFlowAnalyzer.enterClass() val type = anonymousObject.defaultType() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt index 6eae0cea3ca..a2616b59479 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt @@ -14,10 +14,12 @@ import org.jetbrains.kotlin.fir.resolve.transformers.runTypeResolvePhaseForLocal import org.jetbrains.kotlin.fir.scopes.impl.createCurrentScopeList fun > 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,