FIR: Support context receivers in Fir2Ir
This commit is contained in:
+5
@@ -147,6 +147,11 @@ open class FirJvmMangleComputer(
|
|||||||
builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK)
|
builder.appendSignature(MangleConstant.STATIC_MEMBER_MARK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contextReceivers.forEach {
|
||||||
|
builder.appendSignature(MangleConstant.CONTEXT_RECEIVER_PREFIX)
|
||||||
|
mangleType(builder, it.typeRef.coneType)
|
||||||
|
}
|
||||||
|
|
||||||
receiverTypeRef?.let {
|
receiverTypeRef?.let {
|
||||||
builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX)
|
builder.appendSignature(MangleConstant.EXTENSION_RECEIVER_PREFIX)
|
||||||
mangleType(builder, it.coneType)
|
mangleType(builder, it.coneType)
|
||||||
|
|||||||
@@ -721,3 +721,9 @@ fun FirVariableAssignment.getIrAssignmentOrigin(): IrStatementOrigin {
|
|||||||
}
|
}
|
||||||
return IrStatementOrigin.EQ
|
return IrStatementOrigin.EQ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirCallableDeclaration.contextReceiversForFunctionOrContainingProperty(): List<FirContextReceiver> =
|
||||||
|
if (this is FirPropertyAccessor)
|
||||||
|
this.propertySymbol?.fir?.contextReceivers.orEmpty()
|
||||||
|
else
|
||||||
|
this.contextReceivers
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ class Fir2IrClassifierStorage(
|
|||||||
|
|
||||||
private val enumEntryCache = mutableMapOf<FirEnumEntry, IrEnumEntry>()
|
private val enumEntryCache = mutableMapOf<FirEnumEntry, IrEnumEntry>()
|
||||||
|
|
||||||
|
private val fieldsForContextReceivers = mutableMapOf<IrClass, List<IrField>>()
|
||||||
|
|
||||||
private val localStorage = Fir2IrLocalStorage()
|
private val localStorage = Fir2IrLocalStorage()
|
||||||
|
|
||||||
private fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
|
private fun FirTypeRef.toIrType(typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
|
||||||
@@ -126,9 +128,39 @@ class Fir2IrClassifierStorage(
|
|||||||
if (klass is FirRegularClass) {
|
if (klass is FirRegularClass) {
|
||||||
preCacheTypeParameters(klass)
|
preCacheTypeParameters(klass)
|
||||||
setTypeParameters(klass)
|
setTypeParameters(klass)
|
||||||
|
val fieldsForContextReceiversOfCurrentClass = createContextReceiverFields(klass)
|
||||||
|
if (fieldsForContextReceiversOfCurrentClass.isNotEmpty()) {
|
||||||
|
declarations.addAll(fieldsForContextReceiversOfCurrentClass)
|
||||||
|
fieldsForContextReceivers[this] = fieldsForContextReceiversOfCurrentClass
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IrClass.createContextReceiverFields(klass: FirRegularClass): List<IrField> {
|
||||||
|
if (klass.contextReceivers.isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
val contextReceiverFields = mutableListOf<IrField>()
|
||||||
|
for ((index, contextReceiver) in klass.contextReceivers.withIndex()) {
|
||||||
|
val irField = components.irFactory.createField(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
|
IrDeclarationOrigin.FIELD_FOR_CLASS_CONTEXT_RECEIVER,
|
||||||
|
IrFieldSymbolImpl(),
|
||||||
|
Name.identifier("contextReceiverField$index"),
|
||||||
|
contextReceiver.typeRef.toIrType(),
|
||||||
|
DescriptorVisibilities.PRIVATE,
|
||||||
|
isFinal = true,
|
||||||
|
isExternal = false,
|
||||||
|
isStatic = false
|
||||||
|
)
|
||||||
|
irField.parent = this@createContextReceiverFields
|
||||||
|
contextReceiverFields.add(irField)
|
||||||
|
}
|
||||||
|
|
||||||
|
return contextReceiverFields
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFieldsWithContextReceiversForClass(irClass: IrClass): List<IrField>? = fieldsForContextReceivers[irClass]
|
||||||
|
|
||||||
private fun IrClass.declareSupertypes(klass: FirClass) {
|
private fun IrClass.declareSupertypes(klass: FirClass) {
|
||||||
superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() }
|
superTypes = klass.superTypeRefs.map { superTypeRef -> superTypeRef.toIrType() }
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-10
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor
|
|||||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty
|
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyProperty
|
||||||
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction
|
import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
|
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
|
||||||
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.isKFunctionInvoke
|
import org.jetbrains.kotlin.fir.resolve.isKFunctionInvoke
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
@@ -335,14 +334,21 @@ class Fir2IrDeclarationStorage(
|
|||||||
val type = function.valueParameters.first().returnTypeRef.toIrType(ConversionTypeContext.DEFAULT.inSetter())
|
val type = function.valueParameters.first().returnTypeRef.toIrType(ConversionTypeContext.DEFAULT.inSetter())
|
||||||
declareDefaultSetterParameter(type)
|
declareDefaultSetterParameter(type)
|
||||||
} else if (function != null) {
|
} else if (function != null) {
|
||||||
valueParameters = function.valueParameters.mapIndexed { index, valueParameter ->
|
val contextReceivers = function.contextReceiversForFunctionOrContainingProperty()
|
||||||
createIrParameter(
|
|
||||||
valueParameter, index,
|
contextReceiverParametersCount = contextReceivers.size
|
||||||
useStubForDefaultValueStub = function !is FirConstructor || containingClass?.name != Name.identifier("Enum"),
|
valueParameters = buildList {
|
||||||
typeContext,
|
addContextReceiverParametersTo(contextReceivers, parent, this)
|
||||||
skipDefaultParameter = isFakeOverride
|
|
||||||
).apply {
|
function.valueParameters.mapIndexedTo(this) { index, valueParameter ->
|
||||||
this.parent = parent
|
createIrParameter(
|
||||||
|
valueParameter, index + contextReceiverParametersCount,
|
||||||
|
useStubForDefaultValueStub = function !is FirConstructor || containingClass?.name != Name.identifier("Enum"),
|
||||||
|
typeContext,
|
||||||
|
skipDefaultParameter = isFakeOverride
|
||||||
|
).apply {
|
||||||
|
this.parent = parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,6 +397,18 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addContextReceiverParametersTo(
|
||||||
|
contextReceivers: List<FirContextReceiver>,
|
||||||
|
parent: IrFunction,
|
||||||
|
result: MutableList<IrValueParameter>,
|
||||||
|
) {
|
||||||
|
contextReceivers.mapIndexedTo(result) { index, contextReceiver ->
|
||||||
|
createIrParameterFromContextReceiver(contextReceiver, index).apply {
|
||||||
|
this.parent = parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun <T : IrFunction> T.bindAndDeclareParameters(
|
private fun <T : IrFunction> T.bindAndDeclareParameters(
|
||||||
function: FirFunction?,
|
function: FirFunction?,
|
||||||
irParent: IrDeclarationParent?,
|
irParent: IrDeclarationParent?,
|
||||||
@@ -404,7 +422,9 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T : IrFunction> T.putParametersInScope(function: FirFunction): T {
|
fun <T : IrFunction> T.putParametersInScope(function: FirFunction): T {
|
||||||
for ((firParameter, irParameter) in function.valueParameters.zip(valueParameters)) {
|
val contextReceivers = function.contextReceiversForFunctionOrContainingProperty()
|
||||||
|
|
||||||
|
for ((firParameter, irParameter) in function.valueParameters.zip(valueParameters.drop(contextReceivers.size))) {
|
||||||
localStorage.putParameter(firParameter, irParameter)
|
localStorage.putParameter(firParameter, irParameter)
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
@@ -1055,6 +1075,22 @@ class Fir2IrDeclarationStorage(
|
|||||||
return irParameter
|
return irParameter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createIrParameterFromContextReceiver(
|
||||||
|
contextReceiver: FirContextReceiver,
|
||||||
|
index: Int,
|
||||||
|
): IrValueParameter = convertCatching(contextReceiver) {
|
||||||
|
val type = contextReceiver.typeRef.toIrType()
|
||||||
|
return contextReceiver.convertWithOffsets { startOffset, endOffset ->
|
||||||
|
irFactory.createValueParameter(
|
||||||
|
startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrValueParameterSymbolImpl(),
|
||||||
|
Name.identifier("_context_receiver_$index"), index, type,
|
||||||
|
null,
|
||||||
|
isCrossinline = false, isNoinline = false,
|
||||||
|
isHidden = false, isAssignable = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var lastTemporaryIndex: Int = 0
|
private var lastTemporaryIndex: Int = 0
|
||||||
private fun nextTemporaryIndex(): Int = lastTemporaryIndex++
|
private fun nextTemporaryIndex(): Int = lastTemporaryIndex++
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
package org.jetbrains.kotlin.fir.backend
|
package org.jetbrains.kotlin.fir.backend
|
||||||
|
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.*
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
|
import org.jetbrains.kotlin.KtPsiSourceElement
|
||||||
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
@@ -23,7 +26,6 @@ import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
|
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
|
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
@@ -451,13 +453,39 @@ class Fir2IrVisitor(
|
|||||||
val dispatchReceiver = conversionScope.dispatchReceiverParameter(irClass)
|
val dispatchReceiver = conversionScope.dispatchReceiverParameter(irClass)
|
||||||
if (dispatchReceiver != null) {
|
if (dispatchReceiver != null) {
|
||||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol)
|
val thisRef = IrGetValueImpl(startOffset, endOffset, dispatchReceiver.type, dispatchReceiver.symbol)
|
||||||
|
if (calleeReference.contextReceiverNumber != -1) {
|
||||||
|
val contextReceivers =
|
||||||
|
components.classifierStorage.getFieldsWithContextReceiversForClass(irClass)
|
||||||
|
?: error("Not defined context receivers for $irClass")
|
||||||
|
|
||||||
|
IrGetFieldImpl(
|
||||||
|
startOffset, endOffset, contextReceivers[calleeReference.contextReceiverNumber].symbol,
|
||||||
|
thisReceiverExpression.typeRef.toIrType(),
|
||||||
|
thisRef,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
thisRef
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (boundSymbol is FirCallableSymbol) {
|
} else if (boundSymbol is FirCallableSymbol) {
|
||||||
val receiverSymbol =
|
val irFunction = when (boundSymbol) {
|
||||||
calleeReference.toSymbolForCall(FirNoReceiverExpression, session, classifierStorage, declarationStorage, conversionScope)
|
is FirFunctionSymbol -> declarationStorage.getIrFunctionSymbol(boundSymbol).owner
|
||||||
val receiver = (receiverSymbol?.owner as? IrSimpleFunction)?.extensionReceiverParameter
|
is FirPropertySymbol -> {
|
||||||
|
val property = declarationStorage.getIrPropertySymbol(boundSymbol).owner as? IrProperty
|
||||||
|
property?.let { conversionScope.parentAccessorOfPropertyFromStack(it) }
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
val receiver = irFunction?.let { function ->
|
||||||
|
if (calleeReference.contextReceiverNumber != -1)
|
||||||
|
function.valueParameters[calleeReference.contextReceiverNumber]
|
||||||
|
else
|
||||||
|
function.extensionReceiverParameter
|
||||||
|
}
|
||||||
|
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||||
IrGetValueImpl(startOffset, endOffset, receiver.type, receiver.symbol)
|
IrGetValueImpl(startOffset, endOffset, receiver.type, receiver.symbol)
|
||||||
@@ -1208,4 +1236,4 @@ val KtSourceElement.operationToken: IElementType?
|
|||||||
return if (this is KtPsiSourceElement) (psi as? KtBinaryExpression)?.operationToken
|
return if (this is KtPsiSourceElement) (psi as? KtBinaryExpression)?.operationToken
|
||||||
else treeStructure.findChildByType(lighterASTNode, KtNodeTypes.OPERATION_REFERENCE)?.tokenType
|
else treeStructure.findChildByType(lighterASTNode, KtNodeTypes.OPERATION_REFERENCE)?.tokenType
|
||||||
?: error("No operation reference for binary expression: $lighterASTNode")
|
?: error("No operation reference for binary expression: $lighterASTNode")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -90,7 +90,7 @@ class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComp
|
|||||||
propertyAccessor.annotations += property.annotations
|
propertyAccessor.annotations += property.annotations
|
||||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_SETTER }
|
.filter { it.useSiteTarget == AnnotationUseSiteTarget.PROPERTY_SETTER }
|
||||||
.toIrAnnotations()
|
.toIrAnnotations()
|
||||||
val parameter = propertyAccessor.valueParameters.single()
|
val parameter = propertyAccessor.valueParameters.last()
|
||||||
parameter.annotations += property.annotations
|
parameter.annotations += property.annotations
|
||||||
.filter { it.useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER }
|
.filter { it.useSiteTarget == AnnotationUseSiteTarget.SETTER_PARAMETER }
|
||||||
.toIrAnnotations()
|
.toIrAnnotations()
|
||||||
|
|||||||
+47
-14
@@ -7,19 +7,21 @@ package org.jetbrains.kotlin.fir.backend.generators
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
|
import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
|
||||||
import org.jetbrains.kotlin.fir.*
|
|
||||||
import org.jetbrains.kotlin.fir.backend.*
|
import org.jetbrains.kotlin.fir.backend.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
import org.jetbrains.kotlin.fir.declarations.utils.isCompanion
|
||||||
|
import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
|
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.references.FirDelegateFieldReference
|
import org.jetbrains.kotlin.fir.references.FirDelegateFieldReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
|
import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations
|
||||||
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
|
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
@@ -318,7 +320,7 @@ class CallAndReferenceGenerator(
|
|||||||
getter != null -> IrCallImpl(
|
getter != null -> IrCallImpl(
|
||||||
startOffset, endOffset, type, getter.symbol,
|
startOffset, endOffset, type, getter.symbol,
|
||||||
typeArgumentsCount = getter.typeParameters.size,
|
typeArgumentsCount = getter.typeParameters.size,
|
||||||
valueArgumentsCount = 0,
|
valueArgumentsCount = getter.valueParameters.size,
|
||||||
origin = IrStatementOrigin.GET_PROPERTY,
|
origin = IrStatementOrigin.GET_PROPERTY,
|
||||||
superQualifierSymbol = dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = dispatchReceiver.superQualifierSymbol()
|
||||||
)
|
)
|
||||||
@@ -346,7 +348,7 @@ class CallAndReferenceGenerator(
|
|||||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference, type)
|
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference, type)
|
||||||
}
|
}
|
||||||
}.applyTypeArguments(qualifiedAccess).applyReceivers(qualifiedAccess, explicitReceiverExpression)
|
}.applyTypeArguments(qualifiedAccess).applyReceivers(qualifiedAccess, explicitReceiverExpression)
|
||||||
.applyCallArguments(qualifiedAccess as? FirCall, annotationMode)
|
.applyCallArguments(qualifiedAccess, annotationMode)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
throw IllegalStateException(
|
throw IllegalStateException(
|
||||||
"Error while translating ${qualifiedAccess.render()} " +
|
"Error while translating ${qualifiedAccess.render()} " +
|
||||||
@@ -375,10 +377,11 @@ class CallAndReferenceGenerator(
|
|||||||
setter != null -> IrCallImpl(
|
setter != null -> IrCallImpl(
|
||||||
startOffset, endOffset, type, setter.symbol,
|
startOffset, endOffset, type, setter.symbol,
|
||||||
typeArgumentsCount = setter.typeParameters.size,
|
typeArgumentsCount = setter.typeParameters.size,
|
||||||
valueArgumentsCount = 1,
|
valueArgumentsCount = setter.valueParameters.size,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
||||||
).apply {
|
).apply {
|
||||||
|
putContextReceiverArguments(variableAssignment)
|
||||||
putValueArgument(0, assignedValue)
|
putValueArgument(0, assignedValue)
|
||||||
}
|
}
|
||||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||||
@@ -392,11 +395,11 @@ class CallAndReferenceGenerator(
|
|||||||
setter != null -> IrCallImpl(
|
setter != null -> IrCallImpl(
|
||||||
startOffset, endOffset, type, setter.symbol,
|
startOffset, endOffset, type, setter.symbol,
|
||||||
typeArgumentsCount = setter.typeParameters.size,
|
typeArgumentsCount = setter.typeParameters.size,
|
||||||
valueArgumentsCount = 1,
|
valueArgumentsCount = setter.valueParameters.size,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
||||||
).apply {
|
).apply {
|
||||||
putValueArgument(0, assignedValue)
|
putValueArgument(putContextReceiverArguments(variableAssignment), assignedValue)
|
||||||
}
|
}
|
||||||
backingField != null -> IrSetFieldImpl(
|
backingField != null -> IrSetFieldImpl(
|
||||||
startOffset, endOffset, backingField.symbol, type,
|
startOffset, endOffset, backingField.symbol, type,
|
||||||
@@ -548,10 +551,16 @@ class CallAndReferenceGenerator(
|
|||||||
return ConeSubstitutorByMap(map, session)
|
return ConeSubstitutorByMap(map, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrExpression.applyCallArguments(call: FirCall?, annotationMode: Boolean): IrExpression {
|
internal fun IrExpression.applyCallArguments(
|
||||||
if (call == null) return this
|
statement: FirStatement?,
|
||||||
|
annotationMode: Boolean
|
||||||
|
): IrExpression {
|
||||||
|
val qualifiedAccess = statement as? FirQualifiedAccess
|
||||||
|
val call = statement as? FirCall
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is IrMemberAccessExpression<*> -> {
|
is IrMemberAccessExpression<*> -> {
|
||||||
|
val contextReceiverCount = putContextReceiverArguments(qualifiedAccess)
|
||||||
|
if (call == null) return this
|
||||||
val argumentsCount = call.arguments.size
|
val argumentsCount = call.arguments.size
|
||||||
if (argumentsCount <= valueArgumentsCount) {
|
if (argumentsCount <= valueArgumentsCount) {
|
||||||
apply {
|
apply {
|
||||||
@@ -573,7 +582,10 @@ class CallAndReferenceGenerator(
|
|||||||
val substitutor = (call as? FirFunctionCall)?.buildSubstitutorByCalledFunction(function) ?: ConeSubstitutor.Empty
|
val substitutor = (call as? FirFunctionCall)?.buildSubstitutorByCalledFunction(function) ?: ConeSubstitutor.Empty
|
||||||
if (argumentMapping != null && (annotationMode || argumentMapping.isNotEmpty())) {
|
if (argumentMapping != null && (annotationMode || argumentMapping.isNotEmpty())) {
|
||||||
if (valueParameters != null) {
|
if (valueParameters != null) {
|
||||||
return applyArgumentsWithReorderingIfNeeded(argumentMapping, valueParameters, substitutor, annotationMode)
|
return applyArgumentsWithReorderingIfNeeded(
|
||||||
|
argumentMapping, valueParameters, substitutor, annotationMode,
|
||||||
|
contextReceiverCount,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Case without argument mapping (deserialized annotation)
|
// Case without argument mapping (deserialized annotation)
|
||||||
@@ -584,7 +596,10 @@ class CallAndReferenceGenerator(
|
|||||||
else -> null
|
else -> null
|
||||||
} ?: valueParameters?.get(index)
|
} ?: valueParameters?.get(index)
|
||||||
val argumentExpression = convertArgument(argument, valueParameter, substitutor)
|
val argumentExpression = convertArgument(argument, valueParameter, substitutor)
|
||||||
putValueArgument(valueParameters?.indexOf(valueParameter)?.takeIf { it >= 0 } ?: index, argumentExpression)
|
putValueArgument(
|
||||||
|
(valueParameters?.indexOf(valueParameter)?.takeIf { it >= 0 } ?: index) + contextReceiverCount,
|
||||||
|
argumentExpression
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -600,7 +615,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is IrErrorCallExpressionImpl -> apply {
|
is IrErrorCallExpressionImpl -> apply {
|
||||||
for (argument in call.arguments) {
|
for (argument in call?.arguments.orEmpty()) {
|
||||||
addArgument(visitor.convertToIrExpression(argument))
|
addArgument(visitor.convertToIrExpression(argument))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -608,11 +623,26 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrMemberAccessExpression<*>.putContextReceiverArguments(statement: FirStatement?): Int {
|
||||||
|
val contextReceiverCount = (statement as? FirQualifiedAccess)?.contextReceiverArguments?.size ?: 0
|
||||||
|
if (statement is FirQualifiedAccess && contextReceiverCount > 0) {
|
||||||
|
for (index in 0 until contextReceiverCount) {
|
||||||
|
putValueArgument(
|
||||||
|
index,
|
||||||
|
visitor.convertToIrExpression(statement.contextReceiverArguments[index]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return contextReceiverCount
|
||||||
|
}
|
||||||
|
|
||||||
private fun IrMemberAccessExpression<*>.applyArgumentsWithReorderingIfNeeded(
|
private fun IrMemberAccessExpression<*>.applyArgumentsWithReorderingIfNeeded(
|
||||||
argumentMapping: Map<FirExpression, FirValueParameter>,
|
argumentMapping: Map<FirExpression, FirValueParameter>,
|
||||||
valueParameters: List<FirValueParameter>,
|
valueParameters: List<FirValueParameter>,
|
||||||
substitutor: ConeSubstitutor,
|
substitutor: ConeSubstitutor,
|
||||||
annotationMode: Boolean
|
annotationMode: Boolean,
|
||||||
|
contextReceiverCount: Int,
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
val converted = argumentMapping.entries.map { (argument, parameter) ->
|
val converted = argumentMapping.entries.map { (argument, parameter) ->
|
||||||
parameter to convertArgument(argument, parameter, substitutor, annotationMode)
|
parameter to convertArgument(argument, parameter, substitutor, annotationMode)
|
||||||
@@ -633,13 +663,16 @@ class CallAndReferenceGenerator(
|
|||||||
dispatchReceiver = dispatchReceiver?.freeze("\$this")
|
dispatchReceiver = dispatchReceiver?.freeze("\$this")
|
||||||
extensionReceiver = extensionReceiver?.freeze("\$receiver")
|
extensionReceiver = extensionReceiver?.freeze("\$receiver")
|
||||||
for ((parameter, irArgument) in converted) {
|
for ((parameter, irArgument) in converted) {
|
||||||
putValueArgument(valueParameters.indexOf(parameter), irArgument.freeze(parameter.name.asString()))
|
putValueArgument(
|
||||||
|
valueParameters.indexOf(parameter) + contextReceiverCount,
|
||||||
|
irArgument.freeze(parameter.name.asString())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
statements.add(this@applyArgumentsWithReorderingIfNeeded)
|
statements.add(this@applyArgumentsWithReorderingIfNeeded)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for ((parameter, irArgument) in converted) {
|
for ((parameter, irArgument) in converted) {
|
||||||
putValueArgument(valueParameters.indexOf(parameter), irArgument)
|
putValueArgument(valueParameters.indexOf(parameter) + contextReceiverCount, irArgument)
|
||||||
}
|
}
|
||||||
if (annotationMode) {
|
if (annotationMode) {
|
||||||
for ((index, parameter) in valueParameters.withIndex()) {
|
for ((index, parameter) in valueParameters.withIndex()) {
|
||||||
|
|||||||
+34
-2
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
|||||||
import org.jetbrains.kotlin.fir.resolvedSymbol
|
import org.jetbrains.kotlin.fir.resolvedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
|
||||||
@@ -104,8 +105,9 @@ internal class ClassMemberGenerator(
|
|||||||
irFunction.putParametersInScope(firFunction)
|
irFunction.putParametersInScope(firFunction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val irParameters = valueParameters.drop(firFunction.contextReceivers.size)
|
||||||
val annotationMode = containingClass?.classKind == ClassKind.ANNOTATION_CLASS && irFunction is IrConstructor
|
val annotationMode = containingClass?.classKind == ClassKind.ANNOTATION_CLASS && irFunction is IrConstructor
|
||||||
for ((valueParameter, firValueParameter) in valueParameters.zip(firFunction.valueParameters)) {
|
for ((valueParameter, firValueParameter) in irParameters.zip(firFunction.valueParameters)) {
|
||||||
valueParameter.setDefaultValue(firValueParameter, annotationMode)
|
valueParameter.setDefaultValue(firValueParameter, annotationMode)
|
||||||
annotationGenerator.generate(valueParameter, firValueParameter, irFunction is IrConstructor)
|
annotationGenerator.generate(valueParameter, firValueParameter, irFunction is IrConstructor)
|
||||||
}
|
}
|
||||||
@@ -118,12 +120,42 @@ internal class ClassMemberGenerator(
|
|||||||
val irDelegatingConstructorCall = delegatedConstructor.toIrDelegatingConstructorCall()
|
val irDelegatingConstructorCall = delegatedConstructor.toIrDelegatingConstructorCall()
|
||||||
body.statements += irDelegatingConstructorCall
|
body.statements += irDelegatingConstructorCall
|
||||||
}
|
}
|
||||||
|
val irClass = parent as IrClass
|
||||||
if (delegatedConstructor?.isThis == false) {
|
if (delegatedConstructor?.isThis == false) {
|
||||||
val instanceInitializerCall = IrInstanceInitializerCallImpl(
|
val instanceInitializerCall = IrInstanceInitializerCallImpl(
|
||||||
startOffset, endOffset, (parent as IrClass).symbol, irFunction.constructedClassType
|
startOffset, endOffset, irClass.symbol, irFunction.constructedClassType
|
||||||
)
|
)
|
||||||
body.statements += instanceInitializerCall
|
body.statements += instanceInitializerCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (containingClass is FirRegularClass && containingClass.contextReceivers.isNotEmpty()) {
|
||||||
|
val contextReceiverFields =
|
||||||
|
components.classifierStorage.getFieldsWithContextReceiversForClass(irClass)
|
||||||
|
?: error("Not found context receiver fields")
|
||||||
|
|
||||||
|
val thisParameter =
|
||||||
|
conversionScope.dispatchReceiverParameter(irClass) ?: error("No found this parameter for $irClass")
|
||||||
|
|
||||||
|
val receiver = IrGetValueImpl(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
|
thisParameter.type,
|
||||||
|
thisParameter.symbol,
|
||||||
|
)
|
||||||
|
|
||||||
|
for (index in containingClass.contextReceivers.indices) {
|
||||||
|
val irValueParameter = valueParameters[index]
|
||||||
|
body.statements.add(
|
||||||
|
IrSetFieldImpl(
|
||||||
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
|
contextReceiverFields[index].symbol,
|
||||||
|
receiver,
|
||||||
|
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValueParameter.type, irValueParameter.symbol),
|
||||||
|
components.irBuiltIns.unitType,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val regularBody = firFunction.body?.let { visitor.convertToIrBlockBody(it) }
|
val regularBody = firFunction.body?.let { visitor.convertToIrBlockBody(it) }
|
||||||
if (regularBody != null) {
|
if (regularBody != null) {
|
||||||
body.statements += regularBody.statements
|
body.statements += regularBody.statements
|
||||||
|
|||||||
@@ -197,6 +197,10 @@ class Fir2IrLazyClass(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
with(classifierStorage) {
|
||||||
|
result.addAll(this@Fir2IrLazyClass.createContextReceiverFields(fir))
|
||||||
|
}
|
||||||
|
|
||||||
for (name in scope.getCallableNames()) {
|
for (name in scope.getCallableNames()) {
|
||||||
result += getFakeOverridesByName(name)
|
result += getFakeOverridesByName(name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,15 @@
|
|||||||
package org.jetbrains.kotlin.fir.lazy
|
package org.jetbrains.kotlin.fir.lazy
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||||
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
|
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
|
||||||
import org.jetbrains.kotlin.fir.backend.toIrType
|
import org.jetbrains.kotlin.fir.backend.toIrType
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||||
import org.jetbrains.kotlin.fir.symbols.Fir2IrConstructorSymbol
|
import org.jetbrains.kotlin.fir.symbols.Fir2IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -20,13 +25,8 @@ import org.jetbrains.kotlin.ir.types.IrType
|
|||||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isInline
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||||
|
|
||||||
class Fir2IrLazyConstructor(
|
class Fir2IrLazyConstructor(
|
||||||
components: Fir2IrComponents,
|
components: Fir2IrComponents,
|
||||||
@@ -100,16 +100,25 @@ class Fir2IrLazyConstructor(
|
|||||||
error("Mutating Fir2Ir lazy elements is not possible")
|
error("Mutating Fir2Ir lazy elements is not possible")
|
||||||
}
|
}
|
||||||
|
|
||||||
override var contextReceiverParametersCount: Int = 0
|
override var contextReceiverParametersCount: Int = fir.contextReceivers.size
|
||||||
|
|
||||||
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
|
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
|
||||||
declarationStorage.enterScope(this)
|
declarationStorage.enterScope(this)
|
||||||
fir.valueParameters.mapIndexed { index, valueParameter ->
|
|
||||||
declarationStorage.createIrParameter(
|
buildList {
|
||||||
valueParameter, index,
|
declarationStorage.addContextReceiverParametersTo(
|
||||||
useStubForDefaultValueStub = (parent as? IrClass)?.name != Name.identifier("Enum")
|
fir.contextReceivers,
|
||||||
).apply {
|
this@Fir2IrLazyConstructor,
|
||||||
this.parent = this@Fir2IrLazyConstructor
|
this@buildList,
|
||||||
|
)
|
||||||
|
|
||||||
|
fir.valueParameters.mapIndexedTo(this) { index, valueParameter ->
|
||||||
|
declarationStorage.createIrParameter(
|
||||||
|
valueParameter, index,
|
||||||
|
useStubForDefaultValueStub = (parent as? IrClass)?.name != Name.identifier("Enum")
|
||||||
|
).apply {
|
||||||
|
this.parent = this@Fir2IrLazyConstructor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.apply {
|
}.apply {
|
||||||
declarationStorage.leaveScope(this@Fir2IrLazyConstructor)
|
declarationStorage.leaveScope(this@Fir2IrLazyConstructor)
|
||||||
|
|||||||
+22
-14
@@ -5,10 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.lazy
|
package org.jetbrains.kotlin.fir.lazy
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.backend.ConversionTypeContext
|
import org.jetbrains.kotlin.fir.backend.*
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
|
||||||
import org.jetbrains.kotlin.fir.backend.generateOverriddenAccessorSymbols
|
|
||||||
import org.jetbrains.kotlin.fir.backend.toIrType
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||||
@@ -76,21 +73,32 @@ class Fir2IrLazyPropertyAccessor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override var contextReceiverParametersCount: Int = 0
|
override var contextReceiverParametersCount: Int = fir.contextReceiversForFunctionOrContainingProperty().size
|
||||||
|
|
||||||
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
|
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
|
||||||
if (!isSetter) emptyList()
|
if (!isSetter && contextReceiverParametersCount == 0) emptyList()
|
||||||
else {
|
else {
|
||||||
declarationStorage.enterScope(this)
|
declarationStorage.enterScope(this)
|
||||||
listOf(
|
|
||||||
declarationStorage.createDefaultSetterParameter(
|
buildList {
|
||||||
startOffset, endOffset,
|
declarationStorage.addContextReceiverParametersTo(
|
||||||
(firAccessor?.valueParameters?.firstOrNull()?.returnTypeRef ?: firParentProperty.returnTypeRef).toIrType(
|
fir.contextReceiversForFunctionOrContainingProperty(),
|
||||||
typeConverter, conversionTypeContext
|
this@Fir2IrLazyPropertyAccessor,
|
||||||
),
|
this@buildList,
|
||||||
parent = this@Fir2IrLazyPropertyAccessor
|
|
||||||
)
|
)
|
||||||
).apply {
|
|
||||||
|
if (isSetter) {
|
||||||
|
add(
|
||||||
|
declarationStorage.createDefaultSetterParameter(
|
||||||
|
startOffset, endOffset,
|
||||||
|
(firAccessor?.valueParameters?.firstOrNull()?.returnTypeRef ?: firParentProperty.returnTypeRef).toIrType(
|
||||||
|
typeConverter, conversionTypeContext
|
||||||
|
),
|
||||||
|
parent = this@Fir2IrLazyPropertyAccessor
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.apply {
|
||||||
declarationStorage.leaveScope(this@Fir2IrLazyPropertyAccessor)
|
declarationStorage.leaveScope(this@Fir2IrLazyPropertyAccessor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.lazy
|
package org.jetbrains.kotlin.fir.lazy
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||||
|
import org.jetbrains.kotlin.fir.backend.contextReceiversForFunctionOrContainingProperty
|
||||||
import org.jetbrains.kotlin.fir.backend.generateOverriddenFunctionSymbols
|
import org.jetbrains.kotlin.fir.backend.generateOverriddenFunctionSymbols
|
||||||
import org.jetbrains.kotlin.fir.backend.toIrType
|
import org.jetbrains.kotlin.fir.backend.toIrType
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
@@ -64,15 +65,24 @@ class Fir2IrLazySimpleFunction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override var contextReceiverParametersCount: Int = 0
|
override var contextReceiverParametersCount: Int = fir.contextReceiversForFunctionOrContainingProperty().size
|
||||||
|
|
||||||
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
|
override var valueParameters: List<IrValueParameter> by lazyVar(lock) {
|
||||||
declarationStorage.enterScope(this)
|
declarationStorage.enterScope(this)
|
||||||
fir.valueParameters.mapIndexed { index, valueParameter ->
|
|
||||||
declarationStorage.createIrParameter(
|
buildList {
|
||||||
valueParameter, index, skipDefaultParameter = isFakeOverride
|
declarationStorage.addContextReceiverParametersTo(
|
||||||
).apply {
|
fir.contextReceiversForFunctionOrContainingProperty(),
|
||||||
this.parent = this@Fir2IrLazySimpleFunction
|
this@Fir2IrLazySimpleFunction,
|
||||||
|
this@buildList,
|
||||||
|
)
|
||||||
|
|
||||||
|
fir.valueParameters.mapIndexedTo(this) { index, valueParameter ->
|
||||||
|
declarationStorage.createIrParameter(
|
||||||
|
valueParameter, index, skipDefaultParameter = isFakeOverride
|
||||||
|
).apply {
|
||||||
|
this.parent = this@Fir2IrLazySimpleFunction
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.apply {
|
}.apply {
|
||||||
declarationStorage.leaveScope(this@Fir2IrLazySimpleFunction)
|
declarationStorage.leaveScope(this@Fir2IrLazySimpleFunction)
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ sealed class ImplicitReceiverValue<S : FirBasedSymbol<*>>(
|
|||||||
protected val useSiteSession: FirSession,
|
protected val useSiteSession: FirSession,
|
||||||
protected val scopeSession: ScopeSession,
|
protected val scopeSession: ScopeSession,
|
||||||
private val mutable: Boolean,
|
private val mutable: Boolean,
|
||||||
|
val contextReceiverNumber: Int = -1,
|
||||||
) : ReceiverValue {
|
) : ReceiverValue {
|
||||||
final override var type: ConeKotlinType = type
|
final override var type: ConeKotlinType = type
|
||||||
private set
|
private set
|
||||||
@@ -92,7 +93,7 @@ sealed class ImplicitReceiverValue<S : FirBasedSymbol<*>>(
|
|||||||
|
|
||||||
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope? = implicitScope
|
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope? = implicitScope
|
||||||
|
|
||||||
private val originalReceiverExpression: FirThisReceiverExpression = receiverExpression(boundSymbol, type)
|
private val originalReceiverExpression: FirThisReceiverExpression = receiverExpression(boundSymbol, type, contextReceiverNumber)
|
||||||
final override var receiverExpression: FirExpression = originalReceiverExpression
|
final override var receiverExpression: FirExpression = originalReceiverExpression
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@@ -119,13 +120,18 @@ sealed class ImplicitReceiverValue<S : FirBasedSymbol<*>>(
|
|||||||
abstract fun createSnapshot(): ImplicitReceiverValue<S>
|
abstract fun createSnapshot(): ImplicitReceiverValue<S>
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun receiverExpression(symbol: FirBasedSymbol<*>, type: ConeKotlinType): FirThisReceiverExpression =
|
private fun receiverExpression(
|
||||||
|
symbol: FirBasedSymbol<*>,
|
||||||
|
type: ConeKotlinType,
|
||||||
|
contextReceiverNumber: Int,
|
||||||
|
): FirThisReceiverExpression =
|
||||||
buildThisReceiverExpression {
|
buildThisReceiverExpression {
|
||||||
// NB: we can't use `symbol.fir.source` as the source of `this` receiver. For instance, if this is an implicit receiver for a class,
|
// NB: we can't use `symbol.fir.source` as the source of `this` receiver. For instance, if this is an implicit receiver for a class,
|
||||||
// the entire class itself will be set as a source. If combined with an implicit type operation, a certain assertion, like null
|
// the entire class itself will be set as a source. If combined with an implicit type operation, a certain assertion, like null
|
||||||
// check assertion, will retrieve source as an assertion message, which is literally the entire class (!).
|
// check assertion, will retrieve source as an assertion message, which is literally the entire class (!).
|
||||||
calleeReference = buildImplicitThisReference {
|
calleeReference = buildImplicitThisReference {
|
||||||
boundSymbol = symbol
|
boundSymbol = symbol
|
||||||
|
this.contextReceiverNumber = contextReceiverNumber
|
||||||
}
|
}
|
||||||
typeRef = buildResolvedTypeRef {
|
typeRef = buildResolvedTypeRef {
|
||||||
this.type = type
|
this.type = type
|
||||||
@@ -193,8 +199,9 @@ sealed class ContextReceiverValue<S : FirBasedSymbol<*>>(
|
|||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
mutable: Boolean = true,
|
mutable: Boolean = true,
|
||||||
|
contextReceiverNumber: Int,
|
||||||
) : ImplicitReceiverValue<S>(
|
) : ImplicitReceiverValue<S>(
|
||||||
boundSymbol, type, useSiteSession, scopeSession, mutable
|
boundSymbol, type, useSiteSession, scopeSession, mutable, contextReceiverNumber,
|
||||||
) {
|
) {
|
||||||
abstract override fun createSnapshot(): ContextReceiverValue<S>
|
abstract override fun createSnapshot(): ContextReceiverValue<S>
|
||||||
}
|
}
|
||||||
@@ -206,11 +213,12 @@ class ContextReceiverValueForCallable(
|
|||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
mutable: Boolean = true,
|
mutable: Boolean = true,
|
||||||
|
contextReceiverNumber: Int,
|
||||||
) : ContextReceiverValue<FirCallableSymbol<*>>(
|
) : ContextReceiverValue<FirCallableSymbol<*>>(
|
||||||
boundSymbol, type, labelName, useSiteSession, scopeSession, mutable
|
boundSymbol, type, labelName, useSiteSession, scopeSession, mutable, contextReceiverNumber
|
||||||
) {
|
) {
|
||||||
override fun createSnapshot(): ContextReceiverValue<FirCallableSymbol<*>> =
|
override fun createSnapshot(): ContextReceiverValue<FirCallableSymbol<*>> =
|
||||||
ContextReceiverValueForCallable(boundSymbol, type, labelName, useSiteSession, scopeSession, mutable = false)
|
ContextReceiverValueForCallable(boundSymbol, type, labelName, useSiteSession, scopeSession, mutable = false, contextReceiverNumber)
|
||||||
|
|
||||||
override val isContextReceiver: Boolean
|
override val isContextReceiver: Boolean
|
||||||
get() = true
|
get() = true
|
||||||
@@ -223,11 +231,12 @@ class ContextReceiverValueForClass(
|
|||||||
useSiteSession: FirSession,
|
useSiteSession: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
mutable: Boolean = true,
|
mutable: Boolean = true,
|
||||||
|
contextReceiverNumber: Int,
|
||||||
) : ContextReceiverValue<FirClassSymbol<*>>(
|
) : ContextReceiverValue<FirClassSymbol<*>>(
|
||||||
boundSymbol, type, labelName, useSiteSession, scopeSession, mutable
|
boundSymbol, type, labelName, useSiteSession, scopeSession, mutable, contextReceiverNumber
|
||||||
) {
|
) {
|
||||||
override fun createSnapshot(): ContextReceiverValue<FirClassSymbol<*>> =
|
override fun createSnapshot(): ContextReceiverValue<FirClassSymbol<*>> =
|
||||||
ContextReceiverValueForClass(boundSymbol, type, labelName, useSiteSession, scopeSession, mutable = false)
|
ContextReceiverValueForClass(boundSymbol, type, labelName, useSiteSession, scopeSession, mutable = false, contextReceiverNumber)
|
||||||
|
|
||||||
override val isContextReceiver: Boolean
|
override val isContextReceiver: Boolean
|
||||||
get() = true
|
get() = true
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ class FirCallResolver(
|
|||||||
dispatchReceiver = candidate.dispatchReceiverExpression()
|
dispatchReceiver = candidate.dispatchReceiverExpression()
|
||||||
extensionReceiver = candidate.chosenExtensionReceiverExpression()
|
extensionReceiver = candidate.chosenExtensionReceiverExpression()
|
||||||
argumentList = candidate.callInfo.argumentList
|
argumentList = candidate.callInfo.argumentList
|
||||||
|
contextReceiverArguments.addAll(candidate.contextReceiverArguments())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resultExpression
|
resultExpression
|
||||||
@@ -382,6 +383,7 @@ class FirCallResolver(
|
|||||||
val candidate = reducedCandidates.single()
|
val candidate = reducedCandidates.single()
|
||||||
resultExpression = resultExpression.transformDispatchReceiver(StoreReceiver, candidate.dispatchReceiverExpression())
|
resultExpression = resultExpression.transformDispatchReceiver(StoreReceiver, candidate.dispatchReceiverExpression())
|
||||||
resultExpression = resultExpression.transformExtensionReceiver(StoreReceiver, candidate.chosenExtensionReceiverExpression())
|
resultExpression = resultExpression.transformExtensionReceiver(StoreReceiver, candidate.chosenExtensionReceiverExpression())
|
||||||
|
resultExpression.replaceContextReceiverArguments(candidate.contextReceiverArguments())
|
||||||
}
|
}
|
||||||
if (resultExpression is FirExpression) transformer.storeTypeFromCallee(resultExpression)
|
if (resultExpression is FirExpression) transformer.storeTypeFromCallee(resultExpression)
|
||||||
return resultExpression
|
return resultExpression
|
||||||
|
|||||||
@@ -104,6 +104,9 @@ class Candidate(
|
|||||||
fun chosenExtensionReceiverExpression(): FirExpression =
|
fun chosenExtensionReceiverExpression(): FirExpression =
|
||||||
chosenExtensionReceiverValue?.receiverExpression?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression
|
chosenExtensionReceiverValue?.receiverExpression?.takeIf { it !is FirExpressionStub } ?: FirNoReceiverExpression
|
||||||
|
|
||||||
|
fun contextReceiverArguments(): List<FirExpression> =
|
||||||
|
contextReceiverArguments ?: emptyList()
|
||||||
|
|
||||||
var hasVisibleBackingField = false
|
var hasVisibleBackingField = false
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
|
|||||||
+3
@@ -147,6 +147,9 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
)
|
)
|
||||||
.transformDispatchReceiver(StoreReceiver, dispatchReceiver)
|
.transformDispatchReceiver(StoreReceiver, dispatchReceiver)
|
||||||
.transformExtensionReceiver(StoreReceiver, extensionReceiver) as T
|
.transformExtensionReceiver(StoreReceiver, extensionReceiver) as T
|
||||||
|
|
||||||
|
result.replaceContextReceiverArguments(subCandidate.contextReceiverArguments())
|
||||||
|
|
||||||
if (result is FirPropertyAccessExpressionImpl && calleeReference.candidate.currentApplicability == CandidateApplicability.PROPERTY_AS_OPERATOR) {
|
if (result is FirPropertyAccessExpressionImpl && calleeReference.candidate.currentApplicability == CandidateApplicability.PROPERTY_AS_OPERATOR) {
|
||||||
result.nonFatalDiagnostics.add(ConePropertyAsOperator(calleeReference.candidate.symbol as FirPropertySymbol))
|
result.nonFatalDiagnostics.add(ConePropertyAsOperator(calleeReference.candidate.symbol as FirPropertySymbol))
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -97,8 +97,11 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
is FirThisReference -> {
|
is FirThisReference -> {
|
||||||
val labelName = callee.labelName
|
val labelName = callee.labelName
|
||||||
val implicitReceiver = implicitReceiverStack[labelName]
|
val implicitReceiver = implicitReceiverStack[labelName]
|
||||||
implicitReceiver?.boundSymbol?.let {
|
implicitReceiver?.let {
|
||||||
callee.replaceBoundSymbol(it)
|
callee.replaceBoundSymbol(it.boundSymbol)
|
||||||
|
if (it is ContextReceiverValue) {
|
||||||
|
callee.replaceContextReceiverNumber(it.contextReceiverNumber)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val implicitType = implicitReceiver?.originalType
|
val implicitType = implicitReceiver?.originalType
|
||||||
qualifiedAccessExpression.resultType = when {
|
qualifiedAccessExpression.resultType = when {
|
||||||
@@ -598,6 +601,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
(leftArgument as? FirQualifiedAccess)?.let {
|
(leftArgument as? FirQualifiedAccess)?.let {
|
||||||
dispatchReceiver = it.dispatchReceiver
|
dispatchReceiver = it.dispatchReceiver
|
||||||
extensionReceiver = it.extensionReceiver
|
extensionReceiver = it.extensionReceiver
|
||||||
|
contextReceiverArguments.addAll(it.contextReceiverArguments)
|
||||||
}
|
}
|
||||||
annotations += assignmentOperatorStatement.annotations
|
annotations += assignmentOperatorStatement.annotations
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-4
@@ -90,9 +90,10 @@ fun SessionHolder.collectTowerDataElementsForClass(owner: FirClass, defaultType:
|
|||||||
}
|
}
|
||||||
|
|
||||||
val thisReceiver = ImplicitDispatchReceiverValue(owner.symbol, defaultType, session, scopeSession)
|
val thisReceiver = ImplicitDispatchReceiverValue(owner.symbol, defaultType, session, scopeSession)
|
||||||
val contextReceivers = (owner as? FirRegularClass)?.contextReceivers?.map {
|
val contextReceivers = (owner as? FirRegularClass)?.contextReceivers?.mapIndexed { index, receiver ->
|
||||||
ContextReceiverValueForClass(
|
ContextReceiverValueForClass(
|
||||||
owner.symbol, it.typeRef.coneType, it.labelName, session, scopeSession,
|
owner.symbol, receiver.typeRef.coneType, receiver.labelName, session, scopeSession,
|
||||||
|
contextReceiverNumber = index,
|
||||||
)
|
)
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
|
|
||||||
@@ -248,6 +249,9 @@ typealias FirLocalScopes = PersistentList<FirLocalScope>
|
|||||||
fun FirCallableDeclaration.createContextReceiverValues(
|
fun FirCallableDeclaration.createContextReceiverValues(
|
||||||
sessionHolder: SessionHolder,
|
sessionHolder: SessionHolder,
|
||||||
): List<ContextReceiverValueForCallable> =
|
): List<ContextReceiverValueForCallable> =
|
||||||
contextReceivers.map {
|
contextReceivers.mapIndexed { index, receiver ->
|
||||||
ContextReceiverValueForCallable(symbol, it.typeRef.coneType, it.labelName, sessionHolder.session, sessionHolder.scopeSession)
|
ContextReceiverValueForCallable(
|
||||||
|
symbol, receiver.typeRef.coneType, receiver.labelName, sessionHolder.session, sessionHolder.scopeSession,
|
||||||
|
contextReceiverNumber = index,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user