FirTypeIntersectionScope: introduce "intersection" fake overrides
This commit is contained in:
@@ -447,8 +447,9 @@ class Fir2IrVisitor(
|
|||||||
if (castTypeRef is FirResolvedTypeRef && originalTypeRef is FirResolvedTypeRef) {
|
if (castTypeRef is FirResolvedTypeRef && originalTypeRef is FirResolvedTypeRef) {
|
||||||
val castType = castTypeRef.type
|
val castType = castTypeRef.type
|
||||||
if (castType is ConeIntersectionType) {
|
if (castType is ConeIntersectionType) {
|
||||||
|
val unwrappedSymbol = (referencedSymbol as? FirCallableSymbol)?.overriddenSymbol ?: referencedSymbol
|
||||||
castType.intersectedTypes.forEach {
|
castType.intersectedTypes.forEach {
|
||||||
if (it.doesContainReferencedSymbolInScope(referencedSymbol, calleeReference.name)) {
|
if (it.doesContainReferencedSymbolInScope(unwrappedSymbol, calleeReference.name)) {
|
||||||
return implicitCastOrExpression(value, it)
|
return implicitCastOrExpression(value, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+34
@@ -8,10 +8,15 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
|||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.builder.FirValueParameterBuilder
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
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.FirNamedFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
|
|
||||||
abstract class AbstractFirOverrideScope(
|
abstract class AbstractFirOverrideScope(
|
||||||
val session: FirSession,
|
val session: FirSession,
|
||||||
@@ -58,4 +63,33 @@ abstract class AbstractFirOverrideScope(
|
|||||||
return override
|
return override
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun createFunctionCopy(
|
||||||
|
firSimpleFunction: FirSimpleFunction,
|
||||||
|
newSymbol: FirNamedFunctionSymbol
|
||||||
|
): FirSimpleFunctionBuilder =
|
||||||
|
FirSimpleFunctionBuilder().apply {
|
||||||
|
source = firSimpleFunction.source
|
||||||
|
session = firSimpleFunction.session
|
||||||
|
origin = FirDeclarationOrigin.FakeOverride
|
||||||
|
returnTypeRef = firSimpleFunction.returnTypeRef
|
||||||
|
receiverTypeRef = firSimpleFunction.receiverTypeRef
|
||||||
|
name = firSimpleFunction.name
|
||||||
|
status = firSimpleFunction.status
|
||||||
|
symbol = newSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun createValueParameterCopy(parameter: FirValueParameter, newDefaultValue: FirExpression?): FirValueParameterBuilder =
|
||||||
|
FirValueParameterBuilder().apply {
|
||||||
|
source = parameter.source
|
||||||
|
session = parameter.session
|
||||||
|
origin = FirDeclarationOrigin.FakeOverride
|
||||||
|
returnTypeRef = parameter.returnTypeRef
|
||||||
|
name = parameter.name
|
||||||
|
symbol = FirVariableSymbol(parameter.symbol.callableId)
|
||||||
|
defaultValue = newDefaultValue
|
||||||
|
isCrossinline = parameter.isCrossinline
|
||||||
|
isNoinline = parameter.isNoinline
|
||||||
|
isVararg = parameter.isVararg
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-34
@@ -6,13 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.fir.scopes.impl
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirValueParameterBuilder
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
@@ -108,35 +103,6 @@ abstract class AbstractFirUseSiteMemberScope(
|
|||||||
return newSymbol
|
return newSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun createFunctionCopy(
|
|
||||||
firSimpleFunction: FirSimpleFunction,
|
|
||||||
newSymbol: FirNamedFunctionSymbol
|
|
||||||
): FirSimpleFunctionBuilder =
|
|
||||||
FirSimpleFunctionBuilder().apply {
|
|
||||||
source = firSimpleFunction.source
|
|
||||||
session = firSimpleFunction.session
|
|
||||||
origin = FirDeclarationOrigin.FakeOverride
|
|
||||||
returnTypeRef = firSimpleFunction.returnTypeRef
|
|
||||||
receiverTypeRef = firSimpleFunction.receiverTypeRef
|
|
||||||
name = firSimpleFunction.name
|
|
||||||
status = firSimpleFunction.status
|
|
||||||
symbol = newSymbol
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun createValueParameterCopy(parameter: FirValueParameter, newDefaultValue: FirExpression?): FirValueParameterBuilder =
|
|
||||||
FirValueParameterBuilder().apply {
|
|
||||||
source = parameter.source
|
|
||||||
session = parameter.session
|
|
||||||
origin = FirDeclarationOrigin.FakeOverride
|
|
||||||
returnTypeRef = parameter.returnTypeRef
|
|
||||||
name = parameter.name
|
|
||||||
symbol = FirVariableSymbol(parameter.symbol.callableId)
|
|
||||||
defaultValue = newDefaultValue
|
|
||||||
isCrossinline = parameter.isCrossinline
|
|
||||||
isNoinline = parameter.isNoinline
|
|
||||||
isVararg = parameter.isVararg
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun processOverriddenFunctionsWithDepth(
|
override fun processOverriddenFunctionsWithDepth(
|
||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
||||||
|
|||||||
+21
-6
@@ -91,8 +91,22 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembers)
|
val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembers)
|
||||||
|
|
||||||
val mostSpecific = selectMostSpecificMember(extractedOverrides)
|
val mostSpecific = selectMostSpecificMember(extractedOverrides)
|
||||||
overriddenSymbols[mostSpecific] = extractedOverrides
|
if (extractedOverrides.size > 1 && mostSpecific is FirNamedFunctionSymbol) {
|
||||||
processor(mostSpecific)
|
// TODO: same code for properties
|
||||||
|
val newSymbol = FirNamedFunctionSymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific)
|
||||||
|
val mostSpecificFunction = mostSpecific.fir
|
||||||
|
createFunctionCopy(mostSpecific.fir, newSymbol).apply {
|
||||||
|
resolvePhase = mostSpecificFunction.resolvePhase
|
||||||
|
typeParameters += mostSpecificFunction.typeParameters
|
||||||
|
valueParameters += mostSpecificFunction.valueParameters
|
||||||
|
}.build()
|
||||||
|
overriddenSymbols[newSymbol] = extractedOverrides
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
processor(newSymbol as D)
|
||||||
|
} else {
|
||||||
|
overriddenSymbols[mostSpecific] = extractedOverrides
|
||||||
|
processor(mostSpecific)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@@ -240,12 +254,13 @@ class FirTypeIntersectionScope private constructor(
|
|||||||
functionSymbol: FirFunctionSymbol<*>,
|
functionSymbol: FirFunctionSymbol<*>,
|
||||||
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
|
||||||
): ProcessorAction {
|
): ProcessorAction {
|
||||||
for (directOverridden in getDirectOverriddenSymbols(functionSymbol)) {
|
for (overridden in getDirectOverriddenSymbols(functionSymbol)) {
|
||||||
if (!processor(directOverridden, 0)) return ProcessorAction.STOP
|
val overriddenDepth = if (overridden is FirNamedFunctionSymbol && overridden.overriddenSymbol != null) 0 else 1
|
||||||
|
if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP
|
||||||
// TODO: Preserve the scope where directOverridden came from
|
// TODO: Preserve the scope where directOverridden came from
|
||||||
for (scope in scopes) {
|
for (scope in scopes) {
|
||||||
if (!scope.processOverriddenFunctionsWithDepth(directOverridden) { symbol, depth ->
|
if (!scope.processOverriddenFunctionsWithDepth(overridden) { symbol, depth ->
|
||||||
processor(symbol, depth)
|
processor(symbol, depth + overriddenDepth)
|
||||||
}
|
}
|
||||||
) return ProcessorAction.STOP
|
) return ProcessorAction.STOP
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ abstract class FirTypeScope : FirScope() {
|
|||||||
directOverriddenMap[functionSymbol] ?: return baseScope.processOverriddenFunctionsWithDepth(functionSymbol, processor)
|
directOverriddenMap[functionSymbol] ?: return baseScope.processOverriddenFunctionsWithDepth(functionSymbol, processor)
|
||||||
|
|
||||||
for (overridden in directOverridden) {
|
for (overridden in directOverridden) {
|
||||||
val overriddenDepth = if (overridden is FirNamedFunctionSymbol && overridden.isFakeOverride) 0 else 1
|
val overriddenDepth = if (overridden is FirNamedFunctionSymbol && overridden.overriddenSymbol != null) 0 else 1
|
||||||
if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP
|
if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP
|
||||||
if (!baseScope.processOverriddenFunctionsWithDepth(overridden) { symbol, depth ->
|
if (!baseScope.processOverriddenFunctionsWithDepth(overridden) { symbol, depth ->
|
||||||
processor(symbol, depth + overriddenDepth)
|
processor(symbol, depth + overriddenDepth)
|
||||||
|
|||||||
+1
-1
@@ -97,8 +97,8 @@ FILE fqName:<root> fileName:/implicitNotNullOnDelegatedImplementation.kt
|
|||||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:K4 modality:FINAL visibility:public superTypes:[<root>.JUnrelatedFoo; <root>.IFoo]'
|
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:K4 modality:FINAL visibility:public superTypes:[<root>.JUnrelatedFoo; <root>.IFoo]'
|
||||||
FUN name:foo visibility:public modality:FINAL <> ($this:<root>.K4) returnType:kotlin.String?
|
FUN name:foo visibility:public modality:FINAL <> ($this:<root>.K4) returnType:kotlin.String?
|
||||||
overridden:
|
overridden:
|
||||||
public abstract fun foo (): kotlin.String declared in <root>.IFoo
|
|
||||||
public open fun foo (): kotlin.String? declared in <root>.JUnrelatedFoo
|
public open fun foo (): kotlin.String? declared in <root>.JUnrelatedFoo
|
||||||
|
public abstract fun foo (): kotlin.String declared in <root>.IFoo
|
||||||
$this: VALUE_PARAMETER name:<this> type:<root>.K4
|
$this: VALUE_PARAMETER name:<this> type:<root>.K4
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun foo (): kotlin.String? declared in <root>.K4'
|
RETURN type=kotlin.Nothing from='public final fun foo (): kotlin.String? declared in <root>.K4'
|
||||||
|
|||||||
Reference in New Issue
Block a user