Introduce AbstractFirUseSiteScope and store common J/K code there
This commit is contained in:
+1
-3
@@ -6,14 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.fir.java.scopes
|
package org.jetbrains.kotlin.fir.java.scopes
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||||
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.impl.*
|
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
|
||||||
import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement
|
|
||||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.java.enhancement.*
|
import org.jetbrains.kotlin.fir.java.enhancement.*
|
||||||
@@ -352,7 +350,7 @@ class JavaClassEnhancementScope(
|
|||||||
val backMap = overrideBindCache.getOrPut(this.name) {
|
val backMap = overrideBindCache.getOrPut(this.name) {
|
||||||
useSiteScope.bindOverrides(this.name)
|
useSiteScope.bindOverrides(this.name)
|
||||||
useSiteScope
|
useSiteScope
|
||||||
.overriddenByBase
|
.overrideByBase
|
||||||
.toList()
|
.toList()
|
||||||
.groupBy({ (_, key) -> key }, { (value) -> value })
|
.groupBy({ (_, key) -> key }, { (value) -> value })
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-101
@@ -16,30 +16,25 @@ import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
|||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.*
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.*
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.impl.AbstractFirUseSiteScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirSuperTypeScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirSuperTypeScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.*
|
import org.jetbrains.kotlin.fir.symbols.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
class JavaClassUseSiteScope(
|
class JavaClassUseSiteScope(
|
||||||
klass: FirRegularClass,
|
klass: FirRegularClass,
|
||||||
private val session: FirSession,
|
session: FirSession,
|
||||||
private val superTypesScope: FirSuperTypeScope,
|
superTypesScope: FirSuperTypeScope,
|
||||||
private val declaredMemberScope: FirScope
|
declaredMemberScope: FirScope
|
||||||
) : FirScope() {
|
) : AbstractFirUseSiteScope(session, superTypesScope, declaredMemberScope) {
|
||||||
internal val symbol = klass.symbol
|
internal val symbol = klass.symbol
|
||||||
|
|
||||||
private val javaTypeParameterStack: JavaTypeParameterStack =
|
private val javaTypeParameterStack: JavaTypeParameterStack =
|
||||||
if (klass is FirJavaClass) klass.javaTypeParameterStack else JavaTypeParameterStack.EMPTY
|
if (klass is FirJavaClass) klass.javaTypeParameterStack else JavaTypeParameterStack.EMPTY
|
||||||
|
|
||||||
//base symbol as key, overridden as value
|
|
||||||
internal val overriddenByBase = mutableMapOf<FirCallableSymbol<*>, FirCallableSymbol<*>?>()
|
|
||||||
|
|
||||||
private val context: ConeTypeContext = session.typeContext
|
|
||||||
|
|
||||||
private fun isEqualTypes(a: ConeKotlinType, b: ConeKotlinType, substitutor: ConeSubstitutor): Boolean {
|
private fun isEqualTypes(a: ConeKotlinType, b: ConeKotlinType, substitutor: ConeSubstitutor): Boolean {
|
||||||
if (a is ConeFlexibleType) return isEqualTypes(a.lowerBound, b, substitutor)
|
if (a is ConeFlexibleType) return isEqualTypes(a.lowerBound, b, substitutor)
|
||||||
if (b is ConeFlexibleType) return isEqualTypes(a, b.lowerBound, substitutor)
|
if (b is ConeFlexibleType) return isEqualTypes(a, b.lowerBound, substitutor)
|
||||||
@@ -58,18 +53,19 @@ class JavaClassUseSiteScope(
|
|||||||
substitutor
|
substitutor
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun isOverriddenFunCheck(overriddenInJava: FirSimpleFunction, base: FirSimpleFunction): Boolean {
|
override fun isOverriddenFunCheck(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean {
|
||||||
val receiverTypeRef = base.receiverTypeRef
|
// NB: overrideCandidate is from Java and has no receiver
|
||||||
val baseParameterTypes = listOfNotNull(receiverTypeRef) + base.valueParameters.map { it.returnTypeRef }
|
val receiverTypeRef = baseDeclaration.receiverTypeRef
|
||||||
|
val baseParameterTypes = listOfNotNull(receiverTypeRef) + baseDeclaration.valueParameters.map { it.returnTypeRef }
|
||||||
|
|
||||||
if (overriddenInJava.valueParameters.size != baseParameterTypes.size) return false
|
if (overrideCandidate.valueParameters.size != baseParameterTypes.size) return false
|
||||||
if (overriddenInJava.typeParameters.size != base.typeParameters.size) return false
|
if (overrideCandidate.typeParameters.size != baseDeclaration.typeParameters.size) return false
|
||||||
|
|
||||||
val types = base.typeParameters.map {
|
val types = baseDeclaration.typeParameters.map {
|
||||||
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
||||||
}
|
}
|
||||||
val substitution = substitutorByMap(overriddenInJava.typeParameters.map { it.symbol }.zip(types).toMap())
|
val substitution = substitutorByMap(overrideCandidate.typeParameters.map { it.symbol }.zip(types).toMap())
|
||||||
if (!overriddenInJava.typeParameters.zip(base.typeParameters).all { (a, b) ->
|
if (!overrideCandidate.typeParameters.zip(baseDeclaration.typeParameters).all { (a, b) ->
|
||||||
a.bounds.size == b.bounds.size && a.bounds.zip(b.bounds).all { (aBound, bBound) ->
|
a.bounds.size == b.bounds.size && a.bounds.zip(b.bounds).all { (aBound, bBound) ->
|
||||||
isEqualTypes(aBound, bBound, substitution)
|
isEqualTypes(aBound, bBound, substitution)
|
||||||
}
|
}
|
||||||
@@ -77,29 +73,33 @@ class JavaClassUseSiteScope(
|
|||||||
) return false
|
) return false
|
||||||
|
|
||||||
|
|
||||||
return overriddenInJava.valueParameters.zip(baseParameterTypes).all { (paramFromJava, baseType) ->
|
return overrideCandidate.valueParameters.zip(baseParameterTypes).all { (paramFromJava, baseType) ->
|
||||||
isEqualTypes(paramFromJava.returnTypeRef, baseType, substitution)
|
isEqualTypes(paramFromJava.returnTypeRef, baseType, substitution)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isOverriddenPropertyCheck(overriddenInJava: FirSimpleFunction, base: FirProperty): Boolean {
|
override fun isOverriddenPropertyCheck(overrideCandidate: FirCallableMemberDeclaration<*>, baseDeclaration: FirProperty): Boolean {
|
||||||
val receiverTypeRef = base.receiverTypeRef
|
if (baseDeclaration.modality == Modality.FINAL) return false
|
||||||
if (receiverTypeRef == null) {
|
val receiverTypeRef = baseDeclaration.receiverTypeRef
|
||||||
// TODO: setters
|
return when (overrideCandidate) {
|
||||||
return overriddenInJava.valueParameters.isEmpty()
|
is FirSimpleFunction -> {
|
||||||
} else {
|
if (receiverTypeRef == null) {
|
||||||
if (overriddenInJava.valueParameters.size != 1) return false
|
// TODO: setters
|
||||||
return isEqualTypes(receiverTypeRef, overriddenInJava.valueParameters.single().returnTypeRef, ConeSubstitutor.Empty)
|
return overrideCandidate.valueParameters.isEmpty()
|
||||||
}
|
} else {
|
||||||
}
|
if (overrideCandidate.valueParameters.size != 1) return false
|
||||||
|
return isEqualTypes(receiverTypeRef, overrideCandidate.valueParameters.single().returnTypeRef, ConeSubstitutor.Empty)
|
||||||
private fun isOverriddenPropertyCheck(overriddenInKotlin: FirProperty, base: FirProperty): Boolean {
|
}
|
||||||
val receiverTypeRef = base.receiverTypeRef
|
}
|
||||||
val overriddenReceiverTypeRef = overriddenInKotlin.receiverTypeRef
|
is FirProperty -> {
|
||||||
return when {
|
val overrideReceiverTypeRef = overrideCandidate.receiverTypeRef
|
||||||
receiverTypeRef == null -> overriddenReceiverTypeRef == null
|
return when {
|
||||||
overriddenReceiverTypeRef == null -> false
|
receiverTypeRef == null -> overrideReceiverTypeRef == null
|
||||||
else -> isEqualTypes(receiverTypeRef, overriddenReceiverTypeRef, ConeSubstitutor.Empty)
|
overrideReceiverTypeRef == null -> false
|
||||||
|
else -> isEqualTypes(receiverTypeRef, overrideReceiverTypeRef, ConeSubstitutor.Empty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,70 +117,6 @@ class JavaClassUseSiteScope(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirCallableSymbol<*>.getOverridden(candidates: Set<FirCallableSymbol<*>>): FirCallableSymbol<*>? {
|
|
||||||
if (overriddenByBase.containsKey(this)) return overriddenByBase[this]
|
|
||||||
|
|
||||||
val overriding = when (this) {
|
|
||||||
is FirNamedFunctionSymbol -> {
|
|
||||||
val self = this.fir
|
|
||||||
candidates.firstOrNull {
|
|
||||||
val overridden = (it as? FirNamedFunctionSymbol)?.fir
|
|
||||||
overridden != null && self.modality != Modality.FINAL && isOverriddenFunCheck(overridden, self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is FirConstructorSymbol, is FirFieldSymbol -> {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
is FirPropertySymbol -> {
|
|
||||||
val self = fir
|
|
||||||
candidates.firstOrNull {
|
|
||||||
when (it) {
|
|
||||||
is FirNamedFunctionSymbol -> {
|
|
||||||
val overridden = it.fir
|
|
||||||
self.modality != Modality.FINAL && isOverriddenPropertyCheck(overridden, self)
|
|
||||||
}
|
|
||||||
is FirPropertySymbol -> {
|
|
||||||
val overridden = it.fir
|
|
||||||
self.modality != Modality.FINAL && isOverriddenPropertyCheck(overridden, self)
|
|
||||||
}
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is FirAccessorSymbol -> {
|
|
||||||
val self = fir
|
|
||||||
candidates.firstOrNull {
|
|
||||||
val overridden = (it as? FirNamedFunctionSymbol)?.fir
|
|
||||||
overridden != null && self.modality != Modality.FINAL && isOverriddenFunCheck(overridden, self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> error("Unexpected callable symbol: $this")
|
|
||||||
}
|
|
||||||
// TODO: two or more overrides for one fun?
|
|
||||||
overriddenByBase[this] = overriding
|
|
||||||
return overriding
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
|
|
||||||
val overrideCandidates = mutableSetOf<FirFunctionSymbol<*>>()
|
|
||||||
if (!declaredMemberScope.processFunctionsByName(name) {
|
|
||||||
overrideCandidates += it
|
|
||||||
processor(it)
|
|
||||||
}
|
|
||||||
) return STOP
|
|
||||||
|
|
||||||
return superTypesScope.processFunctionsByName(name) {
|
|
||||||
|
|
||||||
val overriddenBy = it.getOverridden(overrideCandidates)
|
|
||||||
if (overriddenBy == null) {
|
|
||||||
processor(it)
|
|
||||||
} else {
|
|
||||||
NEXT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processAccessorFunctionsAndPropertiesByName(
|
private fun processAccessorFunctionsAndPropertiesByName(
|
||||||
propertyName: Name,
|
propertyName: Name,
|
||||||
accessorName: Name,
|
accessorName: Name,
|
||||||
|
|||||||
+44
-32
@@ -20,10 +20,10 @@ import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
|
|||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
|
|
||||||
abstract class AbstractFirOverrideScope(val session: FirSession) : FirScope() {
|
abstract class AbstractFirOverrideScope(val session: FirSession) : FirScope() {
|
||||||
//base symbol as key
|
//base symbol as key, overridden as value
|
||||||
val overrides = mutableMapOf<FirCallableSymbol<*>, FirCallableSymbol<*>?>()
|
val overrideByBase = mutableMapOf<FirCallableSymbol<*>, FirCallableSymbol<*>?>()
|
||||||
|
|
||||||
val context: ConeTypeContext = session.typeContext
|
protected val context: ConeTypeContext = session.typeContext
|
||||||
|
|
||||||
private fun isEqualTypes(a: ConeKotlinType, b: ConeKotlinType, substitution: ConeSubstitutor) =
|
private fun isEqualTypes(a: ConeKotlinType, b: ConeKotlinType, substitution: ConeSubstitutor) =
|
||||||
AbstractStrictEqualityTypeChecker.strictEqualTypes(context, substitution.substituteOrSelf(a), substitution.substituteOrSelf(b))
|
AbstractStrictEqualityTypeChecker.strictEqualTypes(context, substitution.substituteOrSelf(a), substitution.substituteOrSelf(b))
|
||||||
@@ -31,26 +31,35 @@ abstract class AbstractFirOverrideScope(val session: FirSession) : FirScope() {
|
|||||||
private fun isEqualTypes(a: FirTypeRef, b: FirTypeRef, substitution: ConeSubstitutor) =
|
private fun isEqualTypes(a: FirTypeRef, b: FirTypeRef, substitution: ConeSubstitutor) =
|
||||||
isEqualTypes(a.cast<FirResolvedTypeRef>().type, b.cast<FirResolvedTypeRef>().type, substitution)
|
isEqualTypes(a.cast<FirResolvedTypeRef>().type, b.cast<FirResolvedTypeRef>().type, substitution)
|
||||||
|
|
||||||
private fun isOverriddenFunCheck(member: FirSimpleFunction, self: FirSimpleFunction): Boolean {
|
protected open fun isOverriddenFunCheck(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean {
|
||||||
if (member.valueParameters.size != self.valueParameters.size) return false
|
if (overrideCandidate.valueParameters.size != baseDeclaration.valueParameters.size) return false
|
||||||
if (member.typeParameters.size != self.typeParameters.size) return false
|
if (overrideCandidate.typeParameters.size != baseDeclaration.typeParameters.size) return false
|
||||||
|
|
||||||
val types = self.typeParameters.map {
|
val types = baseDeclaration.typeParameters.map {
|
||||||
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
||||||
}
|
}
|
||||||
val substitution = substitutorByMap(member.typeParameters.map { it.symbol }.zip(types).toMap())
|
val substitution = substitutorByMap(overrideCandidate.typeParameters.map { it.symbol }.zip(types).toMap())
|
||||||
if (!member.typeParameters.zip(self.typeParameters).all { (a, b) ->
|
if (!overrideCandidate.typeParameters.zip(baseDeclaration.typeParameters).all { (a, b) ->
|
||||||
a.bounds.size == b.bounds.size &&
|
a.bounds.size == b.bounds.size &&
|
||||||
a.bounds.zip(b.bounds).all { (aBound, bBound) -> isEqualTypes(aBound, bBound, substitution) }
|
a.bounds.zip(b.bounds).all { (aBound, bBound) -> isEqualTypes(aBound, bBound, substitution) }
|
||||||
}
|
}
|
||||||
) return false
|
) return false
|
||||||
if (!sameReceivers(member.receiverTypeRef, self.receiverTypeRef, substitution)) return false
|
if (!sameReceivers(overrideCandidate.receiverTypeRef, baseDeclaration.receiverTypeRef, substitution)) return false
|
||||||
|
|
||||||
return member.valueParameters.zip(self.valueParameters).all { (memberParam, selfParam) ->
|
return overrideCandidate.valueParameters.zip(baseDeclaration.valueParameters).all { (memberParam, selfParam) ->
|
||||||
isEqualTypes(memberParam.returnTypeRef, selfParam.returnTypeRef, substitution)
|
isEqualTypes(memberParam.returnTypeRef, selfParam.returnTypeRef, substitution)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun isOverriddenPropertyCheck(
|
||||||
|
overrideCandidate: FirCallableMemberDeclaration<*>, // NB: in Java it can be a function which overrides accessor
|
||||||
|
baseDeclaration: FirProperty
|
||||||
|
): Boolean {
|
||||||
|
// TODO: substitutor
|
||||||
|
return overrideCandidate is FirProperty &&
|
||||||
|
sameReceivers(overrideCandidate.receiverTypeRef, baseDeclaration.receiverTypeRef, ConeSubstitutor.Empty)
|
||||||
|
}
|
||||||
|
|
||||||
private fun sameReceivers(memberTypeRef: FirTypeRef?, selfTypeRef: FirTypeRef?, substitution: ConeSubstitutor): Boolean {
|
private fun sameReceivers(memberTypeRef: FirTypeRef?, selfTypeRef: FirTypeRef?, substitution: ConeSubstitutor): Boolean {
|
||||||
return when {
|
return when {
|
||||||
memberTypeRef != null && selfTypeRef != null -> isEqualTypes(memberTypeRef, selfTypeRef, substitution)
|
memberTypeRef != null && selfTypeRef != null -> isEqualTypes(memberTypeRef, selfTypeRef, substitution)
|
||||||
@@ -58,31 +67,34 @@ abstract class AbstractFirOverrideScope(val session: FirSession) : FirScope() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun FirCallableSymbol<*>.isOverridden(seen: Set<FirCallableSymbol<*>>): FirCallableSymbol<*>? {
|
private fun similarFunctionsOrBothProperties(
|
||||||
if (overrides.containsKey(this)) return overrides[this]
|
overrideCandidate: FirCallableMemberDeclaration<*>,
|
||||||
|
baseDeclaration: FirCallableMemberDeclaration<*>
|
||||||
fun similarFunctionsOrBothProperties(declaration: FirCallableDeclaration<*>, self: FirCallableDeclaration<*>): Boolean {
|
): Boolean {
|
||||||
return when (declaration) {
|
return when (overrideCandidate) {
|
||||||
is FirSimpleFunction -> self is FirSimpleFunction && isOverriddenFunCheck(declaration, self)
|
is FirSimpleFunction -> when (baseDeclaration) {
|
||||||
is FirConstructor -> false
|
is FirSimpleFunction -> isOverriddenFunCheck(overrideCandidate, baseDeclaration)
|
||||||
is FirProperty -> self is FirProperty && sameReceivers(
|
is FirProperty -> isOverriddenPropertyCheck(overrideCandidate, baseDeclaration)
|
||||||
declaration.receiverTypeRef,
|
else -> false
|
||||||
self.receiverTypeRef,
|
|
||||||
ConeSubstitutor.Empty // TODO
|
|
||||||
)
|
|
||||||
is FirField -> false
|
|
||||||
else -> error("Unknown fir callable type: $declaration, $self")
|
|
||||||
}
|
}
|
||||||
|
is FirConstructor -> false
|
||||||
|
is FirProperty -> baseDeclaration is FirProperty && isOverriddenPropertyCheck(overrideCandidate, baseDeclaration)
|
||||||
|
is FirField -> false
|
||||||
|
else -> error("Unknown fir callable type: $overrideCandidate, $baseDeclaration")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val self = (this as AbstractFirBasedSymbol<*>).fir as FirCallableMemberDeclaration<*>
|
// Receiver is super-type function here
|
||||||
val overriding = seen.firstOrNull {
|
protected open fun FirCallableSymbol<*>.getOverridden(overrideCandidates: Set<FirCallableSymbol<*>>): FirCallableSymbol<*>? {
|
||||||
val member = (it as AbstractFirBasedSymbol<*>).fir as FirCallableMemberDeclaration<*>
|
if (overrideByBase.containsKey(this)) return overrideByBase[this]
|
||||||
self.modality != Modality.FINAL
|
|
||||||
&& similarFunctionsOrBothProperties(member, self)
|
val baseDeclaration = (this as AbstractFirBasedSymbol<*>).fir as FirCallableMemberDeclaration<*>
|
||||||
|
val override = overrideCandidates.firstOrNull {
|
||||||
|
val overrideCandidate = (it as AbstractFirBasedSymbol<*>).fir as FirCallableMemberDeclaration<*>
|
||||||
|
baseDeclaration.modality != Modality.FINAL && similarFunctionsOrBothProperties(overrideCandidate, baseDeclaration)
|
||||||
} // TODO: two or more overrides for one fun?
|
} // TODO: two or more overrides for one fun?
|
||||||
overrides[this] = overriding
|
overrideByBase[this] = override
|
||||||
return overriding
|
return override
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.scopes.impl
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
abstract class AbstractFirUseSiteScope(
|
||||||
|
session: FirSession,
|
||||||
|
protected val superTypesScope: FirSuperTypeScope,
|
||||||
|
protected val declaredMemberScope: FirScope
|
||||||
|
) : AbstractFirOverrideScope(session) {
|
||||||
|
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||||
|
val overrideCandidates = mutableSetOf<FirFunctionSymbol<*>>()
|
||||||
|
if (!declaredMemberScope.processFunctionsByName(name) {
|
||||||
|
overrideCandidates += it
|
||||||
|
processor(it)
|
||||||
|
}
|
||||||
|
) return ProcessorAction.STOP
|
||||||
|
|
||||||
|
return superTypesScope.processFunctionsByName(name) {
|
||||||
|
|
||||||
|
val overriddenBy = it.getOverridden(overrideCandidates)
|
||||||
|
if (overriddenBy == null) {
|
||||||
|
processor(it)
|
||||||
|
} else {
|
||||||
|
ProcessorAction.NEXT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun processClassifiersByName(name: Name, position: FirPosition, processor: (FirClassifierSymbol<*>) -> Boolean): Boolean {
|
||||||
|
return declaredMemberScope.processClassifiersByName(name, position, processor)
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-30
@@ -6,40 +6,18 @@
|
|||||||
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.scopes.FirPosition
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
class FirClassUseSiteScope(
|
class FirClassUseSiteScope(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
private val superTypesScope: FirSuperTypeScope,
|
superTypesScope: FirSuperTypeScope,
|
||||||
private val declaredMemberScope: FirScope
|
declaredMemberScope: FirScope
|
||||||
) : AbstractFirOverrideScope(session) {
|
) : AbstractFirUseSiteScope(session, superTypesScope, declaredMemberScope) {
|
||||||
|
|
||||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
|
|
||||||
val seen = mutableSetOf<FirCallableSymbol<*>>()
|
|
||||||
if (!declaredMemberScope.processFunctionsByName(name) {
|
|
||||||
seen += it
|
|
||||||
processor(it)
|
|
||||||
}
|
|
||||||
) return STOP
|
|
||||||
|
|
||||||
return superTypesScope.processFunctionsByName(name) {
|
|
||||||
|
|
||||||
val overriddenBy = it.isOverridden(seen)
|
|
||||||
if (overriddenBy == null) {
|
|
||||||
processor(it)
|
|
||||||
} else {
|
|
||||||
NEXT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> ProcessorAction): ProcessorAction {
|
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||||
val seen = mutableSetOf<FirCallableSymbol<*>>()
|
val seen = mutableSetOf<FirCallableSymbol<*>>()
|
||||||
@@ -51,7 +29,7 @@ class FirClassUseSiteScope(
|
|||||||
|
|
||||||
return superTypesScope.processPropertiesByName(name) {
|
return superTypesScope.processPropertiesByName(name) {
|
||||||
|
|
||||||
val overriddenBy = it.isOverridden(seen)
|
val overriddenBy = it.getOverridden(seen)
|
||||||
if (overriddenBy == null) {
|
if (overriddenBy == null) {
|
||||||
processor(it)
|
processor(it)
|
||||||
} else {
|
} else {
|
||||||
@@ -59,10 +37,6 @@ class FirClassUseSiteScope(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processClassifiersByName(name: Name, position: FirPosition, processor: (FirClassifierSymbol<*>) -> Boolean): Boolean {
|
|
||||||
return declaredMemberScope.processClassifiersByName(name, position, processor)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class FirSuperTypeScope(
|
|||||||
for (scope in scopes) {
|
for (scope in scopes) {
|
||||||
if (scope.processFunctionsByName(name) { functionSymbol ->
|
if (scope.processFunctionsByName(name) { functionSymbol ->
|
||||||
empty = false
|
empty = false
|
||||||
if (functionSymbol !in accepted && functionSymbol.isOverridden(accepted) == null) {
|
if (functionSymbol !in accepted && functionSymbol.getOverridden(accepted) == null) {
|
||||||
pending += functionSymbol
|
pending += functionSymbol
|
||||||
processor(functionSymbol)
|
processor(functionSymbol)
|
||||||
} else {
|
} else {
|
||||||
@@ -60,7 +60,7 @@ class FirSuperTypeScope(
|
|||||||
for (scope in scopes) {
|
for (scope in scopes) {
|
||||||
if (scope.processPropertiesByName(name) {
|
if (scope.processPropertiesByName(name) {
|
||||||
empty = false
|
empty = false
|
||||||
if (it !in accepted && it.isOverridden(accepted) == null) {
|
if (it !in accepted && it.getOverridden(accepted) == null) {
|
||||||
pending += it
|
pending += it
|
||||||
processor(it)
|
processor(it)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user