From 600b5ec6e5368e48878e65fdd872c1a0df6a6fad Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 28 Jun 2023 15:10:46 +0200 Subject: [PATCH] [FIR] preserve real source for property accessors ^ KT-59705 If property is delegated, it can't have property accessors with non-default impl, but it can contain property accessors declarations with non-default visibility, annotations, etc. Seems, it's more logical to preserve them as fake sources than use property itself --- .../level/api/fir/util/declarationUtils.kt | 3 +- .../properties/getterWithDelegation.kt | 6 + .../properties/getterWithDelegation.txt | 231 ++++++++++++++++++ ...otLazyDeclarationResolveTestGenerated.java | 6 + ...ceLazyDeclarationResolveTestGenerated.java | 6 + .../kotlin/fir/builder/ConversionUtils.kt | 6 +- 6 files changed, 255 insertions(+), 3 deletions(-) create mode 100644 analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.kt create mode 100644 analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.txt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt index acf965d3fed..985af944c90 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt @@ -158,7 +158,8 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider( else -> errorWithFirSpecificEntries("Invalid container", psi = this) } - return candidate?.takeIf { it.realPsi == this } + //property accessors for properties with delegation have KtFakeSourceElementKind.DelegatedPropertyAccessor kind + return candidate?.takeIf { it.psi == this } } fun FirAnonymousInitializer.containingClass(): FirRegularClass { diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.kt b/analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.kt new file mode 100644 index 00000000000..fd9c8d46ea3 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.kt @@ -0,0 +1,6 @@ +val one: Int by Prp() +@Deprecated("reason") get + +class Prp { + fun getValue() = 1 +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.txt b/analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.txt new file mode 100644 index 00000000000..d7fb75f28e9 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.txt @@ -0,0 +1,231 @@ +RAW_FIR: +FILE: [ResolvedTo(RAW_FIR)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public? final? [ResolvedTo(RAW_FIR)] val one: Intby LAZY_EXPRESSION + @Deprecated[Unresolved](LAZY_EXPRESSION) public? [ResolvedTo(RAW_FIR)] get(): { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +IMPORTS: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public? final? [ResolvedTo(RAW_FIR)] val one: Intby LAZY_EXPRESSION + @Deprecated[Unresolved](LAZY_EXPRESSION) public? [ResolvedTo(RAW_FIR)] get(): { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +COMPILER_REQUIRED_ANNOTATIONS: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public? final? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] val one: Intby LAZY_EXPRESSION + @R|kotlin/Deprecated|[CompilerRequiredAnnotations](String(reason)) public? [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] get(): { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +COMPANION_GENERATION: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public? final? [ResolvedTo(COMPANION_GENERATION)] val one: Intby LAZY_EXPRESSION + @R|kotlin/Deprecated|[CompilerRequiredAnnotations](String(reason)) public? [ResolvedTo(COMPANION_GENERATION)] get(): { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +SUPER_TYPES: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public? final? [ResolvedTo(SUPER_TYPES)] val one: Intby LAZY_EXPRESSION + @R|kotlin/Deprecated|[CompilerRequiredAnnotations](String(reason)) public? [ResolvedTo(SUPER_TYPES)] get(): { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +TYPES: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public? final? [ResolvedTo(TYPES)] val one: R|kotlin/Int|by LAZY_EXPRESSION + @R|kotlin/Deprecated|[Types](String(reason)) public? [ResolvedTo(TYPES)] get(): R|kotlin/Int| { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +STATUS: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public final [ResolvedTo(STATUS)] val one: R|kotlin/Int|by LAZY_EXPRESSION + @R|kotlin/Deprecated|[Types](String(reason)) public [ResolvedTo(STATUS)] get(): R|kotlin/Int| { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +EXPECT_ACTUAL_MATCHING: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public final [ResolvedTo(EXPECT_ACTUAL_MATCHING)] val one: R|kotlin/Int|by LAZY_EXPRESSION + @R|kotlin/Deprecated|[Types](String(reason)) public [ResolvedTo(EXPECT_ACTUAL_MATCHING)] get(): R|kotlin/Int| { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +ARGUMENTS_OF_ANNOTATIONS: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] val one: R|kotlin/Int|by LAZY_EXPRESSION + @R|kotlin/Deprecated|[Types](String(reason)) public [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] get(): R|kotlin/Int| { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +CONTRACTS: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public final [ResolvedTo(CONTRACTS)] val one: R|kotlin/Int|by Prp#() + @R|kotlin/Deprecated|[Types](String(reason)) public [ResolvedTo(CONTRACTS)] get(): R|kotlin/Int| { + ^ D|/one|.getValue#(Null(null), ::R|/one|) + } + public? final? [ResolvedTo(RAW_FIR)] class Prp : R|kotlin/Any| { + public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public? final? [ResolvedTo(RAW_FIR)] fun getValue(): { LAZY_BLOCK } + + } + +IMPLICIT_TYPES_BODY_RESOLVE: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] val one: R|kotlin/Int|by R|/Prp.Prp|() + @R|kotlin/Deprecated|[Types](message = String(reason)) public [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] get(): R|kotlin/Int| { + ^ D|/one|.R|/Prp.getValue#|(Null(null), ::R|/one|) + } + public final [ResolvedTo(STATUS)] class Prp : R|kotlin/Any| { + public [ResolvedTo(STATUS)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] fun getValue(): R|kotlin/Int| { + ^getValue Int(1) + } + + } + +ANNOTATIONS_ARGUMENTS_MAPPING: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] val one: R|kotlin/Int|by R|/Prp.Prp|() + @R|kotlin/Deprecated|[Types](message = String(reason)) public [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] get(): R|kotlin/Int| { + ^ D|/one|.R|/Prp.getValue#|(Null(null), ::R|/one|) + } + public final [ResolvedTo(STATUS)] class Prp : R|kotlin/Any| { + public [ResolvedTo(STATUS)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] fun getValue(): R|kotlin/Int| { + ^getValue Int(1) + } + + } + +BODY_RESOLVE: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public final [ResolvedTo(BODY_RESOLVE)] val one: R|kotlin/Int|by R|/Prp.Prp|() + @R|kotlin/Deprecated|[Types](message = String(reason)) public [ResolvedTo(BODY_RESOLVE)] get(): R|kotlin/Int| { + ^ D|/one|.R|/Prp.getValue#|(Null(null), ::R|/one|) + } + public final [ResolvedTo(STATUS)] class Prp : R|kotlin/Any| { + public [ResolvedTo(STATUS)] [ContainingClassKey=Prp] constructor(): R|Prp| { + LAZY_super + } + + public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] fun getValue(): R|kotlin/Int| { + ^getValue Int(1) + } + + } + +FILE RAW TO BODY: +FILE: [ResolvedTo(IMPORTS)] getterWithDelegation.kt + [ResolvedTo(BODY_RESOLVE)] annotations container + public final [ResolvedTo(BODY_RESOLVE)] val one: R|kotlin/Int|by R|/Prp.Prp|() + @R|kotlin/Deprecated|[Types](message = String(reason)) public [ResolvedTo(BODY_RESOLVE)] get(): R|kotlin/Int| { + ^ D|/one|.R|/Prp.getValue#|(Null(null), ::R|/one|) + } + public final [ResolvedTo(BODY_RESOLVE)] class Prp : R|kotlin/Any| { + public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Prp] constructor(): R|Prp| { + super() + } + + public final [ResolvedTo(BODY_RESOLVE)] fun getValue(): R|kotlin/Int| { + ^getValue Int(1) + } + + } diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOutOfContentRootLazyDeclarationResolveTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOutOfContentRootLazyDeclarationResolveTestGenerated.java index 3d5627ad334..f652e0408e1 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOutOfContentRootLazyDeclarationResolveTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirOutOfContentRootLazyDeclarationResolveTestGenerated.java @@ -693,6 +693,12 @@ public class FirOutOfContentRootLazyDeclarationResolveTestGenerated extends Abst KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/lazyResolve/properties"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("getterWithDelegation.kt") + public void testGetterWithDelegation() throws Exception { + runTest("analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.kt"); + } + @Test @TestMetadata("hierarchyWithOverride.kt") public void testHierarchyWithOverride() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirSourceLazyDeclarationResolveTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirSourceLazyDeclarationResolveTestGenerated.java index b527f926dfb..f6a1c1896e2 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirSourceLazyDeclarationResolveTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/FirSourceLazyDeclarationResolveTestGenerated.java @@ -693,6 +693,12 @@ public class FirSourceLazyDeclarationResolveTestGenerated extends AbstractFirSou KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/lazyResolve/properties"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("getterWithDelegation.kt") + public void testGetterWithDelegation() throws Exception { + runTest("analysis/low-level-api-fir/testdata/lazyResolve/properties/getterWithDelegation.kt"); + } + @Test @TestMetadata("hierarchyWithOverride.kt") public void testHierarchyWithOverride() throws Exception { diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt index 8a4c84036f1..5d249ca11ae 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt @@ -417,8 +417,9 @@ fun FirPropertyBuilder.generateAccessorsByDelegate( val annotations = getter?.annotations val returnTarget = FirFunctionTarget(null, isLambda = false) val getterStatus = getter?.status + val getterElement = getter?.source?.fakeElement(KtFakeSourceElementKind.DelegatedPropertyAccessor) ?: fakeSource getter = buildPropertyAccessor { - this.source = fakeSource + this.source = getterElement this.moduleData = moduleData origin = FirDeclarationOrigin.Source returnTypeRef = FirImplicitTypeRefImplWithoutSource @@ -456,8 +457,9 @@ fun FirPropertyBuilder.generateAccessorsByDelegate( val annotations = setter?.annotations val parameterAnnotations = setter?.valueParameters?.firstOrNull()?.annotations val setterStatus = setter?.status + val setterElement = setter?.source?.fakeElement(KtFakeSourceElementKind.DelegatedPropertyAccessor) ?: fakeSource setter = buildPropertyAccessor { - this.source = fakeSource + this.source = setterElement this.moduleData = moduleData origin = FirDeclarationOrigin.Source returnTypeRef = moduleData.session.builtinTypes.unitType