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.
This commit is contained in:
committed by
Dmitriy Novozhilov
parent
fb14b03824
commit
ae902e6fe5
@@ -10,18 +10,18 @@ open class A3(x: String, y: String = "") {
|
||||
constructor(x: String, b: Boolean = true) : this(x, x)
|
||||
}
|
||||
|
||||
class B3_1 : <!AMBIGUITY{LT}!><!AMBIGUITY{PSI}!>A3<!>("")<!>
|
||||
class B3_1 : <!AMBIGUITY!>A3<!>("")
|
||||
class B3_2 : A3("", "asas")
|
||||
class B3_3 : A3("", true)
|
||||
class B3_4 : <!NONE_APPLICABLE{LT}!><!NONE_APPLICABLE{PSI}!>A3<!>("", Unit)<!>
|
||||
class B3_4 : <!NONE_APPLICABLE!>A3<!>("", Unit)
|
||||
|
||||
open class A4(val x: Byte)
|
||||
class B4 : <!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>A4<!>( 1 + 1)<!>
|
||||
class B4 : <!INAPPLICABLE_CANDIDATE!>A4<!>( 1 + 1)
|
||||
|
||||
open class A5 {
|
||||
constructor(x: Byte)
|
||||
constructor(x: Short)
|
||||
}
|
||||
|
||||
class B5_1 : <!NONE_APPLICABLE{LT}!><!NONE_APPLICABLE{PSI}!>A5<!>(1 + 1)<!>
|
||||
class B5_2 : <!NONE_APPLICABLE{LT}!><!NONE_APPLICABLE{PSI}!>A5<!>(100 * 2)<!>
|
||||
class B5_1 : <!NONE_APPLICABLE!>A5<!>(1 + 1)
|
||||
class B5_2 : <!NONE_APPLICABLE!>A5<!>(100 * 2)
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ class G<E : Double>(val balue: E) : F<E>(balue) {
|
||||
override var rest: E = balue
|
||||
}
|
||||
|
||||
class H<E : String>(val balue: E) : <!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>F<E><!>(balue)<!> {
|
||||
class H<E : String>(val balue: E) : <!INAPPLICABLE_CANDIDATE!>F<E><!>(balue) {
|
||||
override var rest: E = balue // no report because of INAPPLICABLE_CANDIDATE
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ class G<E : Double>(val balue: E) : F<E>(balue) {
|
||||
override fun rest(): E = balue
|
||||
}
|
||||
|
||||
class H<E : String>(val balue: E) : <!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>F<E><!>(balue)<!> {
|
||||
class H<E : String>(val balue: E) : <!INAPPLICABLE_CANDIDATE!>F<E><!>(balue) {
|
||||
override fun rest(): E = balue // no report because of INAPPLICABLE_CANDIDATE
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -21,7 +21,7 @@ class CallBasedInExpressionGenerator(
|
||||
gen(argument).let { if (isInverted) <!UNRESOLVED_REFERENCE!>Invert<!>(it) else it }
|
||||
|
||||
private fun gen(argument: StackValue): BranchedValue =
|
||||
object : <!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>BranchedValue<!>(argument, null, argument.<!UNRESOLVED_REFERENCE!>type<!>, <!UNRESOLVED_REFERENCE!>Opcodes<!>.IFEQ)<!> {
|
||||
object : <!INAPPLICABLE_CANDIDATE!>BranchedValue<!>(argument, null, argument.<!UNRESOLVED_REFERENCE!>type<!>, <!UNRESOLVED_REFERENCE!>Opcodes<!>.IFEQ) {
|
||||
override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) {
|
||||
invokeFunction(v)
|
||||
<!UNRESOLVED_REFERENCE!>coerceTo<!>(type, kotlinType, v)
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
class Outer { inner class Inner }
|
||||
fun test() {
|
||||
val x = object : <!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>Outer.Inner<!>()<!> { }
|
||||
val x = object : <!UNRESOLVED_REFERENCE!>Outer.Inner<!>() { }
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@ sealed class WithPrivateConstructor private constructor(val x: Int) {
|
||||
private constructor() : this(42)
|
||||
}
|
||||
|
||||
object First : <!NONE_APPLICABLE{LT}!><!NONE_APPLICABLE{PSI}!>WithPrivateConstructor<!>()<!> // error
|
||||
object Second : <!NONE_APPLICABLE{LT}!><!NONE_APPLICABLE{PSI}!>WithPrivateConstructor<!>(0)<!> // error
|
||||
object First : <!NONE_APPLICABLE!>WithPrivateConstructor<!>() // error
|
||||
object Second : <!NONE_APPLICABLE!>WithPrivateConstructor<!>(0) // error
|
||||
|
||||
@@ -13,7 +13,7 @@ abstract class My<T : Some> {
|
||||
|
||||
abstract val z: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>test.My.T<!>
|
||||
|
||||
class Some : <!UNRESOLVED_REFERENCE{LT}!><!SUPERTYPE_NOT_A_CLASS_OR_INTERFACE, UNRESOLVED_REFERENCE{PSI}!>T<!>()<!>
|
||||
class Some : <!SUPERTYPE_NOT_A_CLASS_OR_INTERFACE, UNRESOLVED_REFERENCE!>T<!>()
|
||||
}
|
||||
|
||||
abstract class Your<T : Some> : <!SUPERTYPE_NOT_A_CLASS_OR_INTERFACE!>T<!>
|
||||
|
||||
+2
-2
@@ -38,7 +38,7 @@ interface E {
|
||||
|
||||
}
|
||||
|
||||
class Test2 : A.APublicI, <!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>B.BInner<!>()<!> {
|
||||
class Test2 : A.APublicI, <!UNRESOLVED_REFERENCE!>B.BInner<!>() {
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class Test4 : E, A.AProtectedI {
|
||||
|
||||
}
|
||||
|
||||
class Test5 : C.CPublicI, <!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>B.BInner<!>()<!> {
|
||||
class Test5 : C.CPublicI, <!UNRESOLVED_REFERENCE!>B.BInner<!>() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
||||
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by error<FirSourceElement, PsiElement>()
|
||||
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning<FirSourceElement, PsiElement>()
|
||||
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
|
||||
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning<FirSourceElement, PsiElement>(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||
val EXPLICIT_DELEGATION_CALL_REQUIRED by error<FirSourceElement, PsiElement>(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||
val SEALED_CLASS_CONSTRUCTOR_CALL by error<FirSourceElement, PsiElement>()
|
||||
|
||||
// TODO: Consider creating a parameter list position strategy and report on the parameter list instead
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ object FirErrors {
|
||||
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by error0<FirSourceElement, PsiElement>()
|
||||
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
|
||||
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error0<FirSourceElement, KtNamedDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
|
||||
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||
val EXPLICIT_DELEGATION_CALL_REQUIRED by error0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||
val SEALED_CLASS_CONSTRUCTOR_CALL by error0<FirSourceElement, PsiElement>()
|
||||
val DATA_CLASS_WITHOUT_PARAMETERS by error0<FirSourceElement, KtPrimaryConstructor>()
|
||||
val DATA_CLASS_VARARG_PARAMETER by error0<FirSourceElement, KtParameter>()
|
||||
|
||||
+21
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
+2
@@ -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<Boolean>()
|
||||
|
||||
override fun build(): FirDelegatedConstructorCall {
|
||||
@@ -44,6 +45,7 @@ class FirDelegatedConstructorCallBuilder : FirCallBuilder, FirAnnotationContaine
|
||||
argumentList,
|
||||
constructedTypeRef,
|
||||
dispatchReceiver,
|
||||
calleeReference,
|
||||
isThis,
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -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 <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
|
||||
-4
@@ -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
|
||||
|
||||
@@ -26,4 +26,4 @@ package toplevelObjectDeclarations
|
||||
override fun foo() : Int = 1
|
||||
}
|
||||
|
||||
val z = y.foo()
|
||||
val z = y.foo()
|
||||
|
||||
Reference in New Issue
Block a user