From 6c26aeeb97601d6248992eff862d9be36d5d48b2 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 4 Aug 2023 22:13:31 +0900 Subject: [PATCH] [LL API] Check declaration resolution status in 'ContextCollector' tests --- .../contextCollector/contextReceivers.txt | 16 ++++++++++- .../contextReceiversClass.txt | 19 ++++++++++++- .../contextCollector/extensionFunction.txt | 9 +++++- .../contextCollector/extensionLambdas.txt | 18 +++++++++++- .../contextCollector/innerClasses.txt | 27 ++++++++++++++++-- .../contextCollector/lambdaArguments.txt | 16 ++++++++++- .../contextCollector/nestedClasses.txt | 23 ++++++++++++++- .../testdata/contextCollector/simple.kt | 9 ++++++ .../testdata/contextCollector/simple.txt | 28 ++++++++++++++++++- .../contextCollector/smartCastArgument.txt | 16 ++++++++++- .../smartCastReceiverArgument.txt | 23 ++++++++++++++- .../api/fir/AbstractContextCollectorTest.kt | 17 +++++++---- 12 files changed, 203 insertions(+), 18 deletions(-) diff --git a/analysis/low-level-api-fir/testdata/contextCollector/contextReceivers.txt b/analysis/low-level-api-fir/testdata/contextCollector/contextReceivers.txt index 66213d6a382..4d6a4f492d5 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/contextReceivers.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/contextReceivers.txt @@ -26,4 +26,18 @@ Tower Data Context: Type: Bar Label: Bar Element 9 - Scope: FirLocalScope \ No newline at end of file + Scope: FirLocalScope + +FILE: [ResolvedTo(IMPORTS)] contextReceivers.kt + public abstract [ResolvedTo(STATUS)] interface Foo : R|kotlin/Any| { + public abstract [ResolvedTo(CONTRACTS)] fun foo(): R|kotlin/Int| + + } + public abstract [ResolvedTo(STATUS)] interface Bar : R|kotlin/Any| { + public abstract [ResolvedTo(CONTRACTS)] fun bar(): R|kotlin/Int| + + } + context(R|Foo|, R|Bar|) + public final [ResolvedTo(BODY_RESOLVE)] fun test(): R|kotlin/Unit| { + this@R|/test|.R|/Foo.foo|().R|kotlin/Int.plus|(this@R|/test|.R|/Bar.bar|()) + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/contextReceiversClass.txt b/analysis/low-level-api-fir/testdata/contextCollector/contextReceiversClass.txt index 711ffc5090d..5b78dfaf51e 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/contextReceiversClass.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/contextReceiversClass.txt @@ -27,4 +27,21 @@ Tower Data Context: Element 9 Scope: FirLocalScope Element 10 - Scope: FirLocalScope \ No newline at end of file + Scope: FirLocalScope + +FILE: [ResolvedTo(IMPORTS)] contextReceiversClass.kt + public abstract [ResolvedTo(STATUS)] interface Foo : R|kotlin/Any| { + public abstract [ResolvedTo(CONTRACTS)] fun foo(): R|kotlin/Int| + + } + context(R|Foo|) + public final [ResolvedTo(STATUS)] class Test : R|kotlin/Any| { + public [ResolvedTo(STATUS)] constructor(): R|Test| { + LAZY_super + } + + public final [ResolvedTo(BODY_RESOLVE)] fun test(): R|kotlin/Unit| { + this@R|/Test|.R|/Foo.foo|() + } + + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/extensionFunction.txt b/analysis/low-level-api-fir/testdata/contextCollector/extensionFunction.txt index c429ad3fb6b..9482e735123 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/extensionFunction.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/extensionFunction.txt @@ -20,4 +20,11 @@ Tower Data Context: FirNamedFunctionSymbol public final fun R|kotlin/String|.test(): R|kotlin/Unit| Type: kotlin/String Element 9 - Scope: FirLocalScope \ No newline at end of file + Scope: FirLocalScope + +FILE: [ResolvedTo(IMPORTS)] extensionFunction.kt + public final [ResolvedTo(BODY_RESOLVE)] fun R|kotlin/String|.test(): R|kotlin/Unit| { + R|/consume|(this@R|/test|) + } + public final [ResolvedTo(CONTRACTS)] fun consume([ResolvedTo(CONTRACTS)] obj: R|kotlin/Any|): R|kotlin/Unit| { + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/extensionLambdas.txt b/analysis/low-level-api-fir/testdata/contextCollector/extensionLambdas.txt index 7af20ff8f00..f05b815b50b 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/extensionLambdas.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/extensionLambdas.txt @@ -32,4 +32,20 @@ Tower Data Context: FirAnonymousFunctionSymbol num@fun R|kotlin/Int|.(): R|kotlin/Unit| Type: kotlin/Int Element 14 - Scope: FirLocalScope \ No newline at end of file + Scope: FirLocalScope + +FILE: [ResolvedTo(IMPORTS)] extensionLambdas.kt + public final [ResolvedTo(BODY_RESOLVE)] fun test(): R|kotlin/Unit| { + R|/block|(String(foo), = [ResolvedTo(BODY_RESOLVE)] foo@fun R|kotlin/String|.(): R|kotlin/Unit| { + R|/block|(Int(42), = [ResolvedTo(BODY_RESOLVE)] num@fun R|kotlin/Int|.(): R|kotlin/Unit| { + R|/consume|(this@R|special/anonymous|.R|kotlin/String.length|.R|kotlin/Int.plus|(this@R|special/anonymous|)) + } + ) + } + ) + } + public final [ResolvedTo(CONTRACTS)] fun <[ResolvedTo(CONTRACTS)] T> block([ResolvedTo(CONTRACTS)] reciever: R|T|, [ResolvedTo(CONTRACTS)] block: R|T.() -> kotlin/Unit|): R|kotlin/Unit| { + receiver#.block#() + } + public final [ResolvedTo(CONTRACTS)] fun consume([ResolvedTo(CONTRACTS)] num: R|kotlin/Int|): R|kotlin/Unit| { + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/innerClasses.txt b/analysis/low-level-api-fir/testdata/contextCollector/innerClasses.txt index 9f2814d128a..3d5aef74f20 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/innerClasses.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/innerClasses.txt @@ -20,7 +20,7 @@ Tower Data Context: Element 8 Scope: FirNestedClassifierScopeImpl Classifiers: - FirRegularClassSymbol public final inner class Bar : R|kotlin/Any| + FirRegularClassSymbol public final inner class Bar : R|kotlin/Any| Element 9 Implicit receiver: FirRegularClassSymbol public final class Foo : R|kotlin/Any| @@ -31,7 +31,7 @@ Tower Data Context: FirTypeParameterSymbol B Element 11 Implicit receiver: - FirRegularClassSymbol public final inner class Bar : R|kotlin/Any| + FirRegularClassSymbol public final inner class Bar : R|kotlin/Any| Type: test/Foo.Bar Element 12 Scope: FirLocalScope @@ -39,4 +39,25 @@ Tower Data Context: FirValueParameterSymbol b: R|B| FirValueParameterSymbol f: R|F| Element 13 - Scope: FirLocalScope \ No newline at end of file + Scope: FirLocalScope + +FILE: [ResolvedTo(IMPORTS)] innerClasses.kt + public final [ResolvedTo(STATUS)] class Foo<[ResolvedTo(STATUS)] F> : R|kotlin/Any| { + public [ResolvedTo(STATUS)] constructor<[ResolvedTo(STATUS)] F>(): R|test/Foo| { + LAZY_super + } + + public final inner [ResolvedTo(STATUS)] class Bar<[ResolvedTo(STATUS)] B, [ResolvedTo(STATUS)] Outer(F)> : R|kotlin/Any| { + public [ResolvedTo(STATUS)] test/Foo.constructor<[ResolvedTo(STATUS)] B>(): R|test/Foo.Bar| { + LAZY_super + } + + public final [ResolvedTo(BODY_RESOLVE)] fun test([ResolvedTo(BODY_RESOLVE)] f: R|F|, [ResolvedTo(BODY_RESOLVE)] b: R|B|): R|kotlin/Unit| { + R|test/consume#|(R|/f|) + } + + } + + } + public final [ResolvedTo(CONTRACTS)] fun consume([ResolvedTo(CONTRACTS)] obj: R|kotlin/Any|): R|kotlin/Unit| { + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/lambdaArguments.txt b/analysis/low-level-api-fir/testdata/contextCollector/lambdaArguments.txt index 52192c367e3..8cfb4ed1940 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/lambdaArguments.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/lambdaArguments.txt @@ -28,4 +28,18 @@ Tower Data Context: Properties: FirValueParameterSymbol n: R|kotlin/Int| Element 12 - Scope: FirLocalScope \ No newline at end of file + Scope: FirLocalScope + +FILE: [ResolvedTo(IMPORTS)] lambdaArguments.kt + public final [ResolvedTo(BODY_RESOLVE)] fun test(): R|kotlin/Unit| { + R|/block|(String(foo), = [ResolvedTo(BODY_RESOLVE)] block@fun ([ResolvedTo(BODY_RESOLVE)] s: R|kotlin/String|): R|kotlin/Unit| { + R|/block|(Int(42), = [ResolvedTo(BODY_RESOLVE)] block@fun ([ResolvedTo(BODY_RESOLVE)] n: R|kotlin/Int|): R|kotlin/Unit| { + R|/s|.R|kotlin/String.length|.R|kotlin/Int.plus|(R|/n|) + } + ) + } + ) + } + public final [ResolvedTo(CONTRACTS)] fun <[ResolvedTo(CONTRACTS)] T> block([ResolvedTo(CONTRACTS)] obj: R|T|, [ResolvedTo(CONTRACTS)] block: R|(T) -> kotlin/Unit|): R|kotlin/Unit| { + block#(obj#) + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/nestedClasses.txt b/analysis/low-level-api-fir/testdata/contextCollector/nestedClasses.txt index 85e5d713dc8..20e902a3e9d 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/nestedClasses.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/nestedClasses.txt @@ -30,4 +30,25 @@ Tower Data Context: Properties: FirValueParameterSymbol b: R|B| Element 11 - Scope: FirLocalScope \ No newline at end of file + Scope: FirLocalScope + +FILE: [ResolvedTo(IMPORTS)] nestedClasses.kt + public final [ResolvedTo(STATUS)] class Foo<[ResolvedTo(STATUS)] F> : R|kotlin/Any| { + public [ResolvedTo(STATUS)] constructor<[ResolvedTo(STATUS)] F>(): R|test/Foo| { + LAZY_super + } + + public final [ResolvedTo(STATUS)] class Bar<[ResolvedTo(STATUS)] B> : R|kotlin/Any| { + public [ResolvedTo(STATUS)] constructor<[ResolvedTo(STATUS)] B>(): R|test/Foo.Bar| { + LAZY_super + } + + public final [ResolvedTo(BODY_RESOLVE)] fun test([ResolvedTo(BODY_RESOLVE)] b: R|B|): R|kotlin/Unit| { + R|test/consume#|(R|/b|) + } + + } + + } + public final [ResolvedTo(CONTRACTS)] fun consume([ResolvedTo(CONTRACTS)] obj: R|kotlin/Any|): R|kotlin/Unit| { + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/simple.kt b/analysis/low-level-api-fir/testdata/contextCollector/simple.kt index cb9bd9e62d4..6efba05d248 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/simple.kt +++ b/analysis/low-level-api-fir/testdata/contextCollector/simple.kt @@ -7,4 +7,13 @@ class Foo { val x = 1.0f print(x) } +} + +class Unrelated { + val unrelatedMember: Boolean + get() = true +} + +fun unrelatedFunction(): Int { + return "foo".length } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/simple.txt b/analysis/low-level-api-fir/testdata/contextCollector/simple.txt index 50bd6f14979..194909351fb 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/simple.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/simple.txt @@ -24,4 +24,30 @@ Tower Data Context: Element 9 Scope: FirLocalScope Properties: - FirPropertySymbol lval x: R|kotlin/Float| \ No newline at end of file + FirPropertySymbol lval x: R|kotlin/Float| + +FILE: [ResolvedTo(IMPORTS)] simple.kt + public final [ResolvedTo(STATUS)] class Foo : R|kotlin/Any| { + public [ResolvedTo(STATUS)] constructor(): R|foo/Foo| { + LAZY_super + } + + public final [ResolvedTo(STATUS)] val a: R|kotlin/Int| + public [ResolvedTo(STATUS)] get(): R|kotlin/Int| + + public final [ResolvedTo(BODY_RESOLVE)] fun foo([ResolvedTo(BODY_RESOLVE)] p: R|kotlin/String|): R|kotlin/Unit| { + [ResolvedTo(BODY_RESOLVE)] lval x: R|kotlin/Float| = Float(1.0) + #(R|/x|) + } + + } + public? final? [ResolvedTo(RAW_FIR)] class Unrelated : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] constructor(): R|foo/Unrelated| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] val unrelatedMember: Boolean + public? [ResolvedTo(RAW_FIR)] get(): Boolean { LAZY_BLOCK } + + } + public? final? [ResolvedTo(RAW_FIR)] fun unrelatedFunction(): Int { LAZY_BLOCK } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/smartCastArgument.txt b/analysis/low-level-api-fir/testdata/contextCollector/smartCastArgument.txt index 18609dfc09f..274b72a276a 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/smartCastArgument.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/smartCastArgument.txt @@ -25,4 +25,18 @@ Smart Casts: FirValueParameterSymbol obj: R|kotlin/Any| Types: Foo - kotlin/Any \ No newline at end of file + kotlin/Any + +FILE: [ResolvedTo(IMPORTS)] smartCastArgument.kt + public abstract [ResolvedTo(STATUS)] interface Foo : R|kotlin/Any| { + } + public final [ResolvedTo(BODY_RESOLVE)] fun test([ResolvedTo(BODY_RESOLVE)] obj: R|kotlin/Any|): R|kotlin/Unit| { + when () { + (R|/obj| is R|Foo|) -> { + R|/consume|(R|/obj|) + } + } + + } + public final [ResolvedTo(CONTRACTS)] fun consume([ResolvedTo(CONTRACTS)] obj: R|kotlin/Any|): R|kotlin/Unit| { + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/contextCollector/smartCastReceiverArgument.txt b/analysis/low-level-api-fir/testdata/contextCollector/smartCastReceiverArgument.txt index 1087daa8000..363a8d6c671 100644 --- a/analysis/low-level-api-fir/testdata/contextCollector/smartCastReceiverArgument.txt +++ b/analysis/low-level-api-fir/testdata/contextCollector/smartCastReceiverArgument.txt @@ -28,4 +28,25 @@ Smart Casts: Types: Foo kotlin/Any - Bar \ No newline at end of file + Bar + +FILE: [ResolvedTo(IMPORTS)] smartCastReceiverArgument.kt + public abstract [ResolvedTo(STATUS)] interface Foo : R|kotlin/Any| { + } + public abstract [ResolvedTo(STATUS)] interface Bar : R|kotlin/Any| { + } + public final [ResolvedTo(BODY_RESOLVE)] fun test([ResolvedTo(BODY_RESOLVE)] obj: R|kotlin/Any|): R|kotlin/Unit| { + when () { + (R|/obj| is R|Foo|) -> { + when () { + (R|/obj| is R|Bar|) -> { + R|/obj|.R|/consume|(R|/obj|) + } + } + + } + } + + } + public final [ResolvedTo(CONTRACTS)] fun R|Bar|.consume([ResolvedTo(CONTRACTS)] obj: R|Foo|): R|kotlin/Unit| { + } \ No newline at end of file diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractContextCollectorTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractContextCollectorTest.kt index c9bbe51cc3f..61d93c809da 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractContextCollectorTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractContextCollectorTest.kt @@ -51,17 +51,22 @@ abstract class AbstractContextCollectorTest : AbstractAnalysisApiBasedSingleModu val elementContext = ContextCollector.process(firFile, sessionHolder, targetElement) ?: error("Context not found for element $targetElement") - val actualText = ElementContextRenderer.render(elementContext) + val firRenderer = FirRenderer.withResolvePhase() + + val actualText = buildString { + ElementContextRenderer.render(elementContext, this) + appendLine() + append(firRenderer.renderElementAsString(firFile, trim = true)) + } + testServices.assertions.assertEqualsToTestDataFileSibling(actualText) } } private object ElementContextRenderer { - fun render(context: ContextCollector.Context): String { - return buildString { - renderTowerDataContext(context.towerDataContext) - renderSmartCasts(context.smartCasts) - }.trim() + fun render(context: ContextCollector.Context, builder: StringBuilder) = with(builder) { + renderTowerDataContext(context.towerDataContext) + renderSmartCasts(context.smartCasts) } private fun StringBuilder.renderTowerDataContext(towerDataContext: FirTowerDataContext) {