[FIR2IR] Get rid of most of usages IrSymbol.owner from CallAndReferenceGenerator
^KT-60924
This commit is contained in:
committed by
Space Team
parent
ff1c38872e
commit
d847d00d6f
@@ -814,3 +814,38 @@ fun FirExpression.asCompileTimeIrInitializer(components: Fir2IrComponents): IrEx
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: for componentN call, we have to change the type here (to the original component type) to keep compatibility with PSI2IR
|
||||||
|
* Some backend optimizations related to withIndex() probably depend on this type: index should always be Int
|
||||||
|
* See e.g. forInStringWithIndexWithExplicitlyTypedIndexVariable.kt from codegen box tests
|
||||||
|
*
|
||||||
|
* [predefinedType] is needed for case, when this function is used to convert some variable access, and
|
||||||
|
* default IR type, for it is already known
|
||||||
|
* It's not correct to always use converted [this.returnTypeRef] in one particular case:
|
||||||
|
*
|
||||||
|
* val <T> T.some: T
|
||||||
|
* get() = ...
|
||||||
|
* set(value) {
|
||||||
|
* field = value <----
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Here `value` has type `T`. In FIR there is one type parameter `T` for the whole property
|
||||||
|
* But in IR we have different type parameters for getter and setter. And by default `toIrType()` transforms
|
||||||
|
* `T` as type parameter of getter, but here we are in context of the setter. And in CallAndReferenceGenerator.convertToIrCall
|
||||||
|
* we already know that `value` should have type `T[set-some]`, so this type is provided as [predefinedType]
|
||||||
|
*
|
||||||
|
* The alternative could be to determine outside that we are in scope of setter and pass type origin, but it's
|
||||||
|
* much more complicated and messy
|
||||||
|
*/
|
||||||
|
context(Fir2IrComponents)
|
||||||
|
internal fun FirVariable.irTypeForPotentiallyComponentCall(predefinedType: IrType? = null): IrType {
|
||||||
|
val typeRef = when (val initializer = initializer) {
|
||||||
|
is FirComponentCall -> initializer.resolvedType
|
||||||
|
else -> {
|
||||||
|
if (predefinedType != null) return predefinedType
|
||||||
|
this.returnTypeRef.coneType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeRef.toIrType(typeConverter)
|
||||||
|
}
|
||||||
|
|||||||
+1
-4
@@ -1526,10 +1526,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
irParent: IrDeclarationParent,
|
irParent: IrDeclarationParent,
|
||||||
givenOrigin: IrDeclarationOrigin? = null
|
givenOrigin: IrDeclarationOrigin? = null
|
||||||
): IrVariable = convertCatching(variable) {
|
): IrVariable = convertCatching(variable) {
|
||||||
// Note: for components call, we have to change type here (to original component type) to keep compatibility with PSI2IR
|
val type = variable.irTypeForPotentiallyComponentCall()
|
||||||
// Some backend optimizations related to withIndex() probably depend on this type: index should always be Int
|
|
||||||
// See e.g. forInStringWithIndexWithExplicitlyTypedIndexVariable.kt from codegen box tests
|
|
||||||
val type = ((variable.initializer as? FirComponentCall)?.resolvedType ?: variable.returnTypeRef.coneType).toIrType()
|
|
||||||
// Some temporary variables are produced in RawFirBuilder, but we consistently use special names for them.
|
// Some temporary variables are produced in RawFirBuilder, but we consistently use special names for them.
|
||||||
val origin = when {
|
val origin = when {
|
||||||
givenOrigin != null -> givenOrigin
|
givenOrigin != null -> givenOrigin
|
||||||
|
|||||||
@@ -472,6 +472,20 @@ class IrBuiltInsOverFir(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getNonBuiltInFunctionsWithFirCounterpartByExtensionReceiver(
|
||||||
|
name: Name,
|
||||||
|
vararg packageNameSegments: String,
|
||||||
|
): Map<IrClassifierSymbol, Pair<FirNamedFunctionSymbol, IrSimpleFunctionSymbol>> {
|
||||||
|
return getFunctionsByKey(
|
||||||
|
name,
|
||||||
|
*packageNameSegments,
|
||||||
|
mapKey = { symbol ->
|
||||||
|
with(components) { symbol.fir.receiverParameter?.typeRef?.toIrType(typeConverter)?.classifierOrNull }
|
||||||
|
},
|
||||||
|
mapValue = { firSymbol, irSymbol -> firSymbol to irSymbol }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private val functionNMap = mutableMapOf<Int, IrClass>()
|
private val functionNMap = mutableMapOf<Int, IrClass>()
|
||||||
private val kFunctionNMap = mutableMapOf<Int, IrClass>()
|
private val kFunctionNMap = mutableMapOf<Int, IrClass>()
|
||||||
private val suspendFunctionNMap = mutableMapOf<Int, IrClass>()
|
private val suspendFunctionNMap = mutableMapOf<Int, IrClass>()
|
||||||
|
|||||||
+11
-8
@@ -87,10 +87,12 @@ internal class AdapterGenerator(
|
|||||||
internal fun needToGenerateAdaptedCallableReference(
|
internal fun needToGenerateAdaptedCallableReference(
|
||||||
callableReferenceAccess: FirCallableReferenceAccess,
|
callableReferenceAccess: FirCallableReferenceAccess,
|
||||||
type: IrSimpleType,
|
type: IrSimpleType,
|
||||||
function: IrFunction
|
function: FirFunction
|
||||||
): Boolean =
|
): Boolean {
|
||||||
needSuspendConversion(type, function) || needCoercionToUnit(type, function) ||
|
return needSuspendConversion(type, function) ||
|
||||||
|
needCoercionToUnit(type, function) ||
|
||||||
hasVarargOrDefaultArguments(callableReferenceAccess)
|
hasVarargOrDefaultArguments(callableReferenceAccess)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For example,
|
* For example,
|
||||||
@@ -100,8 +102,9 @@ internal class AdapterGenerator(
|
|||||||
*
|
*
|
||||||
* At the use site, instead of referenced, we can put the suspend lambda as an adapter.
|
* At the use site, instead of referenced, we can put the suspend lambda as an adapter.
|
||||||
*/
|
*/
|
||||||
private fun needSuspendConversion(type: IrSimpleType, function: IrFunction): Boolean =
|
private fun needSuspendConversion(type: IrSimpleType, function: FirFunction): Boolean {
|
||||||
type.isSuspendFunction() && !function.isSuspend
|
return type.isSuspendFunction() && !function.isSuspend
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For example,
|
* For example,
|
||||||
@@ -111,12 +114,12 @@ internal class AdapterGenerator(
|
|||||||
*
|
*
|
||||||
* At the use site, instead of referenced, we can put the adapter: { ... -> referenced(...) }
|
* At the use site, instead of referenced, we can put the adapter: { ... -> referenced(...) }
|
||||||
*/
|
*/
|
||||||
private fun needCoercionToUnit(type: IrSimpleType, function: IrFunction): Boolean {
|
private fun needCoercionToUnit(type: IrSimpleType, function: FirFunction): Boolean {
|
||||||
val expectedReturnType = type.arguments.last().typeOrNull
|
val expectedReturnType = type.arguments.last().typeOrNull
|
||||||
val actualReturnType = function.returnType
|
val actualReturnType = function.returnTypeRef.coneType
|
||||||
return expectedReturnType?.isUnit() == true &&
|
return expectedReturnType?.isUnit() == true &&
|
||||||
// In case of an external function whose return type is a type parameter, e.g., operator fun <T, R> invoke(T): R
|
// In case of an external function whose return type is a type parameter, e.g., operator fun <T, R> invoke(T): R
|
||||||
!actualReturnType.isUnit() && !actualReturnType.isTypeParameter()
|
!actualReturnType.isUnit && actualReturnType.toSymbol(components.session) !is FirTypeParameterSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+133
-119
@@ -9,18 +9,18 @@ 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
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
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.isInterface
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isMethodOfAny
|
import org.jetbrains.kotlin.fir.declarations.utils.isMethodOfAny
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
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.*
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.render
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
|
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.getExpectedType
|
import org.jetbrains.kotlin.fir.resolve.calls.getExpectedType
|
||||||
@@ -44,12 +44,11 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.dump
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
import org.jetbrains.kotlin.ir.util.isFunctionTypeOrSubtype
|
|
||||||
import org.jetbrains.kotlin.ir.util.isInterface
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator.commonSuperType
|
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator.commonSuperType
|
||||||
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.addToStdlib.runIf
|
||||||
|
|
||||||
class CallAndReferenceGenerator(
|
class CallAndReferenceGenerator(
|
||||||
private val components: Fir2IrComponents,
|
private val components: Fir2IrComponents,
|
||||||
@@ -65,7 +64,6 @@ class CallAndReferenceGenerator(
|
|||||||
private fun ConeKotlinType.toIrType(): IrType =
|
private fun ConeKotlinType.toIrType(): IrType =
|
||||||
with(typeConverter) { toIrType(conversionScope.defaultConversionTypeOrigin()) }
|
with(typeConverter) { toIrType(conversionScope.defaultConversionTypeOrigin()) }
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
|
||||||
fun convertToIrCallableReference(
|
fun convertToIrCallableReference(
|
||||||
callableReferenceAccess: FirCallableReferenceAccess,
|
callableReferenceAccess: FirCallableReferenceAccess,
|
||||||
explicitReceiverExpression: IrExpression?,
|
explicitReceiverExpression: IrExpression?,
|
||||||
@@ -101,20 +99,19 @@ class CallAndReferenceGenerator(
|
|||||||
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
||||||
when (symbol) {
|
when (symbol) {
|
||||||
is IrPropertySymbol -> {
|
is IrPropertySymbol -> {
|
||||||
val referencedProperty = symbol.owner
|
val referencedPropertyGetterSymbol = declarationStorage.findGetterOfProperty(symbol)
|
||||||
val referencedPropertyGetter = referencedProperty.getter
|
val referencedPropertySetterSymbol = runIf(callableReferenceAccess.resolvedType.isKMutableProperty(session)) {
|
||||||
val referencedPropertySetterSymbol =
|
declarationStorage.findSetterOfProperty(symbol)
|
||||||
if (callableReferenceAccess.resolvedType.isKMutableProperty(session)) referencedProperty.setter?.symbol
|
}
|
||||||
else null
|
|
||||||
val backingFieldSymbol = when {
|
val backingFieldSymbol = when {
|
||||||
referencedPropertyGetter != null -> null
|
referencedPropertyGetterSymbol != null -> null
|
||||||
else -> referencedProperty.backingField?.symbol
|
else -> declarationStorage.findBackingFieldOfProperty(symbol)
|
||||||
}
|
}
|
||||||
IrPropertyReferenceImpl(
|
IrPropertyReferenceImpl(
|
||||||
startOffset, endOffset, type, symbol,
|
startOffset, endOffset, type, symbol,
|
||||||
typeArgumentsCount = referencedPropertyGetter?.typeParameters?.size ?: 0,
|
typeArgumentsCount = callableReferenceAccess.toResolvedCallableSymbol()?.fir?.typeParameters?.size ?: 0,
|
||||||
field = backingFieldSymbol,
|
field = backingFieldSymbol,
|
||||||
getter = referencedPropertyGetter?.symbol,
|
getter = referencedPropertyGetterSymbol,
|
||||||
setter = referencedPropertySetterSymbol,
|
setter = referencedPropertySetterSymbol,
|
||||||
origin = origin
|
origin = origin
|
||||||
).applyTypeArguments(callableReferenceAccess).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
|
).applyTypeArguments(callableReferenceAccess).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
|
||||||
@@ -123,40 +120,43 @@ class CallAndReferenceGenerator(
|
|||||||
is IrLocalDelegatedPropertySymbol -> {
|
is IrLocalDelegatedPropertySymbol -> {
|
||||||
IrLocalDelegatedPropertyReferenceImpl(
|
IrLocalDelegatedPropertyReferenceImpl(
|
||||||
startOffset, endOffset, type, symbol,
|
startOffset, endOffset, type, symbol,
|
||||||
delegate = symbol.owner.delegate.symbol,
|
delegate = declarationStorage.findDelegateVariableOfProperty(symbol),
|
||||||
getter = symbol.owner.getter.symbol,
|
getter = declarationStorage.findGetterOfProperty(symbol),
|
||||||
setter = symbol.owner.setter?.symbol,
|
setter = declarationStorage.findSetterOfProperty(symbol),
|
||||||
origin = origin
|
origin = origin
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is IrFieldSymbol -> {
|
is IrFieldSymbol -> {
|
||||||
val referencedField = symbol.owner
|
val field = (callableSymbol as FirFieldSymbol).fir
|
||||||
val propertySymbol = referencedField.correspondingPropertySymbol
|
val propertySymbol = declarationStorage.findPropertyForBackingField(symbol)
|
||||||
?: run {
|
?: run {
|
||||||
// In case of [IrField] without the corresponding property, we've created it directly from [FirField].
|
// In case of [IrField] without the corresponding property, we've created it directly from [FirField].
|
||||||
// Since it's used as a field reference, we need a bogus property as a placeholder.
|
// Since it's used as a field reference, we need a bogus property as a placeholder.
|
||||||
val firSymbol =
|
val firSymbol =
|
||||||
(callableReferenceAccess.calleeReference as FirResolvedNamedReference).resolvedSymbol as FirFieldSymbol
|
(callableReferenceAccess.calleeReference as FirResolvedNamedReference).resolvedSymbol as FirFieldSymbol
|
||||||
declarationStorage.getOrCreateIrPropertyByPureField(firSymbol.fir, referencedField.parent).symbol
|
@OptIn(IrSymbolInternals::class)
|
||||||
|
declarationStorage.getOrCreateIrPropertyByPureField(firSymbol.fir, symbol.owner.parent).symbol
|
||||||
}
|
}
|
||||||
IrPropertyReferenceImpl(
|
IrPropertyReferenceImpl(
|
||||||
startOffset, endOffset, type,
|
startOffset, endOffset, type,
|
||||||
propertySymbol,
|
propertySymbol,
|
||||||
typeArgumentsCount = 0,
|
typeArgumentsCount = 0,
|
||||||
field = symbol,
|
field = symbol,
|
||||||
getter = if (referencedField.isStatic) null else propertySymbol.owner.getter?.symbol,
|
getter = runIf(!field.isStatic) { declarationStorage.findGetterOfProperty(propertySymbol) },
|
||||||
setter = if (referencedField.isStatic) null else propertySymbol.owner.setter?.symbol,
|
setter = runIf(!field.isStatic) { declarationStorage.findSetterOfProperty(propertySymbol) },
|
||||||
origin
|
origin
|
||||||
).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
|
).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
is IrFunctionSymbol -> {
|
is IrFunctionSymbol -> {
|
||||||
assert(type.isFunctionTypeOrSubtype()) {
|
require(type is IrSimpleType)
|
||||||
"Callable reference whose symbol refers to a function should be of functional type."
|
var function = callableReferenceAccess.calleeReference.toResolvedFunctionSymbol()!!.fir
|
||||||
|
if (function is FirConstructor) {
|
||||||
|
// The number of type parameters of typealias constructor may mismatch with that number in the original constructor.
|
||||||
|
// And for IR, we need to use the original constructor as a source of truth
|
||||||
|
function = function.originalConstructorIfTypeAlias ?: function
|
||||||
}
|
}
|
||||||
type as IrSimpleType
|
|
||||||
val function = symbol.owner
|
|
||||||
if (adapterGenerator.needToGenerateAdaptedCallableReference(callableReferenceAccess, type, function)) {
|
if (adapterGenerator.needToGenerateAdaptedCallableReference(callableReferenceAccess, type, function)) {
|
||||||
// Receivers are being applied inside
|
// Receivers are being applied inside
|
||||||
with(adapterGenerator) {
|
with(adapterGenerator) {
|
||||||
@@ -165,13 +165,10 @@ class CallAndReferenceGenerator(
|
|||||||
generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, symbol, adaptedType)
|
generateAdaptedCallableReference(callableReferenceAccess, explicitReceiverExpression, symbol, adaptedType)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val klass = function.parent as? IrClass
|
|
||||||
val typeArgumentCount = function.typeParameters.size +
|
|
||||||
if (function is IrConstructor) klass?.typeParameters?.size ?: 0 else 0
|
|
||||||
IrFunctionReferenceImpl(
|
IrFunctionReferenceImpl(
|
||||||
startOffset, endOffset, type, symbol,
|
startOffset, endOffset, type, symbol,
|
||||||
typeArgumentsCount = typeArgumentCount,
|
typeArgumentsCount = function.typeParameters.size,
|
||||||
valueArgumentsCount = function.valueParameters.size,
|
valueArgumentsCount = function.valueParameters.size + function.contextReceivers.size,
|
||||||
reflectionTarget = symbol
|
reflectionTarget = symbol
|
||||||
).applyTypeArguments(callableReferenceAccess)
|
).applyTypeArguments(callableReferenceAccess)
|
||||||
.applyReceivers(callableReferenceAccess, explicitReceiverExpression)
|
.applyReceivers(callableReferenceAccess, explicitReceiverExpression)
|
||||||
@@ -363,7 +360,6 @@ class CallAndReferenceGenerator(
|
|||||||
return IrGetValueImpl(startOffset, endOffset, type, injectedValue.irParameterSymbol, origin)
|
return IrGetValueImpl(startOffset, endOffset, type, injectedValue.irParameterSymbol, origin)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
|
||||||
fun convertToIrCall(
|
fun convertToIrCall(
|
||||||
qualifiedAccess: FirQualifiedAccessExpression,
|
qualifiedAccess: FirQualifiedAccessExpression,
|
||||||
type: ConeKotlinType,
|
type: ConeKotlinType,
|
||||||
@@ -449,8 +445,9 @@ class CallAndReferenceGenerator(
|
|||||||
|
|
||||||
is IrLocalDelegatedPropertySymbol -> {
|
is IrLocalDelegatedPropertySymbol -> {
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
startOffset, endOffset, irType, symbol.owner.getter.symbol,
|
startOffset, endOffset, irType,
|
||||||
typeArgumentsCount = symbol.owner.getter.typeParameters.size,
|
declarationStorage.findGetterOfProperty(symbol),
|
||||||
|
typeArgumentsCount = calleeReference.toResolvedCallableSymbol()!!.fir.typeParameters.size,
|
||||||
valueArgumentsCount = 0,
|
valueArgumentsCount = 0,
|
||||||
origin = IrStatementOrigin.GET_LOCAL_PROPERTY,
|
origin = IrStatementOrigin.GET_LOCAL_PROPERTY,
|
||||||
superQualifierSymbol = dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = dispatchReceiver.superQualifierSymbol()
|
||||||
@@ -458,19 +455,23 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is IrPropertySymbol -> {
|
is IrPropertySymbol -> {
|
||||||
val getter = symbol.owner.getter
|
val property = calleeReference.toResolvedPropertySymbol()!!.fir
|
||||||
val backingField = symbol.owner.backingField
|
val getterSymbol = declarationStorage.findGetterOfProperty(symbol)
|
||||||
|
val backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol)
|
||||||
when {
|
when {
|
||||||
getter != null -> IrCallImpl(
|
getterSymbol != null -> {
|
||||||
startOffset, endOffset, irType, getter.symbol,
|
IrCallImpl(
|
||||||
typeArgumentsCount = getter.typeParameters.size,
|
startOffset, endOffset, irType,
|
||||||
valueArgumentsCount = getter.valueParameters.size,
|
getterSymbol,
|
||||||
origin = IrStatementOrigin.GET_PROPERTY,
|
typeArgumentsCount = property.typeParameters.size,
|
||||||
superQualifierSymbol = dispatchReceiver.superQualifierSymbol()
|
valueArgumentsCount = property.contextReceivers.size,
|
||||||
)
|
origin = IrStatementOrigin.GET_PROPERTY,
|
||||||
|
superQualifierSymbol = dispatchReceiver.superQualifierSymbol()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
backingField != null -> IrGetFieldImpl(
|
backingFieldSymbol != null -> IrGetFieldImpl(
|
||||||
startOffset, endOffset, backingField.symbol, irType,
|
startOffset, endOffset, backingFieldSymbol, irType,
|
||||||
superQualifierSymbol = dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = dispatchReceiver.superQualifierSymbol()
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -496,11 +497,12 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is IrValueSymbol -> {
|
is IrValueSymbol -> {
|
||||||
|
val variable = calleeReference.toResolvedVariableSymbol()!!.fir
|
||||||
IrGetValueImpl(
|
IrGetValueImpl(
|
||||||
// Note: sometimes we change an IR type of local variable
|
startOffset, endOffset,
|
||||||
// (see component call case: Fir2IrDeclarationStorage.createIrVariable -> val type = ...)
|
// Note: there is a case with componentN function when IR type of variable differs from FIR type
|
||||||
// That's why we should use here v the IR variable type and not FIR converted type (to prevent IR inconsistency)
|
variable.irTypeForPotentiallyComponentCall(predefinedType = irType),
|
||||||
startOffset, endOffset, symbol.owner.type, symbol,
|
symbol,
|
||||||
origin = if (variableAsFunctionMode) IrStatementOrigin.VARIABLE_AS_FUNCTION
|
origin = if (variableAsFunctionMode) IrStatementOrigin.VARIABLE_AS_FUNCTION
|
||||||
else calleeReference.statementOrigin()
|
else calleeReference.statementOrigin()
|
||||||
)
|
)
|
||||||
@@ -575,7 +577,6 @@ class CallAndReferenceGenerator(
|
|||||||
|
|
||||||
internal fun findInjectedValue(calleeReference: FirReference) = extensions.findInjectedValue(calleeReference, conversionScope)
|
internal fun findInjectedValue(calleeReference: FirReference) = extensions.findInjectedValue(calleeReference, conversionScope)
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
|
||||||
fun convertToIrSetCall(variableAssignment: FirVariableAssignment, explicitReceiverExpression: IrExpression?): IrExpression {
|
fun convertToIrSetCall(variableAssignment: FirVariableAssignment, explicitReceiverExpression: IrExpression?): IrExpression {
|
||||||
try {
|
try {
|
||||||
val type = irBuiltIns.unitType
|
val type = irBuiltIns.unitType
|
||||||
@@ -614,12 +615,13 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is IrLocalDelegatedPropertySymbol -> {
|
is IrLocalDelegatedPropertySymbol -> {
|
||||||
val setter = symbol.owner.setter
|
val firProperty = calleeReference.toResolvedPropertySymbol()!!.fir
|
||||||
|
val setterSymbol = declarationStorage.findSetterOfProperty(symbol)
|
||||||
when {
|
when {
|
||||||
setter != null -> IrCallImpl(
|
setterSymbol != null -> IrCallImpl(
|
||||||
startOffset, endOffset, type, setter.symbol,
|
startOffset, endOffset, type, setterSymbol,
|
||||||
typeArgumentsCount = setter.typeParameters.size,
|
typeArgumentsCount = firProperty.typeParameters.size,
|
||||||
valueArgumentsCount = setter.valueParameters.size,
|
valueArgumentsCount = 1 + firProperty.contextReceivers.size,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
||||||
).apply {
|
).apply {
|
||||||
@@ -632,29 +634,29 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is IrPropertySymbol -> {
|
is IrPropertySymbol -> {
|
||||||
val irProperty = symbol.owner
|
val setterSymbol = declarationStorage.findSetterOfProperty(symbol)
|
||||||
val setter = irProperty.setter
|
var backingFieldSymbol = declarationStorage.findBackingFieldOfProperty(symbol)
|
||||||
var backingField = irProperty.backingField
|
val firProperty = calleeReference.toResolvedPropertySymbol()!!.fir
|
||||||
|
|
||||||
// If we found neither a setter nor a backing field, check if we have an override (possibly fake) of a val with
|
// If we found neither a setter nor a backing field, check if we have an override (possibly fake) of a val with
|
||||||
// backing field. This can happen in a class initializer where `this` was smart-casted. See KT-57105.
|
// backing field. This can happen in a class initializer where `this` was smart-casted. See KT-57105.
|
||||||
if (setter == null && backingField == null) {
|
if (setterSymbol == null && backingFieldSymbol == null) {
|
||||||
backingField = irProperty.overriddenBackingFieldOrNull()
|
backingFieldSymbol = symbol.overriddenBackingFieldOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
setter != null -> IrCallImpl(
|
setterSymbol != null -> IrCallImpl(
|
||||||
startOffset, endOffset, type, setter.symbol,
|
startOffset, endOffset, type, setterSymbol,
|
||||||
typeArgumentsCount = setter.typeParameters.size,
|
typeArgumentsCount = firProperty.typeParameters.size,
|
||||||
valueArgumentsCount = setter.valueParameters.size,
|
valueArgumentsCount = 1 + firProperty.contextReceivers.size,
|
||||||
origin = origin,
|
origin = origin,
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
||||||
).apply {
|
).apply {
|
||||||
putValueArgument(putContextReceiverArguments(lValue), assignedValue)
|
putValueArgument(putContextReceiverArguments(lValue), assignedValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
backingField != null -> IrSetFieldImpl(
|
backingFieldSymbol != null -> IrSetFieldImpl(
|
||||||
startOffset, endOffset, backingField.symbol, type,
|
startOffset, endOffset, backingFieldSymbol, type,
|
||||||
origin = null, // NB: to be consistent with PSI2IR, origin should be null here
|
origin = null, // NB: to be consistent with PSI2IR, origin should be null here
|
||||||
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
||||||
).apply {
|
).apply {
|
||||||
@@ -666,9 +668,10 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is IrSimpleFunctionSymbol -> {
|
is IrSimpleFunctionSymbol -> {
|
||||||
|
val firFunction = calleeReference.toResolvedFunctionSymbol()?.fir
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
startOffset, endOffset, type, symbol,
|
startOffset, endOffset, type, symbol,
|
||||||
typeArgumentsCount = symbol.owner.typeParameters.size,
|
typeArgumentsCount = firFunction?.typeParameters?.size ?: 0,
|
||||||
valueArgumentsCount = 1,
|
valueArgumentsCount = 1,
|
||||||
origin = origin
|
origin = origin
|
||||||
).apply {
|
).apply {
|
||||||
@@ -694,14 +697,13 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
@OptIn(IrSymbolInternals::class)
|
||||||
private fun IrProperty.overriddenBackingFieldOrNull(): IrField? {
|
private fun IrPropertySymbol.overriddenBackingFieldOrNull(): IrFieldSymbol? {
|
||||||
return overriddenSymbols.firstNotNullOfOrNull {
|
return owner.overriddenSymbols.firstNotNullOfOrNull {
|
||||||
val owner = it.owner
|
val owner = it.owner
|
||||||
owner.backingField ?: owner.overriddenBackingFieldOrNull()
|
owner.backingField?.symbol ?: it.overriddenBackingFieldOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
|
||||||
fun convertToIrConstructorCall(annotation: FirAnnotation): IrExpression {
|
fun convertToIrConstructorCall(annotation: FirAnnotation): IrExpression {
|
||||||
val coneType = annotation.annotationTypeRef.coneTypeSafe<ConeLookupTagBasedType>()
|
val coneType = annotation.annotationTypeRef.coneTypeSafe<ConeLookupTagBasedType>()
|
||||||
?.fullyExpandedType(session) as? ConeLookupTagBasedType
|
?.fullyExpandedType(session) as? ConeLookupTagBasedType
|
||||||
@@ -714,7 +716,6 @@ class CallAndReferenceGenerator(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val irClass = symbol.owner
|
|
||||||
val firConstructorSymbol = annotation.toResolvedCallableSymbol() as? FirConstructorSymbol
|
val firConstructorSymbol = annotation.toResolvedCallableSymbol() as? FirConstructorSymbol
|
||||||
?: run {
|
?: run {
|
||||||
// Fallback for FirReferencePlaceholderForResolvedAnnotations from jar
|
// Fallback for FirReferencePlaceholderForResolvedAnnotations from jar
|
||||||
@@ -732,7 +733,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
constructorSymbol
|
constructorSymbol
|
||||||
} ?: return@convertWithOffsets IrErrorCallExpressionImpl(
|
} ?: return@convertWithOffsets IrErrorCallExpressionImpl(
|
||||||
startOffset, endOffset, type, "No annotation constructor found: ${irClass.name}"
|
startOffset, endOffset, type, "No annotation constructor found: $symbol"
|
||||||
)
|
)
|
||||||
|
|
||||||
val irConstructor = declarationStorage.getIrConstructorSymbol(firConstructorSymbol)
|
val irConstructor = declarationStorage.getIrConstructorSymbol(firConstructorSymbol)
|
||||||
@@ -837,7 +838,6 @@ class CallAndReferenceGenerator(
|
|||||||
return Triple(valueParameters, argumentMapping, substitutor)
|
return Triple(valueParameters, argumentMapping, substitutor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
|
||||||
internal fun IrExpression.applyCallArguments(
|
internal fun IrExpression.applyCallArguments(
|
||||||
statement: FirStatement?,
|
statement: FirStatement?,
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
@@ -872,7 +872,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val name = if (this is IrCallImpl) symbol.owner.name else "???"
|
val name = if (this is IrCallImpl) symbol.signature.toString() else "???"
|
||||||
IrErrorCallExpressionImpl(
|
IrErrorCallExpressionImpl(
|
||||||
startOffset, endOffset, type,
|
startOffset, endOffset, type,
|
||||||
"Cannot bind $argumentsCount arguments to $name call with $valueArgumentsCount parameters"
|
"Cannot bind $argumentsCount arguments to $name call with $valueArgumentsCount parameters"
|
||||||
@@ -1049,7 +1049,6 @@ class CallAndReferenceGenerator(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
|
||||||
private fun IrExpression.applyImplicitIntegerCoercionIfNeeded(
|
private fun IrExpression.applyImplicitIntegerCoercionIfNeeded(
|
||||||
argument: FirExpression,
|
argument: FirExpression,
|
||||||
parameter: FirValueParameter?
|
parameter: FirValueParameter?
|
||||||
@@ -1059,56 +1058,64 @@ class CallAndReferenceGenerator(
|
|||||||
if (parameter == null || !parameter.isMarkedWithImplicitIntegerCoercion) return this
|
if (parameter == null || !parameter.isMarkedWithImplicitIntegerCoercion) return this
|
||||||
if (!argument.getExpectedType(parameter).fullyExpandedType(session).isUnsignedTypeOrNullableUnsignedType) return this
|
if (!argument.getExpectedType(parameter).fullyExpandedType(session).isUnsignedTypeOrNullableUnsignedType) return this
|
||||||
|
|
||||||
fun IrExpression.applyToElement(argument: FirExpression, conversionFunction: IrSimpleFunctionSymbol): IrExpression =
|
fun IrExpression.applyToElement(
|
||||||
if (argument.isIntegerLiteralOrOperatorCall() ||
|
argument: FirExpression,
|
||||||
|
firConversionFunction: FirNamedFunctionSymbol,
|
||||||
|
irConversionFunction: IrSimpleFunctionSymbol,
|
||||||
|
): IrExpression {
|
||||||
|
return if (argument.isIntegerLiteralOrOperatorCall() ||
|
||||||
argument.calleeReference?.toResolvedCallableSymbol()?.let {
|
argument.calleeReference?.toResolvedCallableSymbol()?.let {
|
||||||
it.resolvedStatus.isConst && it.isMarkedWithImplicitIntegerCoercion
|
it.resolvedStatus.isConst && it.isMarkedWithImplicitIntegerCoercion
|
||||||
} == true
|
} == true
|
||||||
) {
|
) {
|
||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
conversionFunction.owner.returnType,
|
firConversionFunction.fir.returnTypeRef.toIrType(),
|
||||||
conversionFunction,
|
irConversionFunction,
|
||||||
typeArgumentsCount = 0,
|
typeArgumentsCount = 0,
|
||||||
valueArgumentsCount = 0
|
valueArgumentsCount = 0
|
||||||
).apply {
|
).apply {
|
||||||
extensionReceiver = this@applyToElement
|
extensionReceiver = this@applyToElement
|
||||||
}
|
}
|
||||||
} else this@applyToElement
|
|
||||||
|
|
||||||
if (parameter.isMarkedWithImplicitIntegerCoercion) {
|
|
||||||
if (this is IrVarargImpl && argument is FirVarargArgumentsExpression) {
|
|
||||||
|
|
||||||
val targetTypeFqName = varargElementType.classFqName ?: return this
|
|
||||||
val conversionFunctions = irBuiltIns.getNonBuiltInFunctionsByExtensionReceiver(
|
|
||||||
Name.identifier("to" + targetTypeFqName.shortName().asString()),
|
|
||||||
StandardNames.BUILT_INS_PACKAGE_NAME.asString()
|
|
||||||
)
|
|
||||||
if (conversionFunctions.isNotEmpty()) {
|
|
||||||
elements.forEachIndexed { i, irVarargElement ->
|
|
||||||
val targetFun = argument.arguments[i].resolvedType.toIrType().classifierOrNull?.let { conversionFunctions[it] }
|
|
||||||
if (targetFun != null && irVarargElement is IrExpression) {
|
|
||||||
elements[i] =
|
|
||||||
irVarargElement.applyToElement(argument.arguments[i], targetFun)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
} else {
|
} else {
|
||||||
val targetIrType = parameter.returnTypeRef.toIrType()
|
this@applyToElement
|
||||||
val targetTypeFqName = targetIrType.classFqName ?: return this
|
|
||||||
val conversionFunctions = irBuiltIns.getNonBuiltInFunctionsByExtensionReceiver(
|
|
||||||
Name.identifier("to" + targetTypeFqName.shortName().asString()),
|
|
||||||
StandardNames.BUILT_INS_PACKAGE_NAME.asString()
|
|
||||||
)
|
|
||||||
val sourceTypeClassifier = argument.resolvedType.toIrType().classifierOrNull ?: return this
|
|
||||||
|
|
||||||
val conversionFunction = conversionFunctions[sourceTypeClassifier] ?: return this
|
|
||||||
|
|
||||||
return this.applyToElement(argument, conversionFunction)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this
|
|
||||||
|
return when {
|
||||||
|
parameter.isMarkedWithImplicitIntegerCoercion -> when {
|
||||||
|
this is IrVarargImpl && argument is FirVarargArgumentsExpression -> {
|
||||||
|
val targetTypeFqName = varargElementType.classFqName ?: return this
|
||||||
|
val conversionFunctions = irBuiltIns.getNonBuiltInFunctionsWithFirCounterpartByExtensionReceiver(
|
||||||
|
Name.identifier("to" + targetTypeFqName.shortName().asString()),
|
||||||
|
StandardNames.BUILT_INS_PACKAGE_NAME.asString()
|
||||||
|
)
|
||||||
|
if (conversionFunctions.isNotEmpty()) {
|
||||||
|
elements.forEachIndexed { i, irVarargElement ->
|
||||||
|
if (irVarargElement !is IrExpression) return@forEachIndexed
|
||||||
|
val argumentClassifier = argument.arguments[i].resolvedType.toIrType().classifierOrNull ?: return@forEachIndexed
|
||||||
|
val (targetFirFun, targetIrFun) = conversionFunctions[argumentClassifier] ?: return@forEachIndexed
|
||||||
|
elements[i] = irVarargElement.applyToElement(argument.arguments[i], targetFirFun, targetIrFun)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val targetIrType = parameter.returnTypeRef.toIrType()
|
||||||
|
val targetTypeFqName = targetIrType.classFqName ?: return this
|
||||||
|
val conversionFunctions = irBuiltIns.getNonBuiltInFunctionsWithFirCounterpartByExtensionReceiver(
|
||||||
|
Name.identifier("to" + targetTypeFqName.shortName().asString()),
|
||||||
|
StandardNames.BUILT_INS_PACKAGE_NAME.asString()
|
||||||
|
)
|
||||||
|
val sourceTypeClassifier = argument.resolvedType.toIrType().classifierOrNull ?: return this
|
||||||
|
|
||||||
|
val (firConversionFunction, irConversionFunction) = conversionFunctions[sourceTypeClassifier] ?: return this
|
||||||
|
|
||||||
|
this.applyToElement(argument, firConversionFunction, irConversionFunction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrExpression.applyTypeArguments(access: FirQualifiedAccessExpression): IrExpression {
|
internal fun IrExpression.applyTypeArguments(access: FirQualifiedAccessExpression): IrExpression {
|
||||||
@@ -1159,7 +1166,6 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
|
||||||
private fun IrExpression.applyTypeArguments(
|
private fun IrExpression.applyTypeArguments(
|
||||||
typeArguments: List<FirTypeProjection>?,
|
typeArguments: List<FirTypeProjection>?,
|
||||||
typeParameters: List<FirTypeParameter>?,
|
typeParameters: List<FirTypeParameter>?,
|
||||||
@@ -1185,7 +1191,7 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
} else {
|
} else {
|
||||||
val name = if (this is IrCallImpl) symbol.owner.name else "???"
|
val name = if (this is IrCallImpl) symbol.signature.toString() else "???"
|
||||||
return IrErrorExpressionImpl(
|
return IrErrorExpressionImpl(
|
||||||
startOffset, endOffset, type,
|
startOffset, endOffset, type,
|
||||||
"Cannot bind $argumentsCount type arguments to $name call with $typeArgumentsCount type parameters"
|
"Cannot bind $argumentsCount type arguments to $name call with $typeArgumentsCount type parameters"
|
||||||
@@ -1213,7 +1219,6 @@ class CallAndReferenceGenerator(
|
|||||||
?: explicitReceiverExpression
|
?: explicitReceiverExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(IrSymbolInternals::class)
|
|
||||||
private fun IrExpression.applyReceivers(
|
private fun IrExpression.applyReceivers(
|
||||||
qualifiedAccess: FirQualifiedAccessExpression,
|
qualifiedAccess: FirQualifiedAccessExpression,
|
||||||
explicitReceiverExpression: IrExpression?,
|
explicitReceiverExpression: IrExpression?,
|
||||||
@@ -1223,10 +1228,17 @@ class CallAndReferenceGenerator(
|
|||||||
val resolvedFirSymbol = qualifiedAccess.toResolvedCallableSymbol()
|
val resolvedFirSymbol = qualifiedAccess.toResolvedCallableSymbol()
|
||||||
if (resolvedFirSymbol?.dispatchReceiverType != null) {
|
if (resolvedFirSymbol?.dispatchReceiverType != null) {
|
||||||
val baseDispatchReceiver = qualifiedAccess.findIrDispatchReceiver(explicitReceiverExpression)
|
val baseDispatchReceiver = qualifiedAccess.findIrDispatchReceiver(explicitReceiverExpression)
|
||||||
|
var firDispatchReceiver = qualifiedAccess.dispatchReceiver.takeUnless { it is FirNoReceiverExpression }
|
||||||
|
if (firDispatchReceiver is FirPropertyAccessExpression && firDispatchReceiver.calleeReference is FirSuperReference) {
|
||||||
|
firDispatchReceiver = firDispatchReceiver.dispatchReceiver
|
||||||
|
}
|
||||||
|
val notFromAny = !resolvedFirSymbol.isFunctionFromAny()
|
||||||
|
val notAnInterface = firDispatchReceiver?.resolvedType?.toRegularClassSymbol(session)?.isInterface != true
|
||||||
dispatchReceiver =
|
dispatchReceiver =
|
||||||
if (!resolvedFirSymbol.isFunctionFromAny() || baseDispatchReceiver?.type?.classOrNull?.owner?.isInterface != true) {
|
if (notFromAny || notAnInterface) {
|
||||||
baseDispatchReceiver
|
baseDispatchReceiver
|
||||||
} else {
|
} else {
|
||||||
|
requireNotNull(baseDispatchReceiver)
|
||||||
// NB: for FE 1.0, this type cast is added by InterfaceObjectCallsLowering
|
// NB: for FE 1.0, this type cast is added by InterfaceObjectCallsLowering
|
||||||
// However, it doesn't work for FIR due to different f/o structure
|
// However, it doesn't work for FIR due to different f/o structure
|
||||||
// (FIR calls Any method directly, but FE 1.0 calls its interface f/o instead)
|
// (FIR calls Any method directly, but FE 1.0 calls its interface f/o instead)
|
||||||
@@ -1259,8 +1271,10 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is IrFieldAccessExpression -> {
|
is IrFieldAccessExpression -> {
|
||||||
val ownerField = symbol.owner
|
val firDeclaration = qualifiedAccess.toResolvedCallableSymbol()!!.fir.propertyIfBackingField
|
||||||
if (!ownerField.isStatic) {
|
// Top-level properties are considered as static in IR
|
||||||
|
val fieldIsStatic = firDeclaration.isStatic || (firDeclaration is FirProperty && !firDeclaration.isLocal && firDeclaration.containingClassLookupTag() == null)
|
||||||
|
if (!fieldIsStatic) {
|
||||||
receiver = qualifiedAccess.findIrDispatchReceiver(explicitReceiverExpression)
|
receiver = qualifiedAccess.findIrDispatchReceiver(explicitReceiverExpression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -3717,6 +3717,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("referenceToTypealiasConstructorInLet.kt")
|
||||||
|
public void testReferenceToTypealiasConstructorInLet() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/referenceToTypealiasConstructorInLet.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("staticMethod.kt")
|
@TestMetadata("staticMethod.kt")
|
||||||
public void testStaticMethod() throws Exception {
|
public void testStaticMethod() throws Exception {
|
||||||
|
|||||||
+6
@@ -3717,6 +3717,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("referenceToTypealiasConstructorInLet.kt")
|
||||||
|
public void testReferenceToTypealiasConstructorInLet() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/referenceToTypealiasConstructorInLet.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("staticMethod.kt")
|
@TestMetadata("staticMethod.kt")
|
||||||
public void testStaticMethod() throws Exception {
|
public void testStaticMethod() throws Exception {
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// WITH_STDLIB
|
||||||
|
// FULL_JDK
|
||||||
|
|
||||||
|
import java.util.EnumMap
|
||||||
|
|
||||||
|
enum class SomeEnum {
|
||||||
|
A, B
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias SomeMap = EnumMap<SomeEnum, String>
|
||||||
|
|
||||||
|
fun test(oldMap: SomeMap, key: SomeEnum): String {
|
||||||
|
val newMap = oldMap.let(::SomeMap)
|
||||||
|
return newMap.getValue(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val map = EnumMap(mapOf(SomeEnum.A to "OK"))
|
||||||
|
return test(map, SomeEnum.A)
|
||||||
|
}
|
||||||
+6
@@ -3717,6 +3717,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("referenceToTypealiasConstructorInLet.kt")
|
||||||
|
public void testReferenceToTypealiasConstructorInLet() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/referenceToTypealiasConstructorInLet.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("staticMethod.kt")
|
@TestMetadata("staticMethod.kt")
|
||||||
public void testStaticMethod() throws Exception {
|
public void testStaticMethod() throws Exception {
|
||||||
|
|||||||
+6
@@ -3717,6 +3717,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("referenceToTypealiasConstructorInLet.kt")
|
||||||
|
public void testReferenceToTypealiasConstructorInLet() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/referenceToTypealiasConstructorInLet.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("staticMethod.kt")
|
@TestMetadata("staticMethod.kt")
|
||||||
public void testStaticMethod() throws Exception {
|
public void testStaticMethod() throws Exception {
|
||||||
|
|||||||
+5
@@ -3256,6 +3256,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
runTest("compiler/testData/codegen/box/callableReference/referenceToGenericSyntheticProperty.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("referenceToTypealiasConstructorInLet.kt")
|
||||||
|
public void testReferenceToTypealiasConstructorInLet() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/referenceToTypealiasConstructorInLet.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("staticMethod.kt")
|
@TestMetadata("staticMethod.kt")
|
||||||
public void testStaticMethod() throws Exception {
|
public void testStaticMethod() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/staticMethod.kt");
|
runTest("compiler/testData/codegen/box/callableReference/staticMethod.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user