FIR: Move constructor processing from scopes to tower resolvers
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.types
|
||||
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
|
||||
@@ -191,4 +192,4 @@ class ConeIntersectionType(
|
||||
|
||||
fun ConeIntersectionType.mapTypes(func: (ConeKotlinType) -> ConeKotlinType): ConeIntersectionType {
|
||||
return ConeIntersectionType(intersectedTypes.map(func))
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ class QualifiedReceiverTowerDataConsumer<T : AbstractFirBasedSymbol<*>>(
|
||||
if (skipGroup(group, resultCollector)) return ProcessorAction.NEXT
|
||||
if (kind != TowerDataKind.EMPTY) return ProcessorAction.NEXT
|
||||
|
||||
return QualifiedReceiverTowerLevel(session).processElementsByName(
|
||||
return QualifiedReceiverTowerLevel(session, candidateFactory.bodyResolveComponents).processElementsByName(
|
||||
token,
|
||||
name,
|
||||
explicitReceiver,
|
||||
|
||||
@@ -13,8 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorWithJump
|
||||
import org.jetbrains.kotlin.fir.scopes.FirPosition
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
@@ -25,9 +24,13 @@ import org.jetbrains.kotlin.fir.scopes.processClassifiersByNameWithAction
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeAbbreviatedType
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
interface TowerScopeLevel {
|
||||
|
||||
@@ -184,7 +187,7 @@ class ScopeTowerLevel(
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(name) { candidate ->
|
||||
TowerScopeLevel.Token.Functions -> scope.processFunctionsAndConstructorsByName(name, session, ScopeSession()) { candidate ->
|
||||
if (candidate.hasConsistentReceivers(extensionReceiver)) {
|
||||
processor.consumeCandidate(
|
||||
candidate as T, dispatchReceiverValue = candidate.dispatchReceiverValue(),
|
||||
@@ -207,7 +210,10 @@ class ScopeTowerLevel(
|
||||
/**
|
||||
* Handles only statics and top-levels, DOES NOT handle objects/companions members
|
||||
*/
|
||||
class QualifiedReceiverTowerLevel(session: FirSession) : SessionBasedTowerLevel(session) {
|
||||
class QualifiedReceiverTowerLevel(
|
||||
session: FirSession,
|
||||
private val bodyResolveComponents: BodyResolveComponents
|
||||
) : SessionBasedTowerLevel(session) {
|
||||
override fun <T : AbstractFirBasedSymbol<*>> processElementsByName(
|
||||
token: TowerScopeLevel.Token<T>,
|
||||
name: Name,
|
||||
@@ -222,23 +228,29 @@ class QualifiedReceiverTowerLevel(session: FirSession) : SessionBasedTowerLevel(
|
||||
qualifiedReceiver.packageFqName,
|
||||
qualifiedReceiver.relativeClassFqName
|
||||
)
|
||||
), session, ScopeSession()
|
||||
), session, bodyResolveComponents.scopeSession
|
||||
)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return if (token == TowerScopeLevel.Token.Objects) {
|
||||
scope.processClassifiersByNameWithAction(name, FirPosition.OTHER) {
|
||||
val processorForCallables: (FirCallableSymbol<*>) -> ProcessorAction = {
|
||||
val fir = it.fir
|
||||
if (fir is FirCallableMemberDeclaration<*> && fir.isStatic || it.callableId.classId == null) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
processor.consumeCandidate(it as T, null, null)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
}
|
||||
|
||||
return when (token) {
|
||||
TowerScopeLevel.Token.Objects -> scope.processClassifiersByNameWithAction(name, FirPosition.OTHER) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
processor.consumeCandidate(it as T, null, null)
|
||||
}
|
||||
} else {
|
||||
scope.processCallables(name, token.cast()) {
|
||||
val fir = it.fir
|
||||
if (fir is FirCallableMemberDeclaration<*> && fir.isStatic || it.callableId.classId == null) {
|
||||
processor.consumeCandidate(it as T, null, null)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
TowerScopeLevel.Token.Functions -> {
|
||||
scope.processFunctionsAndConstructorsByName(name, session, bodyResolveComponents.scopeSession, processorForCallables)
|
||||
}
|
||||
TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name, processorForCallables)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,4 +265,82 @@ fun FirCallableDeclaration<*>.dispatchReceiverValue(session: FirSession): ClassD
|
||||
return ClassDispatchReceiverValue(regularClass.symbol)
|
||||
}
|
||||
|
||||
private fun FirCallableSymbol<*>.hasExtensionReceiver(): Boolean = this.fir.receiverTypeRef != null
|
||||
private fun FirCallableSymbol<*>.hasExtensionReceiver(): Boolean = this.fir.receiverTypeRef != null
|
||||
|
||||
private fun FirScope.processFunctionsAndConstructorsByName(
|
||||
name: Name,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
processor: (FirCallableSymbol<*>) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
val matchedClassSymbol = getFirstClassifierOrNull(name) as? FirClassLikeSymbol<*>
|
||||
|
||||
if (processConstructors(
|
||||
matchedClassSymbol,
|
||||
processor,
|
||||
session,
|
||||
scopeSession,
|
||||
name
|
||||
).stop()
|
||||
) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
|
||||
return processFunctionsByName(name, processor)
|
||||
}
|
||||
|
||||
private fun FirScope.getFirstClassifierOrNull(name: Name): FirClassifierSymbol<*>? {
|
||||
var result: FirClassifierSymbol<*>? = null
|
||||
processClassifiersByNameWithAction(name, FirPosition.OTHER) {
|
||||
result = it
|
||||
ProcessorAction.STOP
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun finalExpansionName(symbol: FirTypeAliasSymbol, session: FirSession): Name? {
|
||||
return when (val expandedType = symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>()) {
|
||||
is ConeAbbreviatedType ->
|
||||
expandedType.abbreviationLookupTag.toSymbol(session)?.safeAs<FirTypeAliasSymbol>()?.let {
|
||||
finalExpansionName(it, session)
|
||||
}
|
||||
else -> expandedType.lookupTag.classId.shortClassName
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun processConstructors(
|
||||
matchedSymbol: FirClassLikeSymbol<*>?,
|
||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
name: Name
|
||||
): ProcessorAction {
|
||||
try {
|
||||
if (matchedSymbol != null) {
|
||||
val scope = when (matchedSymbol) {
|
||||
is FirTypeAliasSymbol -> matchedSymbol.fir.buildUseSiteScope(session, scopeSession)
|
||||
is FirClassSymbol -> matchedSymbol.fir.buildUseSiteScope(session, scopeSession)
|
||||
}
|
||||
|
||||
|
||||
val constructorName = when (matchedSymbol) {
|
||||
is FirTypeAliasSymbol -> finalExpansionName(matchedSymbol, session) ?: return ProcessorAction.NEXT
|
||||
is FirClassSymbol -> name
|
||||
}
|
||||
|
||||
//TODO: why don't we use declared member scope at this point?
|
||||
if (scope != null && scope.processFunctionsByName(
|
||||
constructorName,
|
||||
processor
|
||||
) == ProcessorAction.STOP
|
||||
) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
}
|
||||
return ProcessorAction.NEXT
|
||||
} catch (e: Throwable) {
|
||||
throw RuntimeException("While processing constructors", e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,18 +8,7 @@ package org.jetbrains.kotlin.fir.scopes
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeAbbreviatedType
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
fun MutableList<FirScope>.addImportingScopes(file: FirFile, session: FirSession, scopeSession: ScopeSession) {
|
||||
this += listOf(
|
||||
@@ -39,48 +28,3 @@ fun FirCompositeScope.addImportingScopes(file: FirFile, session: FirSession, sco
|
||||
scopes.addImportingScopes(file, session, scopeSession)
|
||||
}
|
||||
|
||||
private fun finalExpansionName(symbol: FirTypeAliasSymbol, session: FirSession): Name? {
|
||||
return when (val expandedType = symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>()) {
|
||||
is ConeAbbreviatedType ->
|
||||
expandedType.abbreviationLookupTag.toSymbol(session)?.safeAs<FirTypeAliasSymbol>()?.let {
|
||||
finalExpansionName(it, session)
|
||||
}
|
||||
else -> expandedType.lookupTag.classId.shortClassName
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun processConstructors(
|
||||
matchedSymbol: FirClassLikeSymbol<*>?,
|
||||
processor: (FirFunctionSymbol<*>) -> ProcessorAction,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
name: Name
|
||||
): ProcessorAction {
|
||||
try {
|
||||
if (matchedSymbol != null) {
|
||||
val scope = when (matchedSymbol) {
|
||||
is FirTypeAliasSymbol -> matchedSymbol.fir.buildUseSiteScope(session, scopeSession)
|
||||
is FirClassSymbol -> matchedSymbol.fir.buildUseSiteScope(session, scopeSession)
|
||||
}
|
||||
|
||||
|
||||
val constructorName = when (matchedSymbol) {
|
||||
is FirTypeAliasSymbol -> finalExpansionName(matchedSymbol, session) ?: return ProcessorAction.NEXT
|
||||
is FirClassSymbol -> name
|
||||
}
|
||||
|
||||
//TODO: why don't we use declared member scope at this point?
|
||||
if (scope != null && scope.processFunctionsByName(
|
||||
constructorName,
|
||||
processor
|
||||
) == ProcessorAction.STOP
|
||||
) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
}
|
||||
return ProcessorAction.NEXT
|
||||
} catch (e: Throwable) {
|
||||
throw RuntimeException("While processing constructors", e)
|
||||
}
|
||||
}
|
||||
+2
-16
@@ -13,8 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.TowerScopeLevel
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.processConstructors
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -69,19 +68,6 @@ abstract class FirAbstractImportingScope(
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
} else if (name.isSpecial || name.identifier.isNotEmpty()) {
|
||||
val matchedClass = provider.getClassLikeSymbolByFqName(ClassId(import.packageFqName, name))
|
||||
if (processConstructors(
|
||||
matchedClass,
|
||||
processor,
|
||||
session,
|
||||
scopeSession,
|
||||
name
|
||||
).stop()
|
||||
) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
|
||||
|
||||
val symbols = provider.getTopLevelCallableSymbols(callableId.packageName, callableId.callableName)
|
||||
|
||||
for (symbol in symbols) {
|
||||
@@ -114,4 +100,4 @@ abstract class FirAbstractImportingScope(
|
||||
) { if (it is FirVariableSymbol<*>) processor(it) else ProcessorAction.NEXT }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
-16
@@ -7,38 +7,22 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP
|
||||
import org.jetbrains.kotlin.fir.scopes.processConstructors
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class FirTopLevelDeclaredMemberScope(
|
||||
file: FirFile,
|
||||
session: FirSession,
|
||||
private val scopeSession: ScopeSession,
|
||||
lookupInFir: Boolean = true
|
||||
) : FirAbstractProviderBasedScope(session, lookupInFir) {
|
||||
private val packageFqName = file.packageFqName
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||
val matchedClass = provider.getClassLikeSymbolByFqName(ClassId(packageFqName, name))
|
||||
|
||||
if (processConstructors(
|
||||
matchedClass,
|
||||
processor,
|
||||
session,
|
||||
scopeSession,
|
||||
name
|
||||
).stop()
|
||||
) {
|
||||
return STOP
|
||||
}
|
||||
val symbols = provider.getTopLevelCallableSymbols(packageFqName, name)
|
||||
for (symbol in symbols) {
|
||||
if (symbol is FirFunctionSymbol<*> && !processor(symbol)) {
|
||||
|
||||
@@ -10,8 +10,8 @@ import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
import org.jetbrains.kotlin.fir.resolve.FirProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirDesignatedBodyResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.runResolve
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirTopLevelDeclaredMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
@@ -39,7 +39,7 @@ private fun FirFile.findCallableMember(
|
||||
packageFqName: FqName, klassFqName: FqName?, declName: Name
|
||||
): FirCallableDeclaration<*> {
|
||||
val memberScope =
|
||||
if (klassFqName == null) FirTopLevelDeclaredMemberScope(this, session, ScopeSession())
|
||||
if (klassFqName == null) FirTopLevelDeclaredMemberScope(this, session)
|
||||
else provider.getClassDeclaredMemberScope(ClassId(packageFqName, klassFqName, false))!!
|
||||
var result: FirCallableDeclaration<*>? = null
|
||||
val processor = { symbol: FirCallableSymbol<*> ->
|
||||
|
||||
Reference in New Issue
Block a user