diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt index 4faf1358cfc..579f5eae30a 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt @@ -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)) -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt index a8c0614895f..6eb7fed9b37 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt @@ -52,7 +52,7 @@ class QualifiedReceiverTowerDataConsumer>( 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, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt index 1d144025888..4fde5b770d4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerLevels.kt @@ -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 > processElementsByName( token: TowerScopeLevel.Token, 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 \ No newline at end of file +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()) { + is ConeAbbreviatedType -> + expandedType.abbreviationLookupTag.toSymbol(session)?.safeAs()?.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) + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/Scopes.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/Scopes.kt index df139b2ddd6..535162217de 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/Scopes.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/Scopes.kt @@ -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.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()) { - is ConeAbbreviatedType -> - expandedType.abbreviationLookupTag.toSymbol(session)?.safeAs()?.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) - } -} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt index a04f73b0ab3..266cbc96517 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt @@ -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 } } -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTopLevelDeclaredMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTopLevelDeclaredMemberScope.kt index 5c6412a03f7..b24d8066dde 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTopLevelDeclaredMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTopLevelDeclaredMemberScope.kt @@ -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)) { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt index 455663c4f52..750067b7d66 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt @@ -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<*> ->