FIR: Explicitlty separate static and member scopes
For Java, they have rather different semantics considering "overrides" and obtaining functions/properties from supertypes See the Java statics implementation
This commit is contained in:
@@ -5,24 +5,21 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.java
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
|
||||
import org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteMemberScope
|
||||
import org.jetbrains.kotlin.fir.java.scopes.JavaOverrideChecker
|
||||
import org.jetbrains.kotlin.fir.java.scopes.*
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
class JavaScopeProvider(
|
||||
val declaredMemberScopeDecorator: (
|
||||
@@ -45,10 +42,11 @@ class JavaScopeProvider(
|
||||
symbol: FirRegularClassSymbol,
|
||||
scopeSession: ScopeSession,
|
||||
visitedSymbols: MutableSet<FirClassLikeSymbol<*>>
|
||||
): JavaClassEnhancementScope {
|
||||
): JavaClassMembersEnhancementScope {
|
||||
return scopeSession.getOrBuild(symbol, JAVA_ENHANCEMENT) {
|
||||
JavaClassEnhancementScope(
|
||||
JavaClassMembersEnhancementScope(
|
||||
useSiteSession,
|
||||
symbol,
|
||||
buildUseSiteMemberScopeWithJavaTypes(symbol.fir, useSiteSession, scopeSession, visitedSymbols)
|
||||
)
|
||||
}
|
||||
@@ -107,24 +105,85 @@ class JavaScopeProvider(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
): FirScope? {
|
||||
if (klass !is FirRegularClass) return null
|
||||
val enhancementScope = scopeSession.getOrBuild(klass.symbol, JAVA_ENHANCEMENT_FOR_STATIC) {
|
||||
val scope = getStaticMemberScopeForCallables(klass, useSiteSession, scopeSession, hashSetOf()) ?: return null
|
||||
return FirOnlyCallablesScope(FirStaticScope(scope))
|
||||
}
|
||||
|
||||
private fun getStaticMemberScopeForCallables(
|
||||
klass: FirClass<*>,
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
visitedClasses: MutableSet<FirRegularClass>
|
||||
): JavaClassStaticEnhancementScope? {
|
||||
if (klass !is FirJavaClass) return null
|
||||
if (!visitedClasses.add(klass)) return null
|
||||
|
||||
return scopeSession.getOrBuild(klass.symbol, JAVA_ENHANCEMENT_FOR_STATIC) {
|
||||
val declaredScope = buildDeclaredMemberScope(klass)
|
||||
val wrappedDeclaredScope = declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession)
|
||||
JavaClassEnhancementScope(
|
||||
useSiteSession, JavaClassUseSiteMemberScope(
|
||||
klass, useSiteSession,
|
||||
superTypesScope = object : FirTypeScope() {
|
||||
override fun processOverriddenFunctions(
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction
|
||||
): ProcessorAction = ProcessorAction.STOP
|
||||
},
|
||||
declaredMemberScope = wrappedDeclaredScope
|
||||
|
||||
val superClassScope = klass.findJavaSuperClass()?.let {
|
||||
(it.scopeProvider as? JavaScopeProvider)
|
||||
?.getStaticMemberScopeForCallables(it, useSiteSession, scopeSession, visitedClasses)
|
||||
} ?: FirTypeScope.Empty
|
||||
|
||||
val superTypesScopes = klass.findClosestJavaSuperTypes().mapNotNull {
|
||||
(it.scopeProvider as? JavaScopeProvider)
|
||||
?.getStaticMemberScopeForCallables(it, useSiteSession, scopeSession, visitedClasses)
|
||||
}
|
||||
|
||||
JavaClassStaticEnhancementScope(
|
||||
useSiteSession,
|
||||
klass.symbol,
|
||||
JavaClassStaticUseSiteScope(
|
||||
useSiteSession,
|
||||
declaredMemberScope = wrappedDeclaredScope,
|
||||
superClassScope, superTypesScopes,
|
||||
klass.javaTypeParameterStack
|
||||
)
|
||||
)
|
||||
}.also {
|
||||
visitedClasses.remove(klass)
|
||||
}
|
||||
return FirOnlyCallablesScope(FirStaticScope(enhancementScope))
|
||||
}
|
||||
|
||||
private tailrec fun FirRegularClass.findJavaSuperClass(): FirRegularClass? {
|
||||
val superClass = superConeTypes.firstNotNullResult {
|
||||
(it.lookupTag.toSymbol(session)?.fir as? FirRegularClass)?.takeIf { superClass ->
|
||||
superClass.classKind == ClassKind.CLASS
|
||||
}
|
||||
} ?: return null
|
||||
|
||||
if (superClass.origin is FirDeclarationOrigin.Java) return superClass
|
||||
|
||||
return superClass.findJavaSuperClass()
|
||||
}
|
||||
|
||||
private fun FirRegularClass.findClosestJavaSuperTypes(): Collection<FirRegularClass> {
|
||||
val result = mutableListOf<FirRegularClass>()
|
||||
DFS.dfs(listOf(this),
|
||||
{ regularClass ->
|
||||
regularClass.superConeTypes.mapNotNull {
|
||||
it.lookupTag.toSymbol(session)?.fir as? FirRegularClass
|
||||
}
|
||||
},
|
||||
object : DFS.AbstractNodeHandler<FirRegularClass, Unit>() {
|
||||
override fun beforeChildren(current: FirRegularClass?): Boolean {
|
||||
if (this@findClosestJavaSuperTypes === current) return true
|
||||
if (current is FirJavaClass) {
|
||||
result.add(current)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun result() {}
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getNestedClassifierScope(klass: FirClass<*>, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? {
|
||||
@@ -136,6 +195,6 @@ class JavaScopeProvider(
|
||||
}
|
||||
}
|
||||
|
||||
private val JAVA_ENHANCEMENT_FOR_STATIC = scopeSessionKey<FirRegularClassSymbol, JavaClassEnhancementScope>()
|
||||
private val JAVA_ENHANCEMENT = scopeSessionKey<FirRegularClassSymbol, JavaClassEnhancementScope>()
|
||||
private val JAVA_ENHANCEMENT_FOR_STATIC = scopeSessionKey<FirRegularClassSymbol, JavaClassStaticEnhancementScope>()
|
||||
private val JAVA_ENHANCEMENT = scopeSessionKey<FirRegularClassSymbol, JavaClassMembersEnhancementScope>()
|
||||
private val JAVA_USE_SITE = scopeSessionKey<FirRegularClassSymbol, JavaClassUseSiteMemberScope>()
|
||||
|
||||
+23
-67
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2020 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.java.scopes
|
||||
package org.jetbrains.kotlin.fir.java.enhancement
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
@@ -21,11 +21,7 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.*
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptor
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
@@ -40,12 +36,11 @@ import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.Jsr305State
|
||||
|
||||
class JavaClassEnhancementScope(
|
||||
class FirSignatureEnhancement(
|
||||
private val owner: FirRegularClass,
|
||||
private val session: FirSession,
|
||||
private val useSiteMemberScope: JavaClassUseSiteMemberScope
|
||||
) : FirTypeScope() {
|
||||
private val owner: FirRegularClass = useSiteMemberScope.symbol.fir
|
||||
|
||||
private val overridden: FirSimpleFunction.() -> List<FirCallableMemberDeclaration<*>>
|
||||
) {
|
||||
private val javaTypeParameterStack: JavaTypeParameterStack =
|
||||
if (owner is FirJavaClass) owner.javaTypeParameterStack else JavaTypeParameterStack.EMPTY
|
||||
|
||||
@@ -57,30 +52,16 @@ class JavaClassEnhancementScope(
|
||||
FirJavaEnhancementContext(session) { null }.copyWithNewDefaultTypeQualifiers(typeQualifierResolver, jsr305State, owner.annotations)
|
||||
|
||||
private val enhancements = mutableMapOf<FirCallableSymbol<*>, FirCallableSymbol<*>>()
|
||||
private val overriddenFunctions = mutableMapOf<FirFunctionSymbol<*>, Collection<FirFunctionSymbol<*>>>()
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
useSiteMemberScope.processPropertiesByName(name) process@{ original ->
|
||||
|
||||
val field = enhancements.getOrPut(original) { enhance(original, name) }
|
||||
processor(field as FirVariableSymbol<*>)
|
||||
}
|
||||
|
||||
return super.processPropertiesByName(name, processor)
|
||||
fun enhancedFunction(
|
||||
function: FirFunctionSymbol<*>,
|
||||
name: Name?
|
||||
): FirFunctionSymbol<*> {
|
||||
return enhancements.getOrPut(function) { enhance(function, name) } as FirFunctionSymbol<*>
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
||||
useSiteMemberScope.processFunctionsByName(name) process@{ original ->
|
||||
|
||||
val function = enhancements.getOrPut(original) { enhance(original, name) }
|
||||
processor(function as FirFunctionSymbol<*>)
|
||||
}
|
||||
|
||||
return super.processFunctionsByName(name, processor)
|
||||
}
|
||||
|
||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||
useSiteMemberScope.processClassifiersByNameWithSubstitution(name, processor)
|
||||
fun enhancedProperty(property: FirVariableSymbol<*>, name: Name): FirVariableSymbol<*> {
|
||||
return enhancements.getOrPut(property) { enhance(property, name) } as FirVariableSymbol<*>
|
||||
}
|
||||
|
||||
private fun enhance(
|
||||
@@ -107,7 +88,7 @@ class JavaClassEnhancementScope(
|
||||
val symbol = FirFieldSymbol(original.callableId)
|
||||
buildJavaField {
|
||||
source = firElement.source
|
||||
session = this@JavaClassEnhancementScope.session
|
||||
session = this@FirSignatureEnhancement.session
|
||||
this.symbol = symbol
|
||||
this.name = name
|
||||
visibility = firElement.visibility
|
||||
@@ -126,7 +107,7 @@ class JavaClassEnhancementScope(
|
||||
firElement.getter.delegate, accessorSymbol.accessorId, accessorSymbol.accessorId.callableName
|
||||
)
|
||||
return buildSyntheticProperty {
|
||||
session = this@JavaClassEnhancementScope.session
|
||||
session = this@FirSignatureEnhancement.session
|
||||
this.name = name
|
||||
symbol = FirAccessorSymbol(accessorSymbol.callableId, accessorSymbol.accessorId)
|
||||
delegateGetter = enhancedFunctionSymbol.fir as FirSimpleFunction
|
||||
@@ -150,7 +131,7 @@ class JavaClassEnhancementScope(
|
||||
}
|
||||
return enhanceMethod(firMethod, original.callableId, name)
|
||||
}
|
||||
|
||||
|
||||
private fun enhanceMethod(
|
||||
firMethod: FirFunction<*>,
|
||||
methodId: CallableId,
|
||||
@@ -169,7 +150,7 @@ class JavaClassEnhancementScope(
|
||||
}
|
||||
}
|
||||
|
||||
val overriddenMembers = (firMethod as? FirSimpleFunction)?.overriddenMembers().orEmpty()
|
||||
val overriddenMembers = (firMethod as? FirSimpleFunction)?.overridden().orEmpty()
|
||||
val hasReceiver = overriddenMembers.any { it.receiverTypeRef != null }
|
||||
|
||||
val newReceiverTypeRef = if (firMethod is FirJavaMethod && hasReceiver) {
|
||||
@@ -196,7 +177,7 @@ class JavaClassEnhancementScope(
|
||||
val (newTypeRef, newDefaultValue) = newInfo
|
||||
buildValueParameter {
|
||||
source = valueParameter.source
|
||||
session = this@JavaClassEnhancementScope.session
|
||||
session = this@FirSignatureEnhancement.session
|
||||
origin = FirDeclarationOrigin.Enhancement
|
||||
returnTypeRef = newTypeRef
|
||||
this.name = valueParameter.name
|
||||
@@ -230,7 +211,7 @@ class JavaClassEnhancementScope(
|
||||
}
|
||||
}.apply {
|
||||
source = firMethod.source
|
||||
session = this@JavaClassEnhancementScope.session
|
||||
session = this@FirSignatureEnhancement.session
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
origin = FirDeclarationOrigin.Enhancement
|
||||
this.valueParameters += newValueParameters
|
||||
@@ -240,7 +221,7 @@ class JavaClassEnhancementScope(
|
||||
is FirJavaMethod -> {
|
||||
FirSimpleFunctionBuilder().apply {
|
||||
source = firMethod.source
|
||||
session = this@JavaClassEnhancementScope.session
|
||||
session = this@FirSignatureEnhancement.session
|
||||
origin = FirDeclarationOrigin.Enhancement
|
||||
returnTypeRef = newReturnTypeRef
|
||||
receiverTypeRef = newReceiverTypeRef
|
||||
@@ -255,12 +236,12 @@ class JavaClassEnhancementScope(
|
||||
else -> throw AssertionError("Unknown Java method to enhance: ${firMethod.render()}")
|
||||
}.apply {
|
||||
annotations += firMethod.annotations
|
||||
}.build().also {
|
||||
overriddenFunctions[it.symbol] = overriddenMembers.mapNotNull { it.symbol as? FirFunctionSymbol<*> }
|
||||
}
|
||||
}.build()
|
||||
|
||||
return function.symbol
|
||||
}
|
||||
|
||||
|
||||
// ================================================================================================
|
||||
|
||||
private fun enhanceReceiverType(
|
||||
@@ -327,17 +308,6 @@ class JavaClassEnhancementScope(
|
||||
|
||||
private val overrideBindCache = mutableMapOf<Name, Map<FirCallableSymbol<*>?, List<FirCallableSymbol<*>>>>()
|
||||
|
||||
private fun FirSimpleFunction.overriddenMembers(): List<FirCallableMemberDeclaration<*>> {
|
||||
val backMap = overrideBindCache.getOrPut(this.name) {
|
||||
useSiteMemberScope.bindOverrides(this.name)
|
||||
useSiteMemberScope
|
||||
.overrideByBase
|
||||
.toList()
|
||||
.groupBy({ (_, key) -> key }, { (value) -> value })
|
||||
}
|
||||
return backMap[this.symbol]?.map { it.fir as FirCallableMemberDeclaration<*> } ?: emptyList()
|
||||
}
|
||||
|
||||
private sealed class TypeInSignature {
|
||||
abstract fun getTypeRef(member: FirCallableMemberDeclaration<*>): FirTypeRef
|
||||
|
||||
@@ -406,18 +376,4 @@ class JavaClassEnhancementScope(
|
||||
containerApplicabilityType
|
||||
)
|
||||
}
|
||||
|
||||
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||
|
||||
useSiteMemberScope.processDeclaredConstructors process@{ original ->
|
||||
|
||||
val function = enhancements.getOrPut(original) { enhance(original, name = null) }
|
||||
processor(function as FirConstructorSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processOverriddenFunctions(
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction
|
||||
): ProcessorAction = doProcessOverriddenFunctions(functionSymbol, processor, overriddenFunctions, useSiteMemberScope)
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.java.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class JavaClassMembersEnhancementScope(
|
||||
session: FirSession,
|
||||
owner: FirRegularClassSymbol,
|
||||
private val useSiteMemberScope: JavaClassUseSiteMemberScope,
|
||||
) : FirTypeScope() {
|
||||
private val overriddenFunctions = mutableMapOf<FirFunctionSymbol<*>, Collection<FirFunctionSymbol<*>>>()
|
||||
|
||||
private val overrideBindCache = mutableMapOf<Name, Map<FirCallableSymbol<*>?, List<FirCallableSymbol<*>>>>()
|
||||
private val signatureEnhancement = FirSignatureEnhancement(owner.fir, session) {
|
||||
overriddenMembers()
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
useSiteMemberScope.processPropertiesByName(name) process@{ original ->
|
||||
processor(signatureEnhancement.enhancedProperty(original, name))
|
||||
}
|
||||
|
||||
return super.processPropertiesByName(name, processor)
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
||||
useSiteMemberScope.processFunctionsByName(name) process@{ original ->
|
||||
val enhancedFunction = signatureEnhancement.enhancedFunction(original, name)
|
||||
|
||||
overriddenFunctions[enhancedFunction] =
|
||||
(enhancedFunction.fir as? FirSimpleFunction)
|
||||
?.overriddenMembers()
|
||||
?.mapNotNull { it.symbol as? FirFunctionSymbol<*> }
|
||||
.orEmpty()
|
||||
|
||||
processor(enhancedFunction)
|
||||
}
|
||||
|
||||
return super.processFunctionsByName(name, processor)
|
||||
}
|
||||
|
||||
private fun FirSimpleFunction.overriddenMembers(): List<FirCallableMemberDeclaration<*>> {
|
||||
val backMap = overrideBindCache.getOrPut(this.name) {
|
||||
useSiteMemberScope.bindOverrides(this.name)
|
||||
useSiteMemberScope
|
||||
.overrideByBase
|
||||
.toList()
|
||||
.groupBy({ (_, key) -> key }, { (value) -> value })
|
||||
}
|
||||
return backMap[this.symbol]?.map { it.fir as FirCallableMemberDeclaration<*> } ?: emptyList()
|
||||
}
|
||||
|
||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||
useSiteMemberScope.processClassifiersByNameWithSubstitution(name, processor)
|
||||
}
|
||||
|
||||
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||
useSiteMemberScope.processDeclaredConstructors process@{ original ->
|
||||
val function = signatureEnhancement.enhancedFunction(original, name = null)
|
||||
processor(function as FirConstructorSymbol)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processOverriddenFunctions(
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction
|
||||
): ProcessorAction = doProcessOverriddenFunctions(functionSymbol, processor, overriddenFunctions, useSiteMemberScope)
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.java.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.FirSignatureEnhancement
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class JavaClassStaticEnhancementScope(
|
||||
session: FirSession,
|
||||
owner: FirRegularClassSymbol,
|
||||
private val useSiteStaticScope: FirScope,
|
||||
) : FirScope() {
|
||||
private val signatureEnhancement = FirSignatureEnhancement(owner.fir, session) {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
useSiteStaticScope.processPropertiesByName(name) process@{ original ->
|
||||
processor(signatureEnhancement.enhancedProperty(original, name))
|
||||
}
|
||||
|
||||
return super.processPropertiesByName(name, processor)
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
||||
useSiteStaticScope.processFunctionsByName(name) process@{ original ->
|
||||
val enhancedFunction = signatureEnhancement.enhancedFunction(original, name)
|
||||
processor(enhancedFunction)
|
||||
}
|
||||
|
||||
return super.processFunctionsByName(name, processor)
|
||||
}
|
||||
|
||||
override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) {
|
||||
useSiteStaticScope.processClassifiersByNameWithSubstitution(name, processor)
|
||||
}
|
||||
|
||||
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||
useSiteStaticScope.processDeclaredConstructors process@{ original ->
|
||||
val function = signatureEnhancement.enhancedFunction(original, name = null)
|
||||
processor(function as FirConstructorSymbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.java.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.isStatic
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
class JavaClassStaticUseSiteScope internal constructor(
|
||||
session: FirSession,
|
||||
private val declaredMemberScope: FirScope,
|
||||
private val superClassScope: FirScope,
|
||||
private val superTypesScopes: List<FirScope>,
|
||||
javaTypeParameterStack: JavaTypeParameterStack,
|
||||
) : FirScope() {
|
||||
private val functions = hashMapOf<Name, Collection<FirFunctionSymbol<*>>>()
|
||||
private val properties = hashMapOf<Name, Collection<FirVariableSymbol<*>>>()
|
||||
private val overrideChecker = JavaOverrideChecker(session, javaTypeParameterStack)
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
||||
functions.getOrPut(name) {
|
||||
computeFunctions(name)
|
||||
}.forEach(processor)
|
||||
}
|
||||
|
||||
private fun computeFunctions(name: Name): MutableList<FirNamedFunctionSymbol> {
|
||||
val superClassSymbols = mutableListOf<FirNamedFunctionSymbol>()
|
||||
superClassScope.processFunctionsByName(name) {
|
||||
superClassSymbols.addIfNotNull(it as? FirNamedFunctionSymbol)
|
||||
}
|
||||
|
||||
val result = mutableListOf<FirNamedFunctionSymbol>()
|
||||
|
||||
declaredMemberScope.processFunctionsByName(name) l@{ functionSymbol ->
|
||||
if (functionSymbol !is FirNamedFunctionSymbol || !functionSymbol.isStatic) return@l
|
||||
|
||||
result.add(functionSymbol)
|
||||
superClassSymbols.removeAll { superClassSymbol ->
|
||||
overrideChecker.isOverriddenFunction(functionSymbol.fir, superClassSymbol.fir)
|
||||
}
|
||||
}
|
||||
|
||||
result += superClassSymbols
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
return properties.getOrPut(name) {
|
||||
computeProperties(name)
|
||||
}.forEach(processor)
|
||||
|
||||
}
|
||||
|
||||
private fun computeProperties(name: Name): MutableList<FirVariableSymbol<*>> {
|
||||
val result: MutableList<FirVariableSymbol<*>> = mutableListOf()
|
||||
declaredMemberScope.processPropertiesByName(name) l@{ propertySymbol ->
|
||||
if (!propertySymbol.isStatic) return@l
|
||||
result.add(propertySymbol)
|
||||
}
|
||||
|
||||
if (result.isNotEmpty()) return result
|
||||
|
||||
for (superTypesScope in superTypesScopes) {
|
||||
superTypesScope.processPropertiesByName(name) l@{ propertySymbol ->
|
||||
if (!propertySymbol.isStatic) return@l
|
||||
result.add(propertySymbol)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
+7
-12
@@ -15,8 +15,8 @@ import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
import org.jetbrains.kotlin.fir.java.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.AbstractFirUseSiteMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.AbstractFirUseSiteMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
@@ -81,12 +81,12 @@ class JavaClassUseSiteMemberScope(
|
||||
private fun processAccessorFunctionsAndPropertiesByName(
|
||||
propertyName: Name,
|
||||
getterNames: List<Name>,
|
||||
setterName: Name?,
|
||||
processor: (FirVariableSymbol<*>) -> Unit
|
||||
) {
|
||||
val overrideCandidates = mutableSetOf<FirCallableSymbol<*>>()
|
||||
val klass = symbol.fir
|
||||
declaredMemberScope.processPropertiesByName(propertyName) { variableSymbol ->
|
||||
if (variableSymbol.isStatic) return@processPropertiesByName
|
||||
overrideCandidates += variableSymbol
|
||||
processor(variableSymbol)
|
||||
}
|
||||
@@ -106,14 +106,9 @@ class JavaClassUseSiteMemberScope(
|
||||
}
|
||||
|
||||
superTypesScope.processPropertiesByName(propertyName) {
|
||||
val firCallableMember = it.fir as? FirCallableMemberDeclaration<*>
|
||||
if (firCallableMember?.isStatic == true) {
|
||||
processor(it)
|
||||
} else {
|
||||
when (val overriddenBy = it.getOverridden(overrideCandidates)) {
|
||||
null -> processor(it)
|
||||
is FirAccessorSymbol -> processor(overriddenBy)
|
||||
}
|
||||
when (val overriddenBy = it.getOverridden(overrideCandidates)) {
|
||||
null -> processor(it)
|
||||
is FirAccessorSymbol -> processor(overriddenBy)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,11 +141,11 @@ class JavaClassUseSiteMemberScope(
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
// Do not generate accessors at all?
|
||||
if (name.isSpecial) {
|
||||
return processAccessorFunctionsAndPropertiesByName(name, emptyList(), null, processor)
|
||||
return processAccessorFunctionsAndPropertiesByName(name, emptyList(), processor)
|
||||
}
|
||||
val getterNames = FirSyntheticPropertiesScope.possibleGetterNamesByPropertyName(name)
|
||||
val setterName = Name.identifier(SETTER_PREFIX + name.identifier.capitalize())
|
||||
return processAccessorFunctionsAndPropertiesByName(name, getterNames, setterName, processor)
|
||||
return processAccessorFunctionsAndPropertiesByName(name, getterNames, processor)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -69,6 +69,7 @@ class JavaOverrideChecker internal constructor(
|
||||
}
|
||||
|
||||
override fun isOverriddenFunction(overrideCandidate: FirSimpleFunction, baseDeclaration: FirSimpleFunction): Boolean {
|
||||
if (overrideCandidate.isStatic != baseDeclaration.isStatic) return false
|
||||
// NB: overrideCandidate is from Java and has no receiver
|
||||
val receiverTypeRef = baseDeclaration.receiverTypeRef
|
||||
val baseParameterTypes = listOfNotNull(receiverTypeRef) + baseDeclaration.valueParameters.map { it.returnTypeRef }
|
||||
|
||||
Reference in New Issue
Block a user