FIR2IR: Simplify Fir2IrImplicitCastInserter::convertToImplicitCastExpression
Use dispatchReceiverType instead of looking into scopes
This commit is contained in:
+19
-61
@@ -6,9 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.fir.backend
|
package org.jetbrains.kotlin.fir.backend
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.baseForIntersectionOverride
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
|
import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement
|
||||||
@@ -16,15 +16,8 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
|||||||
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.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.scope
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
@@ -36,7 +29,7 @@ import org.jetbrains.kotlin.ir.types.withHasQuestionMark
|
|||||||
import org.jetbrains.kotlin.ir.util.classId
|
import org.jetbrains.kotlin.ir.util.classId
|
||||||
import org.jetbrains.kotlin.ir.util.coerceToUnitIfNeeded
|
import org.jetbrains.kotlin.ir.util.coerceToUnitIfNeeded
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
|
|
||||||
class Fir2IrImplicitCastInserter(
|
class Fir2IrImplicitCastInserter(
|
||||||
private val components: Fir2IrComponents,
|
private val components: Fir2IrComponents,
|
||||||
@@ -292,61 +285,26 @@ class Fir2IrImplicitCastInserter(
|
|||||||
): IrExpression {
|
): IrExpression {
|
||||||
val originalExpression = expressionWithSmartcast.originalExpression
|
val originalExpression = expressionWithSmartcast.originalExpression
|
||||||
val value = visitor.convertToIrExpression(originalExpression)
|
val value = visitor.convertToIrExpression(originalExpression)
|
||||||
val castTypeRef = expressionWithSmartcast.typeRef
|
|
||||||
if (calleeReference !is FirResolvedNamedReference) {
|
|
||||||
return implicitCastOrExpression(value, castTypeRef)
|
|
||||||
}
|
|
||||||
val referencedSymbol = calleeReference.resolvedSymbol
|
|
||||||
if (referencedSymbol !is FirPropertySymbol && referencedSymbol !is FirFunctionSymbol && referencedSymbol !is FirFieldSymbol) {
|
|
||||||
return implicitCastOrExpression(value, castTypeRef)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (castTypeRef is FirResolvedTypeRef) {
|
val typeRef = expressionWithSmartcast.typeRef
|
||||||
val castType = castTypeRef.type
|
val referencedDeclaration =
|
||||||
if (castType is ConeIntersectionType) {
|
((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirCallableSymbol<*>)?.unwrapCallRepresentative()
|
||||||
val unwrappedSymbol = (referencedSymbol as? FirCallableSymbol)?.baseForIntersectionOverride ?: referencedSymbol
|
?.fir as FirCallableMemberDeclaration<*>
|
||||||
castType.intersectedTypes.forEach {
|
|
||||||
if (it.doesContainReferencedSymbolInScope(unwrappedSymbol, calleeReference.name)) {
|
val dispatchReceiverType =
|
||||||
return implicitCastOrExpression(value, it)
|
referencedDeclaration.dispatchReceiverType as? ConeClassLikeType
|
||||||
}
|
?: return implicitCastOrExpression(value, typeRef)
|
||||||
}
|
|
||||||
|
val starProjectedDispatchReceiver = dispatchReceiverType.replaceArgumentsWithStarProjections()
|
||||||
|
|
||||||
|
val castType = typeRef.coneTypeSafe<ConeIntersectionType>()
|
||||||
|
castType?.intersectedTypes?.forEach { type ->
|
||||||
|
if (AbstractTypeChecker.isSubtypeOf(session.typeContext, type, starProjectedDispatchReceiver)) {
|
||||||
|
return implicitCastOrExpression(value, type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return implicitCastOrExpression(value, castTypeRef.toIrType())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ConeKotlinType.doesContainReferencedSymbolInScope(
|
return implicitCastOrExpression(value, typeRef)
|
||||||
referencedSymbol: AbstractFirBasedSymbol<*>, name: Name
|
|
||||||
): Boolean {
|
|
||||||
val scope = scope(session, components.scopeSession, FakeOverrideTypeCalculator.Forced) ?: return false
|
|
||||||
if (referencedSymbol is SyntheticPropertySymbol) {
|
|
||||||
return doesContainReferencedSyntheticSymbolInScope(referencedSymbol, name, scope)
|
|
||||||
}
|
|
||||||
var result = false
|
|
||||||
val processor = { it: FirCallableSymbol<*> ->
|
|
||||||
if (!result && it == referencedSymbol) {
|
|
||||||
result = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
when (referencedSymbol) {
|
|
||||||
is FirPropertySymbol, is FirFieldSymbol -> scope.processPropertiesByName(name, processor)
|
|
||||||
is FirFunctionSymbol -> scope.processFunctionsByName(name, processor)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doesContainReferencedSyntheticSymbolInScope(
|
|
||||||
referencedSymbol: SyntheticPropertySymbol, name: Name, baseScope: FirTypeScope
|
|
||||||
): Boolean {
|
|
||||||
val scope = FirSyntheticPropertiesScope(session, baseScope)
|
|
||||||
var result = false
|
|
||||||
val processor = { it: FirCallableSymbol<*> ->
|
|
||||||
if (!result && it.callableId == referencedSymbol.callableId) {
|
|
||||||
result = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scope.processPropertiesByName(name, processor)
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun implicitCastOrExpression(original: IrExpression, castType: ConeKotlinType): IrExpression {
|
private fun implicitCastOrExpression(original: IrExpression, castType: ConeKotlinType): IrExpression {
|
||||||
|
|||||||
Reference in New Issue
Block a user