From 4b2a122f808860f0f541e7f76c2ad27f8a6d5c2d Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 2 Oct 2023 15:56:52 +0200 Subject: [PATCH] FIR2IR: make delegate field/accessors sources closer to PSI2IR #KT-59864 Fixed --- .../FirAmbiguousAnonymousTypeChecker.kt | 8 +++-- .../Fir2IrCallableDeclarationsGenerator.kt | 34 ++++++++++--------- .../kotlin/fir/builder/ConversionUtils.kt | 5 ++- .../declarations/delegatedProperties.fir.txt | 12 +++---- .../testData/ir/sourceRanges/kt24258.fir.txt | 4 +-- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAmbiguousAnonymousTypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAmbiguousAnonymousTypeChecker.kt index aa35f697ed0..34160dcb332 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAmbiguousAnonymousTypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAmbiguousAnonymousTypeChecker.kt @@ -43,8 +43,12 @@ object FirAmbiguousAnonymousTypeChecker : FirBasicDeclarationChecker() { */ val (type, source) = when (declaration) { is FirProperty -> { - declaration.initializer?.resolvedType?.let { it to declaration.source } - ?: (declaration.getter?.body?.singleExpressionType to declaration.getter?.source) + declaration.initializer?.resolvedType?.let { it to declaration.source } ?: run { + val getter = declaration.getter + // Getter can have delegate call as the source, but diagnostic must be reported on KtDeclaration + val getterDeclarationSource = if (declaration.delegate != null) declaration.source else getter?.source + (getter?.body?.singleExpressionType to getterDeclarationSource) + } } is FirFunction -> declaration.body?.singleExpressionType to declaration.source else -> error("Should not be there") diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt index 646f83d74ff..3b809f03d02 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/Fir2IrCallableDeclarationsGenerator.kt @@ -566,22 +566,24 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi ): IrField = convertCatching(firProperty) { val inferredType = type ?: firInitializerExpression!!.resolvedType.toIrType() return declareIrField { symbol -> - irFactory.createField( - startOffset = irProperty.startOffset, - endOffset = irProperty.endOffset, - origin = origin, - name = name, - visibility = visibility, - symbol = symbol, - type = inferredType, - isFinal = isFinal, - isStatic = firProperty.isStatic || !(irProperty.parent is IrClass || irProperty.parent is IrScript), - isExternal = firProperty.isExternal, - ).also { - it.correspondingPropertySymbol = irProperty.symbol - }.apply { - metadata = FirMetadataSource.Property(firProperty) - convertAnnotationsForNonDeclaredMembers(firProperty, origin) + (firProperty.delegate ?: firProperty.backingField ?: firProperty).convertWithOffsets { startOffset: Int, endOffset: Int -> + irFactory.createField( + startOffset = startOffset, + endOffset = endOffset, + origin = origin, + name = name, + visibility = visibility, + symbol = symbol, + type = inferredType, + isFinal = isFinal, + isStatic = firProperty.isStatic || !(irProperty.parent is IrClass || irProperty.parent is IrScript), + isExternal = firProperty.isExternal, + ).also { + it.correspondingPropertySymbol = irProperty.symbol + }.apply { + metadata = FirMetadataSource.Property(firProperty) + convertAnnotationsForNonDeclaredMembers(firProperty, origin) + } } } } 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 2cac13283c8..368a67e7633 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 @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.builder import com.intellij.psi.tree.IElementType import org.jetbrains.kotlin.KtFakeSourceElementKind +import org.jetbrains.kotlin.KtRealSourceElementKind import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.contracts.description.LogicOperationKind import org.jetbrains.kotlin.descriptors.Modality @@ -446,7 +447,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 + val getterElement = getter?.source?.takeIf { + it.kind == KtRealSourceElementKind + }?.fakeElement(KtFakeSourceElementKind.DelegatedPropertyAccessor) ?: fakeSource getter = buildPropertyAccessor { this.source = getterElement this.moduleData = moduleData diff --git a/compiler/testData/ir/sourceRanges/declarations/delegatedProperties.fir.txt b/compiler/testData/ir/sourceRanges/declarations/delegatedProperties.fir.txt index 2c31ab1543b..ba0208f9353 100644 --- a/compiler/testData/ir/sourceRanges/declarations/delegatedProperties.fir.txt +++ b/compiler/testData/ir/sourceRanges/declarations/delegatedProperties.fir.txt @@ -5,7 +5,7 @@ @5:0..13:1 DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' @5:0..13:1 INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:MyClass modality:FINAL visibility:public superTypes:[kotlin.Any]' @6:4..8:5 PROPERTY name:lazyProp visibility:public modality:FINAL [delegated,val] - @6:4..8:5 FIELD PROPERTY_DELEGATE name:lazyProp$delegate type:kotlin.Lazy visibility:private [final] + @6:20..8:5 FIELD PROPERTY_DELEGATE name:lazyProp$delegate type:kotlin.Lazy visibility:private [final] @6:20..8:5 EXPRESSION_BODY @6:20..8:5 CALL 'public final fun lazy (initializer: kotlin.Function0): kotlin.Lazy declared in kotlin' type=kotlin.Lazy origin=null @6:25..8:5 FUN_EXPR type=kotlin.Function0 origin=LAMBDA @@ -13,8 +13,8 @@ @7:8..9 BLOCK_BODY @7:9..9 RETURN type=kotlin.Nothing from='local final fun (): kotlin.Int declared in .MyClass.lazyProp$delegate' @7:8..9 CONST Int type=kotlin.Int value=5 - @6:4..8:5 FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.MyClass) returnType:kotlin.Int - @6:4..8:5 VALUE_PARAMETER name: type:.MyClass + @6:20..8:5 FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.MyClass) returnType:kotlin.Int + @6:20..8:5 VALUE_PARAMETER name: type:.MyClass @6:20..8:5 BLOCK_BODY @6:20..8:5 RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .MyClass' @6:20..8:5 CALL 'public final fun getValue (thisRef: kotlin.Any?, property: kotlin.reflect.KProperty<*>): T of kotlin.getValue [inline,operator] declared in kotlin' type=kotlin.Int origin=null @@ -23,7 +23,7 @@ @6:20..8:5 GET_VAR ': .MyClass declared in .MyClass.' type=.MyClass origin=null @6:20..8:5 PROPERTY_REFERENCE 'public final lazyProp: kotlin.Int [delegated,val]' field=null getter='public final fun (): kotlin.Int declared in .MyClass' setter=null type=kotlin.reflect.KProperty1<.MyClass, kotlin.Int> origin=PROPERTY_REFERENCE_FOR_DELEGATE @10:4..12:5 PROPERTY name:observableProp visibility:public modality:FINAL [delegated,var] - @10:4..12:5 FIELD PROPERTY_DELEGATE name:observableProp$delegate type:kotlin.properties.ReadWriteProperty visibility:private [final] + @10:34..12:5 FIELD PROPERTY_DELEGATE name:observableProp$delegate type:kotlin.properties.ReadWriteProperty visibility:private [final] @10:44..12:5 EXPRESSION_BODY @10:44..12:5 CALL 'public final fun observable (initialValue: T of kotlin.properties.Delegates.observable, onChange: kotlin.Function3<@[ParameterName(name = 'property')] kotlin.reflect.KProperty<*>, @[ParameterName(name = 'oldValue')] T of kotlin.properties.Delegates.observable, @[ParameterName(name = 'newValue')] T of kotlin.properties.Delegates.observable, kotlin.Unit>): kotlin.properties.ReadWriteProperty [inline] declared in kotlin.properties.Delegates' type=kotlin.properties.ReadWriteProperty origin=null @10:34..43 GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Delegates modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.properties.Delegates @@ -40,8 +40,8 @@ @11:22..25 GET_VAR 'old: @[ParameterName(name = 'oldValue')] kotlin.String declared in .MyClass.observableProp$delegate.' type=@[ParameterName(name = 'oldValue')] kotlin.String origin=null @11:25..31 CONST String type=kotlin.String value=", now " @11:32..35 GET_VAR 'new: @[ParameterName(name = 'newValue')] kotlin.String declared in .MyClass.observableProp$delegate.' type=@[ParameterName(name = 'newValue')] kotlin.String origin=null - @10:4..12:5 FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.MyClass) returnType:kotlin.String - @10:4..12:5 VALUE_PARAMETER name: type:.MyClass + @10:34..12:5 FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.MyClass) returnType:kotlin.String + @10:34..12:5 VALUE_PARAMETER name: type:.MyClass @10:34..12:5 BLOCK_BODY @10:34..12:5 RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .MyClass' @10:34..12:5 CALL 'public abstract fun getValue (thisRef: T of kotlin.properties.ReadWriteProperty, property: kotlin.reflect.KProperty<*>): V of kotlin.properties.ReadWriteProperty [operator] declared in kotlin.properties.ReadWriteProperty' type=kotlin.String origin=null diff --git a/compiler/testData/ir/sourceRanges/kt24258.fir.txt b/compiler/testData/ir/sourceRanges/kt24258.fir.txt index edeff6ee8fc..26851ca5489 100644 --- a/compiler/testData/ir/sourceRanges/kt24258.fir.txt +++ b/compiler/testData/ir/sourceRanges/kt24258.fir.txt @@ -1,6 +1,6 @@ @0:0..9:0 FILE fqName: fileName:/kt24258.kt @3:0..53 PROPERTY name:lazyNullString visibility:public modality:FINAL [delegated,val] - @3:0..53 FIELD PROPERTY_DELEGATE name:lazyNullString$delegate type:kotlin.Lazy<@[FlexibleNullability] kotlin.String?> visibility:private [final,static] + @3:30..53 FIELD PROPERTY_DELEGATE name:lazyNullString$delegate type:kotlin.Lazy<@[FlexibleNullability] kotlin.String?> visibility:private [final,static] @3:30..53 EXPRESSION_BODY @3:30..53 CALL 'public final fun lazy (initializer: kotlin.Function0): kotlin.Lazy declared in kotlin' type=kotlin.Lazy<@[FlexibleNullability] kotlin.String?> origin=null @3:35..53 FUN_EXPR type=kotlin.Function0<@[FlexibleNullability] kotlin.String?> origin=LAMBDA @@ -8,7 +8,7 @@ @3:37..51 BLOCK_BODY @3:51..51 RETURN type=kotlin.Nothing from='local final fun (): @[FlexibleNullability] kotlin.String? declared in .lazyNullString$delegate' @3:39..51 CALL 'public open fun nullString (): @[FlexibleNullability] kotlin.String? declared in .J' type=@[FlexibleNullability] kotlin.String? origin=null - @3:0..53 FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.String + @3:30..53 FUN DELEGATED_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.String @3:30..53 BLOCK_BODY @3:30..53 RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' @3:30..53 TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String