From ae902e6fe50307f13b6e6466e98a5c1a8f2f1c71 Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Thu, 25 Mar 2021 16:27:03 -0700 Subject: [PATCH] FIR: fix source of callee reference in delegated constructor call Previously the callee reference of a delegated constructor call is always the same as the call itself. This violates the contract that no two FIR elements can have identical sources. In addition, this sets the entire call expression as the source of the callee expression. This change instead sets the proper constructor ref as the callee. Also fixed EXPLICIT_DELEGATION_CALL_REQUIRED type. It should be an error instead of a warning. --- .../resolve/delegatingConstructorCall.kt | 10 ++++----- .../propertyTypeMismatchOnOverride.kt | 2 +- .../returnTypeMismatchOnOverride.kt | 2 +- .../CallBasedInExpressionGenerator.kt | 2 +- .../problems/objectDerivedFromInnerClass.kt | 2 +- .../testData/resolve/sealedClass.kt | 4 ++-- .../testData/resolve/typeParameterVsNested.kt | 2 +- .../resolve/visibility/exposedSupertype.kt | 4 ++-- .../diagnostics/FirDiagnosticsList.kt | 2 +- .../fir/analysis/diagnostics/FirErrors.kt | 2 +- .../converter/DeclarationsConverter.kt | 21 +++++++++++++++++++ .../kotlin/fir/builder/RawFirBuilder.kt | 18 ++++++++++++++++ .../FirDelegatedConstructorCallBuilder.kt | 2 ++ .../impl/FirDelegatedConstructorCallImpl.kt | 2 +- .../generator/ImplementationConfigurator.kt | 4 ---- .../diagnostics/tests/objects/Objects.fir.kt | 2 +- 16 files changed, 59 insertions(+), 22 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/resolve/delegatingConstructorCall.kt b/compiler/fir/analysis-tests/testData/resolve/delegatingConstructorCall.kt index 74b8f919ea8..5d6d63eb1a1 100644 --- a/compiler/fir/analysis-tests/testData/resolve/delegatingConstructorCall.kt +++ b/compiler/fir/analysis-tests/testData/resolve/delegatingConstructorCall.kt @@ -10,18 +10,18 @@ open class A3(x: String, y: String = "") { constructor(x: String, b: Boolean = true) : this(x, x) } -class B3_1 : A3("") +class B3_1 : A3("") class B3_2 : A3("", "asas") class B3_3 : A3("", true) -class B3_4 : A3("", Unit) +class B3_4 : A3("", Unit) open class A4(val x: Byte) -class B4 : A4( 1 + 1) +class B4 : A4( 1 + 1) open class A5 { constructor(x: Byte) constructor(x: Short) } -class B5_1 : A5(1 + 1) -class B5_2 : A5(100 * 2) +class B5_1 : A5(1 + 1) +class B5_2 : A5(100 * 2) diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/propertyTypeMismatchOnOverride.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/propertyTypeMismatchOnOverride.kt index ed71e8f5054..4a98050c4e7 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/propertyTypeMismatchOnOverride.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/propertyTypeMismatchOnOverride.kt @@ -26,7 +26,7 @@ class G(val balue: E) : F(balue) { override var rest: E = balue } -class H(val balue: E) : F(balue) { +class H(val balue: E) : F(balue) { override var rest: E = balue // no report because of INAPPLICABLE_CANDIDATE } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/returnTypeMismatchOnOverride.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/returnTypeMismatchOnOverride.kt index 187ce893956..c967908f762 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/returnTypeMismatchOnOverride.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/returnTypeMismatchOnOverride.kt @@ -27,7 +27,7 @@ class G(val balue: E) : F(balue) { override fun rest(): E = balue } -class H(val balue: E) : F(balue) { +class H(val balue: E) : F(balue) { override fun rest(): E = balue // no report because of INAPPLICABLE_CANDIDATE } diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt b/compiler/fir/analysis-tests/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt index 337300ebe84..b4f776776d1 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt @@ -21,7 +21,7 @@ class CallBasedInExpressionGenerator( gen(argument).let { if (isInverted) Invert(it) else it } private fun gen(argument: StackValue): BranchedValue = - object : BranchedValue(argument, null, argument.type, Opcodes.IFEQ) { + object : BranchedValue(argument, null, argument.type, Opcodes.IFEQ) { override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) { invokeFunction(v) coerceTo(type, kotlinType, v) diff --git a/compiler/fir/analysis-tests/testData/resolve/problems/objectDerivedFromInnerClass.kt b/compiler/fir/analysis-tests/testData/resolve/problems/objectDerivedFromInnerClass.kt index 9f0e79eaeed..b3985793836 100644 --- a/compiler/fir/analysis-tests/testData/resolve/problems/objectDerivedFromInnerClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/problems/objectDerivedFromInnerClass.kt @@ -1,4 +1,4 @@ class Outer { inner class Inner } fun test() { - val x = object : Outer.Inner() { } + val x = object : Outer.Inner() { } } diff --git a/compiler/fir/analysis-tests/testData/resolve/sealedClass.kt b/compiler/fir/analysis-tests/testData/resolve/sealedClass.kt index 76cc50ceb00..071205181ae 100644 --- a/compiler/fir/analysis-tests/testData/resolve/sealedClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/sealedClass.kt @@ -6,5 +6,5 @@ sealed class WithPrivateConstructor private constructor(val x: Int) { private constructor() : this(42) } -object First : WithPrivateConstructor() // error -object Second : WithPrivateConstructor(0) // error +object First : WithPrivateConstructor() // error +object Second : WithPrivateConstructor(0) // error diff --git a/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.kt b/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.kt index 9126477c414..cfa08ca9bf9 100644 --- a/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.kt +++ b/compiler/fir/analysis-tests/testData/resolve/typeParameterVsNested.kt @@ -13,7 +13,7 @@ abstract class My { abstract val z: test.My.T - class Some : T() + class Some : T() } abstract class Your : T diff --git a/compiler/fir/analysis-tests/testData/resolve/visibility/exposedSupertype.kt b/compiler/fir/analysis-tests/testData/resolve/visibility/exposedSupertype.kt index a9b9742ad19..8c7e5def17d 100644 --- a/compiler/fir/analysis-tests/testData/resolve/visibility/exposedSupertype.kt +++ b/compiler/fir/analysis-tests/testData/resolve/visibility/exposedSupertype.kt @@ -38,7 +38,7 @@ interface E { } -class Test2 : A.APublicI, B.BInner() { +class Test2 : A.APublicI, B.BInner() { } @@ -50,7 +50,7 @@ class Test4 : E, A.AProtectedI { } -class Test5 : C.CPublicI, B.BInner() { +class Test5 : C.CPublicI, B.BInner() { } diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index effe6b3aba8..af2705e85a1 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -118,7 +118,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() { val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by error() val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning() val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error(PositioningStrategy.DECLARATION_NAME) - val EXPLICIT_DELEGATION_CALL_REQUIRED by warning(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) + val EXPLICIT_DELEGATION_CALL_REQUIRED by error(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) val SEALED_CLASS_CONSTRUCTOR_CALL by error() // TODO: Consider creating a parameter list position strategy and report on the parameter list instead diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 98bb25ede92..e0433baad2d 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -115,7 +115,7 @@ object FirErrors { val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by error0() val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0() val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error0(SourceElementPositioningStrategies.DECLARATION_NAME) - val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) + val EXPLICIT_DELEGATION_CALL_REQUIRED by error0(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) val SEALED_CLASS_CONSTRUCTOR_CALL by error0() val DATA_CLASS_WITHOUT_PARAMETERS by error0() val DATA_CLASS_VARARG_PARAMETER by error0() diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 46f52e708de..c2456e66307 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -37,6 +37,8 @@ import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeModifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeParameterModifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeProjectionModifier +import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference +import org.jetbrains.kotlin.fir.references.builder.buildExplicitThisReference import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations import org.jetbrains.kotlin.fir.scopes.FirScopeProvider @@ -736,6 +738,11 @@ class DeclarationsConverter( source = delegatedConstructorSource ?: selfTypeSource?.fakeElement(FirFakeSourceElementKind.DelegatingConstructorCall) constructedTypeRef = classWrapper.delegatedSuperTypeRef.copyWithNewSourceKind(FirFakeSourceElementKind.ImplicitTypeRef) isThis = false + calleeReference = buildExplicitSuperReference { + source = classWrapper.delegatedSuperTypeRef.source?.fakeElement(FirFakeSourceElementKind.DelegatingConstructorCall) + ?: this@buildDelegatedConstructorCall.source?.fakeElement(FirFakeSourceElementKind.DelegatingConstructorCall) + superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef + } extractArgumentsFrom(classWrapper.superTypeCallEntry, stubMode) } @@ -875,6 +882,20 @@ class DeclarationsConverter( } constructedTypeRef = delegatedType.copyWithNewSourceKind(FirFakeSourceElementKind.ImplicitTypeRef) this.isThis = isThis + val calleeKind = if (isImplicit) FirFakeSourceElementKind.ImplicitConstructor else FirFakeSourceElementKind.DelegatingConstructorCall + val calleeSource = constructorDelegationCall.getChildNodeByType(CONSTRUCTOR_DELEGATION_REFERENCE) + ?.toFirSourceElement(calleeKind) + ?: this@buildDelegatedConstructorCall.source?.fakeElement(calleeKind) + calleeReference = if (isThis) { + buildExplicitThisReference { + this.source = calleeSource + } + } else { + buildExplicitSuperReference { + source = calleeSource + superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef + } + } extractArgumentsFrom(firValueArguments, stubMode) } } diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 1560101ec87..6cb1ff170e3 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -632,6 +632,11 @@ open class RawFirBuilder( source = constructorCall ?: constructorSource.fakeElement(FirFakeSourceElementKind.DelegatingConstructorCall) constructedTypeRef = delegatedSuperTypeRef.copyWithNewSourceKind(FirFakeSourceElementKind.ImplicitTypeRef) isThis = false + calleeReference = buildExplicitSuperReference { + source = superTypeCallEntry?.calleeExpression?.toFirSourceElement(FirFakeSourceElementKind.DelegatingConstructorCall) + ?: this@buildDelegatedConstructorCall.source?.fakeElement(FirFakeSourceElementKind.DelegatingConstructorCall) + superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef + } if (!stubMode) { superTypeCallEntry?.extractArgumentsTo(this) } @@ -1189,6 +1194,19 @@ open class RawFirBuilder( this.source = source constructedTypeRef = delegatedType.copyWithNewSourceKind(FirFakeSourceElementKind.ImplicitTypeRef) this.isThis = isThis + val calleeKind = if (isImplicit)FirFakeSourceElementKind.ImplicitConstructor else FirFakeSourceElementKind.DelegatingConstructorCall + val calleeSource = this@convert.calleeExpression?.toFirSourceElement(calleeKind) + ?: source.fakeElement(calleeKind) + this.calleeReference = if (isThis) { + buildExplicitThisReference { + this.source = calleeSource + } + } else { + buildExplicitSuperReference { + this.source = calleeSource + this.superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef + } + } if (!stubMode) { extractArgumentsTo(this) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirDelegatedConstructorCallBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirDelegatedConstructorCallBuilder.kt index 476cdf3ccc1..5c5be506254 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirDelegatedConstructorCallBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirDelegatedConstructorCallBuilder.kt @@ -35,6 +35,7 @@ class FirDelegatedConstructorCallBuilder : FirCallBuilder, FirAnnotationContaine override var argumentList: FirArgumentList = FirEmptyArgumentList lateinit var constructedTypeRef: FirTypeRef var dispatchReceiver: FirExpression = FirNoReceiverExpression + lateinit var calleeReference: FirReference var isThis: Boolean by kotlin.properties.Delegates.notNull() override fun build(): FirDelegatedConstructorCall { @@ -44,6 +45,7 @@ class FirDelegatedConstructorCallBuilder : FirCallBuilder, FirAnnotationContaine argumentList, constructedTypeRef, dispatchReceiver, + calleeReference, isThis, ) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirDelegatedConstructorCallImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirDelegatedConstructorCallImpl.kt index ddd3071ecbd..72e14bf56cf 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirDelegatedConstructorCallImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirDelegatedConstructorCallImpl.kt @@ -27,9 +27,9 @@ internal class FirDelegatedConstructorCallImpl( override var argumentList: FirArgumentList, override var constructedTypeRef: FirTypeRef, override var dispatchReceiver: FirExpression, + override var calleeReference: FirReference, override val isThis: Boolean, ) : FirDelegatedConstructorCall() { - override var calleeReference: FirReference = if (isThis) FirExplicitThisReference(source, null) else FirExplicitSuperReference(source, null, constructedTypeRef) override val isSuper: Boolean get() = !isThis override fun acceptChildren(visitor: FirVisitor, data: D) { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 5dae160a747..7266595914c 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -87,10 +87,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() impl(doWhileLoop) impl(delegatedConstructorCall) { - default( - "calleeReference", - "if (isThis) FirExplicitThisReference(source, null) else FirExplicitSuperReference(source, null, constructedTypeRef)" - ) default("isSuper") { value = "!isThis" withGetter = true diff --git a/compiler/testData/diagnostics/tests/objects/Objects.fir.kt b/compiler/testData/diagnostics/tests/objects/Objects.fir.kt index 56cb0460e7d..1907fec8769 100644 --- a/compiler/testData/diagnostics/tests/objects/Objects.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/Objects.fir.kt @@ -26,4 +26,4 @@ package toplevelObjectDeclarations override fun foo() : Int = 1 } - val z = y.foo() \ No newline at end of file + val z = y.foo()