[FIR] Don't create call to this in generated provideDelegate for top-level extension properies

This commit is contained in:
Dmitriy Novozhilov
2020-09-16 18:54:14 +03:00
parent a666eee67b
commit 57ceb0fa20
@@ -289,7 +289,21 @@ fun FirPropertyBuilder.generateAccessorsByDelegate(
} }
val isMember = ownerSymbol != null val isMember = ownerSymbol != null
fun thisRef(): FirExpression = /*
* If we have delegation with provide delegate then we generate call like
* `delegateExpression.provideDelegate(this, ::prop)`
* Note that `this` is always reference for dispatch receiver
* unlike other `this` references in `getValue` `setValue` calls, where
* `this` is reference to closest receiver (extension, then dispatch)
*
* So for top-level extension properties we should generate
* val A.prop by delegateExpression.provideDelegate(null, ::prop)
* get() = delegate.getValue(this@prop, ::prop)
*
* And for this case we can pass isForDelegateProviderCall to this reference
* generator function
*/
fun thisRef(isForDelegateProviderCall: Boolean = false): FirExpression =
when { when {
ownerSymbol != null -> buildThisReceiverExpression { ownerSymbol != null -> buildThisReceiverExpression {
source = delegateBuilder.source source = delegateBuilder.source
@@ -301,7 +315,7 @@ fun FirPropertyBuilder.generateAccessorsByDelegate(
type = ownerSymbol.constructStarProjectedType(typeParameterNumber) type = ownerSymbol.constructStarProjectedType(typeParameterNumber)
} }
} }
isExtension -> buildThisReceiverExpression { isExtension && !isForDelegateProviderCall -> buildThisReceiverExpression {
source = delegateBuilder.source source = delegateBuilder.source
calleeReference = buildImplicitThisReference { calleeReference = buildImplicitThisReference {
boundSymbol = this@generateAccessorsByDelegate.symbol boundSymbol = this@generateAccessorsByDelegate.symbol
@@ -353,7 +367,7 @@ fun FirPropertyBuilder.generateAccessorsByDelegate(
source = delegateBuilder.source source = delegateBuilder.source
name = PROVIDE_DELEGATE name = PROVIDE_DELEGATE
} }
argumentList = buildBinaryArgumentList(thisRef(), propertyRef()) argumentList = buildBinaryArgumentList(thisRef(isForDelegateProviderCall = true), propertyRef())
} }
delegate = delegateBuilder.build() delegate = delegateBuilder.build()
if (stubMode) return if (stubMode) return