[FIR2IR] Unify utilities for rethrowing exceptions with attachments
This commit is contained in:
committed by
Space Team
parent
88206ca151
commit
e4537cb9f0
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.backend
|
package org.jetbrains.kotlin.fir.backend
|
||||||
|
|
||||||
|
import com.intellij.openapi.progress.ProcessCanceledException
|
||||||
import com.intellij.psi.PsiCompiledElement
|
import com.intellij.psi.PsiCompiledElement
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
@@ -45,6 +46,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
|||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
|
import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
|
||||||
@@ -67,6 +69,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
|||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
@@ -918,3 +921,16 @@ val incOrDeclSourceKindToIrStatementOrigin = mapOf(
|
|||||||
KtFakeSourceElementKind.DesugaredPrefixIncSecondGetReference to IrStatementOrigin.PREFIX_INCR,
|
KtFakeSourceElementKind.DesugaredPrefixIncSecondGetReference to IrStatementOrigin.PREFIX_INCR,
|
||||||
KtFakeSourceElementKind.DesugaredPrefixDecSecondGetReference to IrStatementOrigin.PREFIX_DECR
|
KtFakeSourceElementKind.DesugaredPrefixDecSecondGetReference to IrStatementOrigin.PREFIX_DECR
|
||||||
)
|
)
|
||||||
|
|
||||||
|
internal inline fun <R> convertCatching(element: FirElement, conversionScope: Fir2IrConversionScope? = null, block: () -> R): R {
|
||||||
|
try {
|
||||||
|
return block()
|
||||||
|
} catch (e: ProcessCanceledException) {
|
||||||
|
throw e
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
errorWithAttachment("Exception was thrown during transformation of ${element::class.java}", cause = e) {
|
||||||
|
withFirEntry("element", element)
|
||||||
|
conversionScope?.containingFileIfAny()?.let { withEntry("file", it.path) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+236
-253
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.backend.generators
|
package org.jetbrains.kotlin.fir.backend.generators
|
||||||
|
|
||||||
import com.intellij.openapi.progress.ProcessCanceledException
|
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
@@ -39,7 +38,6 @@ import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance
|
|||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
|
import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
|
||||||
import org.jetbrains.kotlin.ir.declarations.name
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
@@ -408,158 +406,149 @@ class CallAndReferenceGenerator(
|
|||||||
dynamicOperator: IrDynamicOperator? = null,
|
dynamicOperator: IrDynamicOperator? = null,
|
||||||
variableAsFunctionMode: Boolean = false,
|
variableAsFunctionMode: Boolean = false,
|
||||||
noArguments: Boolean = false,
|
noArguments: Boolean = false,
|
||||||
): IrExpression {
|
): IrExpression = convertCatching(qualifiedAccess, conversionScope) {
|
||||||
try {
|
injectGetValueCall(qualifiedAccess, qualifiedAccess.calleeReference)?.let { return it }
|
||||||
injectGetValueCall(qualifiedAccess, qualifiedAccess.calleeReference)?.let { return it }
|
|
||||||
|
|
||||||
val irType = type.toIrType()
|
val irType = type.toIrType()
|
||||||
val samConstructorCall = qualifiedAccess.tryConvertToSamConstructorCall(irType)
|
val samConstructorCall = qualifiedAccess.tryConvertToSamConstructorCall(irType)
|
||||||
if (samConstructorCall != null) return samConstructorCall
|
if (samConstructorCall != null) return samConstructorCall
|
||||||
|
|
||||||
val dispatchReceiver = qualifiedAccess.dispatchReceiver
|
val dispatchReceiver = qualifiedAccess.dispatchReceiver
|
||||||
val calleeReference = qualifiedAccess.calleeReference
|
val calleeReference = qualifiedAccess.calleeReference
|
||||||
|
|
||||||
val firSymbol = calleeReference.toResolvedBaseSymbol()
|
val firSymbol = calleeReference.toResolvedBaseSymbol()
|
||||||
val isDynamicAccess = firSymbol?.origin == FirDeclarationOrigin.DynamicScope
|
val isDynamicAccess = firSymbol?.origin == FirDeclarationOrigin.DynamicScope
|
||||||
|
|
||||||
if (isDynamicAccess) {
|
if (isDynamicAccess) {
|
||||||
return convertToIrCallForDynamic(
|
return convertToIrCallForDynamic(
|
||||||
qualifiedAccess,
|
qualifiedAccess,
|
||||||
explicitReceiverExpression,
|
explicitReceiverExpression,
|
||||||
irType,
|
irType,
|
||||||
calleeReference,
|
calleeReference,
|
||||||
firSymbol ?: error("Must have had a symbol"),
|
firSymbol ?: error("Must have had a symbol"),
|
||||||
dynamicOperator,
|
dynamicOperator,
|
||||||
noArguments,
|
noArguments,
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// We might have had a dynamic receiver, but resolved
|
|
||||||
// into a non-fake member. For example, we can
|
|
||||||
// resolve into members of `Any`.
|
|
||||||
val convertedExplicitReceiver = if (explicitReceiverExpression?.type is IrDynamicType) {
|
|
||||||
qualifiedAccess.convertWithOffsets { startOffset, endOffset ->
|
|
||||||
val callableDeclaration = firSymbol?.fir as? FirCallableDeclaration
|
|
||||||
val targetType = callableDeclaration?.dispatchReceiverType?.toIrType()
|
|
||||||
?: callableDeclaration?.receiverParameter?.typeRef?.toIrType()
|
|
||||||
?: error("Couldn't get the proper receiver")
|
|
||||||
IrTypeOperatorCallImpl(
|
|
||||||
startOffset, endOffset, targetType,
|
|
||||||
IrTypeOperator.IMPLICIT_DYNAMIC_CAST,
|
|
||||||
targetType, explicitReceiverExpression,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
explicitReceiverExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
return qualifiedAccess.convertWithOffsets { startOffset, endOffset ->
|
|
||||||
if (calleeReference is FirSuperReference) {
|
|
||||||
if (dispatchReceiver != null) {
|
|
||||||
return@convertWithOffsets visitor.convertToIrExpression(dispatchReceiver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val symbol = calleeReference.toSymbolForCall(
|
|
||||||
dispatchReceiver,
|
|
||||||
explicitReceiver = qualifiedAccess.explicitReceiver
|
|
||||||
)
|
|
||||||
when (symbol) {
|
|
||||||
is IrConstructorSymbol -> {
|
|
||||||
require(firSymbol is FirConstructorSymbol)
|
|
||||||
val constructor = firSymbol.unwrapCallRepresentative().fir as FirConstructor
|
|
||||||
val totalTypeParametersCount = constructor.typeParameters.size
|
|
||||||
val constructorTypeParametersCount = constructor.typeParameters.count { it is FirTypeParameter }
|
|
||||||
IrConstructorCallImpl(
|
|
||||||
startOffset,
|
|
||||||
endOffset,
|
|
||||||
irType,
|
|
||||||
symbol,
|
|
||||||
typeArgumentsCount = totalTypeParametersCount,
|
|
||||||
valueArgumentsCount = firSymbol.valueParametersSize(),
|
|
||||||
constructorTypeArgumentsCount = constructorTypeParametersCount,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is IrSimpleFunctionSymbol -> {
|
|
||||||
require(firSymbol is FirCallableSymbol<*>) { "Illegal symbol: ${firSymbol!!::class}" }
|
|
||||||
IrCallImpl(
|
|
||||||
startOffset, endOffset, irType, symbol,
|
|
||||||
typeArgumentsCount = firSymbol.typeParameterSymbols.size,
|
|
||||||
valueArgumentsCount = firSymbol.valueParametersSize(),
|
|
||||||
origin = calleeReference.statementOrigin(),
|
|
||||||
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is IrLocalDelegatedPropertySymbol -> {
|
|
||||||
IrCallImpl(
|
|
||||||
startOffset, endOffset, irType,
|
|
||||||
declarationStorage.findGetterOfProperty(symbol),
|
|
||||||
typeArgumentsCount = calleeReference.toResolvedCallableSymbol()!!.fir.typeParameters.size,
|
|
||||||
valueArgumentsCount = 0,
|
|
||||||
origin = IrStatementOrigin.GET_LOCAL_PROPERTY,
|
|
||||||
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is IrPropertySymbol -> {
|
|
||||||
val property = calleeReference.toResolvedPropertySymbol()!!.fir
|
|
||||||
val getterSymbol = declarationStorage.findGetterOfProperty(symbol)
|
|
||||||
val backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol)
|
|
||||||
when {
|
|
||||||
getterSymbol != null -> {
|
|
||||||
IrCallImpl(
|
|
||||||
startOffset, endOffset, irType,
|
|
||||||
getterSymbol,
|
|
||||||
typeArgumentsCount = property.typeParameters.size,
|
|
||||||
valueArgumentsCount = property.contextReceivers.size,
|
|
||||||
origin = incOrDeclSourceKindToIrStatementOrigin[qualifiedAccess.source?.kind]
|
|
||||||
?: IrStatementOrigin.GET_PROPERTY,
|
|
||||||
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
backingFieldSymbol != null -> IrGetFieldImpl(
|
|
||||||
startOffset, endOffset, backingFieldSymbol, irType,
|
|
||||||
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> IrErrorCallExpressionImpl(
|
|
||||||
startOffset, endOffset, irType,
|
|
||||||
description = "No getter or backing field found for ${calleeReference.render()}"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is IrFieldSymbol -> IrGetFieldImpl(
|
|
||||||
startOffset, endOffset, symbol, irType,
|
|
||||||
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
|
||||||
)
|
|
||||||
|
|
||||||
is IrValueSymbol -> {
|
|
||||||
val variable = calleeReference.toResolvedVariableSymbol()!!.fir
|
|
||||||
IrGetValueImpl(
|
|
||||||
startOffset, endOffset,
|
|
||||||
// Note: there is a case with componentN function when IR type of variable differs from FIR type
|
|
||||||
variable.irTypeForPotentiallyComponentCall(predefinedType = irType),
|
|
||||||
symbol,
|
|
||||||
origin = if (variableAsFunctionMode) IrStatementOrigin.VARIABLE_AS_FUNCTION
|
|
||||||
else incOrDeclSourceKindToIrStatementOrigin[qualifiedAccess.source?.kind] ?: calleeReference.statementOrigin()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is IrEnumEntrySymbol -> IrGetEnumValueImpl(startOffset, endOffset, irType, symbol)
|
|
||||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference, irType)
|
|
||||||
}
|
|
||||||
}.applyTypeArguments(qualifiedAccess).applyReceivers(qualifiedAccess, convertedExplicitReceiver)
|
|
||||||
.applyCallArguments(qualifiedAccess)
|
|
||||||
} catch (e: ProcessCanceledException) {
|
|
||||||
throw e
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
throw IllegalStateException(
|
|
||||||
"Error while translating ${qualifiedAccess.render()} " +
|
|
||||||
"from file ${conversionScope.containingFileIfAny()?.name ?: "???"} to BE IR", e
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We might have had a dynamic receiver, but resolved
|
||||||
|
// into a non-fake member. For example, we can
|
||||||
|
// resolve into members of `Any`.
|
||||||
|
val convertedExplicitReceiver = if (explicitReceiverExpression?.type is IrDynamicType) {
|
||||||
|
qualifiedAccess.convertWithOffsets { startOffset, endOffset ->
|
||||||
|
val callableDeclaration = firSymbol?.fir as? FirCallableDeclaration
|
||||||
|
val targetType = callableDeclaration?.dispatchReceiverType?.toIrType()
|
||||||
|
?: callableDeclaration?.receiverParameter?.typeRef?.toIrType()
|
||||||
|
?: error("Couldn't get the proper receiver")
|
||||||
|
IrTypeOperatorCallImpl(
|
||||||
|
startOffset, endOffset, targetType,
|
||||||
|
IrTypeOperator.IMPLICIT_DYNAMIC_CAST,
|
||||||
|
targetType, explicitReceiverExpression,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
explicitReceiverExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
return qualifiedAccess.convertWithOffsets { startOffset, endOffset ->
|
||||||
|
if (calleeReference is FirSuperReference) {
|
||||||
|
if (dispatchReceiver != null) {
|
||||||
|
return@convertWithOffsets visitor.convertToIrExpression(dispatchReceiver)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val symbol = calleeReference.toSymbolForCall(
|
||||||
|
dispatchReceiver,
|
||||||
|
explicitReceiver = qualifiedAccess.explicitReceiver
|
||||||
|
)
|
||||||
|
when (symbol) {
|
||||||
|
is IrConstructorSymbol -> {
|
||||||
|
require(firSymbol is FirConstructorSymbol)
|
||||||
|
val constructor = firSymbol.unwrapCallRepresentative().fir as FirConstructor
|
||||||
|
val totalTypeParametersCount = constructor.typeParameters.size
|
||||||
|
val constructorTypeParametersCount = constructor.typeParameters.count { it is FirTypeParameter }
|
||||||
|
IrConstructorCallImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
irType,
|
||||||
|
symbol,
|
||||||
|
typeArgumentsCount = totalTypeParametersCount,
|
||||||
|
valueArgumentsCount = firSymbol.valueParametersSize(),
|
||||||
|
constructorTypeArgumentsCount = constructorTypeParametersCount,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is IrSimpleFunctionSymbol -> {
|
||||||
|
require(firSymbol is FirCallableSymbol<*>) { "Illegal symbol: ${firSymbol!!::class}" }
|
||||||
|
IrCallImpl(
|
||||||
|
startOffset, endOffset, irType, symbol,
|
||||||
|
typeArgumentsCount = firSymbol.typeParameterSymbols.size,
|
||||||
|
valueArgumentsCount = firSymbol.valueParametersSize(),
|
||||||
|
origin = calleeReference.statementOrigin(),
|
||||||
|
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is IrLocalDelegatedPropertySymbol -> {
|
||||||
|
IrCallImpl(
|
||||||
|
startOffset, endOffset, irType,
|
||||||
|
declarationStorage.findGetterOfProperty(symbol),
|
||||||
|
typeArgumentsCount = calleeReference.toResolvedCallableSymbol()!!.fir.typeParameters.size,
|
||||||
|
valueArgumentsCount = 0,
|
||||||
|
origin = IrStatementOrigin.GET_LOCAL_PROPERTY,
|
||||||
|
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is IrPropertySymbol -> {
|
||||||
|
val property = calleeReference.toResolvedPropertySymbol()!!.fir
|
||||||
|
val getterSymbol = declarationStorage.findGetterOfProperty(symbol)
|
||||||
|
val backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol)
|
||||||
|
when {
|
||||||
|
getterSymbol != null -> {
|
||||||
|
IrCallImpl(
|
||||||
|
startOffset, endOffset, irType,
|
||||||
|
getterSymbol,
|
||||||
|
typeArgumentsCount = property.typeParameters.size,
|
||||||
|
valueArgumentsCount = property.contextReceivers.size,
|
||||||
|
origin = incOrDeclSourceKindToIrStatementOrigin[qualifiedAccess.source?.kind]
|
||||||
|
?: IrStatementOrigin.GET_PROPERTY,
|
||||||
|
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
backingFieldSymbol != null -> IrGetFieldImpl(
|
||||||
|
startOffset, endOffset, backingFieldSymbol, irType,
|
||||||
|
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
||||||
|
)
|
||||||
|
|
||||||
|
else -> IrErrorCallExpressionImpl(
|
||||||
|
startOffset, endOffset, irType,
|
||||||
|
description = "No getter or backing field found for ${calleeReference.render()}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is IrFieldSymbol -> IrGetFieldImpl(
|
||||||
|
startOffset, endOffset, symbol, irType,
|
||||||
|
superQualifierSymbol = dispatchReceiver?.superQualifierSymbol()
|
||||||
|
)
|
||||||
|
|
||||||
|
is IrValueSymbol -> {
|
||||||
|
val variable = calleeReference.toResolvedVariableSymbol()!!.fir
|
||||||
|
IrGetValueImpl(
|
||||||
|
startOffset, endOffset,
|
||||||
|
// Note: there is a case with componentN function when IR type of variable differs from FIR type
|
||||||
|
variable.irTypeForPotentiallyComponentCall(predefinedType = irType),
|
||||||
|
symbol,
|
||||||
|
origin = if (variableAsFunctionMode) IrStatementOrigin.VARIABLE_AS_FUNCTION
|
||||||
|
else incOrDeclSourceKindToIrStatementOrigin[qualifiedAccess.source?.kind] ?: calleeReference.statementOrigin()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is IrEnumEntrySymbol -> IrGetEnumValueImpl(startOffset, endOffset, irType, symbol)
|
||||||
|
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference, irType)
|
||||||
|
}
|
||||||
|
}.applyTypeArguments(qualifiedAccess).applyReceivers(qualifiedAccess, convertedExplicitReceiver)
|
||||||
|
.applyCallArguments(qualifiedAccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirCallableSymbol<*>.valueParametersSize(): Int {
|
private fun FirCallableSymbol<*>.valueParametersSize(): Int {
|
||||||
@@ -626,116 +615,110 @@ class CallAndReferenceGenerator(
|
|||||||
|
|
||||||
internal fun findInjectedValue(calleeReference: FirReference) = extensions.findInjectedValue(calleeReference, conversionScope)
|
internal fun findInjectedValue(calleeReference: FirReference) = extensions.findInjectedValue(calleeReference, conversionScope)
|
||||||
|
|
||||||
fun convertToIrSetCall(variableAssignment: FirVariableAssignment, explicitReceiverExpression: IrExpression?): IrExpression {
|
fun convertToIrSetCall(
|
||||||
try {
|
variableAssignment: FirVariableAssignment,
|
||||||
val type = irBuiltIns.unitType
|
explicitReceiverExpression: IrExpression?,
|
||||||
val calleeReference = variableAssignment.calleeReference ?: error("Reference not resolvable")
|
): IrExpression = convertCatching(variableAssignment, conversionScope) {
|
||||||
val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue)
|
val type = irBuiltIns.unitType
|
||||||
|
val calleeReference = variableAssignment.calleeReference ?: error("Reference not resolvable")
|
||||||
|
val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue)
|
||||||
|
|
||||||
injectSetValueCall(variableAssignment, calleeReference, assignedValue)?.let { return it }
|
injectSetValueCall(variableAssignment, calleeReference, assignedValue)?.let { return it }
|
||||||
|
|
||||||
val firSymbol = calleeReference.toResolvedBaseSymbol()
|
val firSymbol = calleeReference.toResolvedBaseSymbol()
|
||||||
val isDynamicAccess = firSymbol?.origin == FirDeclarationOrigin.DynamicScope
|
val isDynamicAccess = firSymbol?.origin == FirDeclarationOrigin.DynamicScope
|
||||||
|
|
||||||
if (isDynamicAccess) {
|
if (isDynamicAccess) {
|
||||||
return convertToIrSetCallForDynamic(
|
return convertToIrSetCallForDynamic(
|
||||||
variableAssignment,
|
variableAssignment,
|
||||||
explicitReceiverExpression,
|
explicitReceiverExpression,
|
||||||
type,
|
type,
|
||||||
calleeReference,
|
calleeReference,
|
||||||
firSymbol ?: error("Must've had a symbol"),
|
firSymbol ?: error("Must've had a symbol"),
|
||||||
assignedValue,
|
assignedValue,
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val symbol = calleeReference.toSymbolForCall(
|
|
||||||
extractDispatchReceiverOfAssignment(variableAssignment),
|
|
||||||
explicitReceiver = variableAssignment.explicitReceiver,
|
|
||||||
preferGetter = false,
|
|
||||||
)
|
|
||||||
val origin = variableAssignment.getIrAssignmentOrigin()
|
|
||||||
|
|
||||||
val lValue = variableAssignment.unwrapLValue() ?: error("Assignment lValue unwrapped to null")
|
|
||||||
return variableAssignment.convertWithOffsets(calleeReference) { startOffset, endOffset ->
|
|
||||||
when (symbol) {
|
|
||||||
is IrFieldSymbol -> IrSetFieldImpl(startOffset, endOffset, symbol, type, origin).apply {
|
|
||||||
value = assignedValue
|
|
||||||
}
|
|
||||||
|
|
||||||
is IrLocalDelegatedPropertySymbol -> {
|
|
||||||
val firProperty = calleeReference.toResolvedPropertySymbol()!!.fir
|
|
||||||
val setterSymbol = declarationStorage.findSetterOfProperty(symbol)
|
|
||||||
when {
|
|
||||||
setterSymbol != null -> IrCallImpl(
|
|
||||||
startOffset, endOffset, type, setterSymbol,
|
|
||||||
typeArgumentsCount = firProperty.typeParameters.size,
|
|
||||||
valueArgumentsCount = 1 + firProperty.contextReceivers.size,
|
|
||||||
origin = origin,
|
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver?.superQualifierSymbol()
|
|
||||||
).apply {
|
|
||||||
putContextReceiverArguments(lValue)
|
|
||||||
putValueArgument(0, assignedValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is IrPropertySymbol -> {
|
|
||||||
val setterSymbol = declarationStorage.findSetterOfProperty(symbol)
|
|
||||||
val backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol)
|
|
||||||
val firProperty = calleeReference.toResolvedPropertySymbol()!!.fir
|
|
||||||
|
|
||||||
when {
|
|
||||||
setterSymbol != null -> IrCallImpl(
|
|
||||||
startOffset, endOffset, type, setterSymbol,
|
|
||||||
typeArgumentsCount = firProperty.typeParameters.size,
|
|
||||||
valueArgumentsCount = 1 + firProperty.contextReceivers.size,
|
|
||||||
origin = origin,
|
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver?.superQualifierSymbol()
|
|
||||||
).apply {
|
|
||||||
putValueArgument(putContextReceiverArguments(lValue), assignedValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
backingFieldSymbol != null -> IrSetFieldImpl(
|
|
||||||
startOffset, endOffset, backingFieldSymbol, type,
|
|
||||||
origin = null, // NB: to be consistent with PSI2IR, origin should be null here
|
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver?.superQualifierSymbol()
|
|
||||||
).apply {
|
|
||||||
value = assignedValue
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is IrSimpleFunctionSymbol -> {
|
|
||||||
val firFunction = calleeReference.toResolvedFunctionSymbol()?.fir
|
|
||||||
IrCallImpl(
|
|
||||||
startOffset, endOffset, type, symbol,
|
|
||||||
typeArgumentsCount = firFunction?.typeParameters?.size ?: 0,
|
|
||||||
valueArgumentsCount = 1,
|
|
||||||
origin = origin
|
|
||||||
).apply {
|
|
||||||
putValueArgument(0, assignedValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is IrVariableSymbol -> {
|
|
||||||
IrSetValueImpl(startOffset, endOffset, type, symbol, assignedValue, origin)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
|
||||||
}
|
|
||||||
}.applyTypeArguments(lValue).applyReceivers(lValue, explicitReceiverExpression)
|
|
||||||
} catch (e: ProcessCanceledException) {
|
|
||||||
throw e
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
throw IllegalStateException(
|
|
||||||
"Error while translating ${variableAssignment.render()} " +
|
|
||||||
"from file ${conversionScope.containingFileIfAny()?.name ?: "???"} to BE IR", e
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val symbol = calleeReference.toSymbolForCall(
|
||||||
|
extractDispatchReceiverOfAssignment(variableAssignment),
|
||||||
|
explicitReceiver = variableAssignment.explicitReceiver,
|
||||||
|
preferGetter = false,
|
||||||
|
)
|
||||||
|
val origin = variableAssignment.getIrAssignmentOrigin()
|
||||||
|
|
||||||
|
val lValue = variableAssignment.unwrapLValue() ?: error("Assignment lValue unwrapped to null")
|
||||||
|
return variableAssignment.convertWithOffsets(calleeReference) { startOffset, endOffset ->
|
||||||
|
when (symbol) {
|
||||||
|
is IrFieldSymbol -> IrSetFieldImpl(startOffset, endOffset, symbol, type, origin).apply {
|
||||||
|
value = assignedValue
|
||||||
|
}
|
||||||
|
|
||||||
|
is IrLocalDelegatedPropertySymbol -> {
|
||||||
|
val firProperty = calleeReference.toResolvedPropertySymbol()!!.fir
|
||||||
|
val setterSymbol = declarationStorage.findSetterOfProperty(symbol)
|
||||||
|
when {
|
||||||
|
setterSymbol != null -> IrCallImpl(
|
||||||
|
startOffset, endOffset, type, setterSymbol,
|
||||||
|
typeArgumentsCount = firProperty.typeParameters.size,
|
||||||
|
valueArgumentsCount = 1 + firProperty.contextReceivers.size,
|
||||||
|
origin = origin,
|
||||||
|
superQualifierSymbol = variableAssignment.dispatchReceiver?.superQualifierSymbol()
|
||||||
|
).apply {
|
||||||
|
putContextReceiverArguments(lValue)
|
||||||
|
putValueArgument(0, assignedValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is IrPropertySymbol -> {
|
||||||
|
val setterSymbol = declarationStorage.findSetterOfProperty(symbol)
|
||||||
|
val backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol)
|
||||||
|
val firProperty = calleeReference.toResolvedPropertySymbol()!!.fir
|
||||||
|
|
||||||
|
when {
|
||||||
|
setterSymbol != null -> IrCallImpl(
|
||||||
|
startOffset, endOffset, type, setterSymbol,
|
||||||
|
typeArgumentsCount = firProperty.typeParameters.size,
|
||||||
|
valueArgumentsCount = 1 + firProperty.contextReceivers.size,
|
||||||
|
origin = origin,
|
||||||
|
superQualifierSymbol = variableAssignment.dispatchReceiver?.superQualifierSymbol()
|
||||||
|
).apply {
|
||||||
|
putValueArgument(putContextReceiverArguments(lValue), assignedValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
backingFieldSymbol != null -> IrSetFieldImpl(
|
||||||
|
startOffset, endOffset, backingFieldSymbol, type,
|
||||||
|
origin = null, // NB: to be consistent with PSI2IR, origin should be null here
|
||||||
|
superQualifierSymbol = variableAssignment.dispatchReceiver?.superQualifierSymbol()
|
||||||
|
).apply {
|
||||||
|
value = assignedValue
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is IrSimpleFunctionSymbol -> {
|
||||||
|
val firFunction = calleeReference.toResolvedFunctionSymbol()?.fir
|
||||||
|
IrCallImpl(
|
||||||
|
startOffset, endOffset, type, symbol,
|
||||||
|
typeArgumentsCount = firFunction?.typeParameters?.size ?: 0,
|
||||||
|
valueArgumentsCount = 1,
|
||||||
|
origin = origin
|
||||||
|
).apply {
|
||||||
|
putValueArgument(0, assignedValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is IrVariableSymbol -> {
|
||||||
|
IrSetValueImpl(startOffset, endOffset, type, symbol, assignedValue, origin)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||||
|
}
|
||||||
|
}.applyTypeArguments(lValue).applyReceivers(lValue, explicitReceiverExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
-14
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
|
import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -46,7 +45,6 @@ import org.jetbrains.kotlin.ir.types.IrType
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.name.*
|
import org.jetbrains.kotlin.name.*
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
@@ -971,18 +969,6 @@ class Fir2IrCallableDeclarationsGenerator(val components: Fir2IrComponents) : Fi
|
|||||||
annotationGenerator.generate(this, firAnnotationContainer)
|
annotationGenerator.generate(this, firAnnotationContainer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <R> convertCatching(element: FirElement, block: () -> R): R {
|
|
||||||
try {
|
|
||||||
return block()
|
|
||||||
} catch (e: ProcessCanceledException) {
|
|
||||||
throw e
|
|
||||||
} catch (e: Exception) {
|
|
||||||
errorWithAttachment("Exception was thrown during transformation of ${element::class.java}", cause = e) {
|
|
||||||
withFirEntry("element", element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrDeclaration.setParent(irParent: IrDeclarationParent?) {
|
internal fun IrDeclaration.setParent(irParent: IrDeclarationParent?) {
|
||||||
|
|||||||
Reference in New Issue
Block a user