FirTypeIntersectionScope: introduce "intersection" fake overrides

This commit is contained in:
Mikhail Glukhikh
2020-07-14 10:43:10 +03:00
parent 5a422b5ef6
commit 7a2ea49399
6 changed files with 59 additions and 43 deletions
@@ -447,8 +447,9 @@ class Fir2IrVisitor(
if (castTypeRef is FirResolvedTypeRef && originalTypeRef is FirResolvedTypeRef) {
val castType = castTypeRef.type
if (castType is ConeIntersectionType) {
val unwrappedSymbol = (referencedSymbol as? FirCallableSymbol)?.overriddenSymbol ?: referencedSymbol
castType.intersectedTypes.forEach {
if (it.doesContainReferencedSymbolInScope(referencedSymbol, calleeReference.name)) {
if (it.doesContainReferencedSymbolInScope(unwrappedSymbol, calleeReference.name)) {
return implicitCastOrExpression(value, it)
}
}
@@ -8,10 +8,15 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSession
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.FirOverrideChecker
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
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(
val session: FirSession,
@@ -58,4 +63,33 @@ abstract class AbstractFirOverrideScope(
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
}
}
@@ -6,13 +6,8 @@
package org.jetbrains.kotlin.fir.scopes.impl
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.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.scopes.FirOverrideChecker
import org.jetbrains.kotlin.fir.scopes.FirScope
@@ -108,35 +103,6 @@ abstract class AbstractFirUseSiteMemberScope(
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(
functionSymbol: FirFunctionSymbol<*>,
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
@@ -91,8 +91,22 @@ class FirTypeIntersectionScope private constructor(
val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembers)
val mostSpecific = selectMostSpecificMember(extractedOverrides)
overriddenSymbols[mostSpecific] = extractedOverrides
processor(mostSpecific)
if (extractedOverrides.size > 1 && mostSpecific is FirNamedFunctionSymbol) {
// 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
@@ -240,12 +254,13 @@ class FirTypeIntersectionScope private constructor(
functionSymbol: FirFunctionSymbol<*>,
processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction
): ProcessorAction {
for (directOverridden in getDirectOverriddenSymbols(functionSymbol)) {
if (!processor(directOverridden, 0)) return ProcessorAction.STOP
for (overridden in getDirectOverriddenSymbols(functionSymbol)) {
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
for (scope in scopes) {
if (!scope.processOverriddenFunctionsWithDepth(directOverridden) { symbol, depth ->
processor(symbol, depth)
if (!scope.processOverriddenFunctionsWithDepth(overridden) { symbol, depth ->
processor(symbol, depth + overriddenDepth)
}
) return ProcessorAction.STOP
}
@@ -49,7 +49,7 @@ abstract class FirTypeScope : FirScope() {
directOverriddenMap[functionSymbol] ?: return baseScope.processOverriddenFunctionsWithDepth(functionSymbol, processor)
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 (!baseScope.processOverriddenFunctionsWithDepth(overridden) { symbol, depth ->
processor(symbol, depth + overriddenDepth)
@@ -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]'
FUN name:foo visibility:public modality:FINAL <> ($this:<root>.K4) returnType:kotlin.String?
overridden:
public abstract fun foo (): kotlin.String declared in <root>.IFoo
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
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun foo (): kotlin.String? declared in <root>.K4'