diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt index 7ae56d0ed1a..677d5e36b43 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.java 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.java.declarations.FirJavaClass import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope import org.jetbrains.kotlin.fir.java.scopes.JavaClassUseSiteMemberScope @@ -111,7 +112,15 @@ class JavaScopeProvider( ) ) } - return FirStaticScope(enhancementScope) + return FirOnlyCallablesScope(FirStaticScope(enhancementScope)) + } + + override fun getNestedClassifierScope(klass: FirClass<*>, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { + return lazyNestedClassifierScope( + klass.classId, + (klass as FirJavaClass).existingNestedClassifierNames, + useSiteSession.firSymbolProvider + ) } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index c4fcd68e393..dca6c782fc9 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -227,7 +227,7 @@ class JavaSymbolProvider( symbol = constructorSymbol this.visibility = visibility this.isPrimary = isPrimary - isInner = !javaClass.isStatic + isInner = javaClass.outerClass != null && !javaClass.isStatic returnTypeRef = buildResolvedTypeRef { type = firSymbol.constructType( classTypeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(), diff --git a/compiler/fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/StubFirScopeProvider.kt b/compiler/fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/StubFirScopeProvider.kt index 543767802dc..870bc558da9 100644 --- a/compiler/fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/StubFirScopeProvider.kt +++ b/compiler/fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/StubFirScopeProvider.kt @@ -27,4 +27,8 @@ object StubFirScopeProvider : FirScopeProvider() { ): FirScope? { return null } + + override fun getNestedClassifierScope(klass: FirClass<*>, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { + return null + } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index e6835634967..81cd75fff68 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -127,6 +127,7 @@ class FirCallResolver( explicitReceiver, arguments, functionCall.safe, + isPotentialQualifierPart = false, typeArguments, session, file, @@ -166,6 +167,7 @@ class FirCallResolver( qualifiedAccess.explicitReceiver, emptyList(), qualifiedAccess.safe, + qualifiedAccess.explicitReceiver is FirResolvedQualifier && qualifiedResolver.isPotentialQualifierPartPosition(), emptyList(), session, file, @@ -314,6 +316,7 @@ class FirCallResolver( explicitReceiver = null, delegatedConstructorCall.arguments, isSafeCall = false, + isPotentialQualifierPart = false, typeArguments = typeArguments, session, file, @@ -364,6 +367,7 @@ class FirCallResolver( callableReferenceAccess.explicitReceiver, emptyList(), false, + isPotentialQualifierPart = false, emptyList(), session, file, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt index 74e70298e8f..cd40290a93d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt @@ -28,6 +28,18 @@ class FirQualifiedNameResolver(components: BodyResolveComponents) : BodyResolveC qualifierPartsToDrop = 0 } + + /** + * NB: 0 if current 'qualifiedAccess.safe || callee.name.isSpecial', 1 if current is fine, 2 if potential qualifier + * a.b.c + * ^ here stack will be ['c', 'b'], so possible + * a.b?.c + * ^ here stack will be ['b'], so impossible + * a?.b.c + * ^ here stack will be [], so impossible + */ + fun isPotentialQualifierPartPosition() = qualifierStack.size > 1 + fun initProcessingQualifiedAccess(qualifiedAccess: FirQualifiedAccess, callee: FirSimpleNamedReference) { if (qualifiedAccess.safe || callee.name.isSpecial) { qualifierStack.clear() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt index e756bb8c7f8..750f787f2a7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt @@ -33,6 +33,7 @@ data class CallInfo( val explicitReceiver: FirExpression?, val arguments: List, val isSafeCall: Boolean, + val isPotentialQualifierPart: Boolean, val typeArguments: List, val session: FirSession, @@ -50,26 +51,18 @@ data class CallInfo( fun noStubReceiver(): CallInfo = if (stubReceiver == null) this else CallInfo( callKind, name, explicitReceiver, arguments, - isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, null + isSafeCall, isPotentialQualifierPart, typeArguments, session, + containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, null ) fun replaceWithVariableAccess(): CallInfo = - CallInfo( - CallKind.VariableAccess, name, explicitReceiver, emptyList(), - isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, stubReceiver - ) + copy(callKind = CallKind.VariableAccess, arguments = emptyList()) fun replaceExplicitReceiver(explicitReceiver: FirExpression?): CallInfo = - CallInfo( - callKind, name, explicitReceiver, arguments, - isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, stubReceiver - ) + copy(explicitReceiver = explicitReceiver) fun withReceiverAsArgument(receiverExpression: FirExpression): CallInfo = - CallInfo( - callKind, name, explicitReceiver, listOf(receiverExpression) + arguments, - isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, stubReceiver - ) + copy(arguments = listOf(receiverExpression) + arguments) } enum class CandidateApplicability { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt index 48f6749b5a0..94d853bded4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt @@ -20,7 +20,6 @@ import org.jetbrains.kotlin.fir.resolve.constructType import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype import org.jetbrains.kotlin.fir.scopes.FirScope -import org.jetbrains.kotlin.fir.scopes.impl.FirQualifierScope import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol @@ -32,7 +31,7 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.name.ClassId interface Receiver { - fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? + } interface ReceiverValue : Receiver { @@ -40,7 +39,7 @@ interface ReceiverValue : Receiver { val receiverExpression: FirExpression - override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? = + fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? = type.scope(useSiteSession, scopeSession) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt index ec54be98922..1361dd99d2d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirTowerResolver.kt @@ -8,8 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.declarations.builder.buildImport -import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport import org.jetbrains.kotlin.fir.declarations.isCompanion import org.jetbrains.kotlin.fir.declarations.isInner import org.jetbrains.kotlin.fir.expressions.FirExpression @@ -22,13 +20,11 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope -import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.scopes.impl.FirStaticScope import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST @@ -79,35 +75,54 @@ class FirTowerResolver( return implicitReceivers } + private suspend fun processQualifierScopes( + manager: TowerResolveManager, + info: CallInfo, qualifierReceiver: QualifierReceiver? + ) { + if (qualifierReceiver == null) return + for ((depth, qualifierScope) in qualifierReceiver.callableScopes().withIndex()) { + manager.processLevel( + ScopeTowerLevel(session, components, qualifierScope, noInnerConstructors = true), + info.noStubReceiver(), TowerGroup.Qualifier(depth) + ) + } + } + + private suspend fun processClassifierScope( + manager: TowerResolveManager, + info: CallInfo, qualifierReceiver: QualifierReceiver?, prioritized: Boolean + ) { + if (qualifierReceiver == null) return + if (info.callKind != CallKind.CallableReference && + qualifierReceiver is ClassQualifierReceiver && + qualifierReceiver.classSymbol != qualifierReceiver.originalSymbol + ) return + val scope = qualifierReceiver.classifierScope() ?: return + manager.processLevel( + ScopeTowerLevel(session, components, scope, noInnerConstructors = true), info.noStubReceiver(), + if (prioritized) TowerGroup.ClassifierPrioritized else TowerGroup.Classifier + ) + } + private suspend fun runResolverForQualifierReceiver( info: CallInfo, collector: CandidateCollector, resolvedQualifier: FirResolvedQualifier, manager: TowerResolveManager ) { - val qualifierScopes = if (resolvedQualifier.classId == null) { - listOf( - FirExplicitSimpleImportingScope( - listOf( - buildResolvedImport { - delegate = buildImport { - importedFqName = FqName.topLevel(info.name) - isAllUnder = false - } - packageFqName = resolvedQualifier.packageFqName - } - ), session, components.scopeSession - ) - ) - } else { - QualifierReceiver(resolvedQualifier).qualifierScopes(session, components.scopeSession) + val qualifierReceiver = createQualifierReceiver(resolvedQualifier, session, components.scopeSession) + + when { + info.isPotentialQualifierPart -> { + processClassifierScope(manager, info, qualifierReceiver, prioritized = true) + processQualifierScopes(manager, info, qualifierReceiver) + } + else -> { + processQualifierScopes(manager, info, qualifierReceiver) + processClassifierScope(manager, info, qualifierReceiver, prioritized = false) + } } - for ((depth, qualifierScope) in qualifierScopes.withIndex()) { - manager.processLevel( - ScopeTowerLevel(session, components, qualifierScope), info.noStubReceiver(), TowerGroup.Qualifier(depth) - ) - } if (resolvedQualifier.classId != null) { val typeRef = resolvedQualifier.typeRef diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/QualifierReceiver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/QualifierReceiver.kt index 04bf1703ec6..8fcd4aa4efa 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/QualifierReceiver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/QualifierReceiver.kt @@ -6,9 +6,8 @@ package org.jetbrains.kotlin.fir.resolve.calls 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.expandedConeType +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.firSymbolProvider @@ -16,9 +15,8 @@ import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider -import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope -import org.jetbrains.kotlin.fir.scopes.impl.FirQualifierScope -import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope +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.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol @@ -27,11 +25,51 @@ import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.name.ClassId import java.util.ArrayDeque -class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : AbstractExplicitReceiver() { + +fun FirClassLikeDeclaration<*>.fullyExpandedClass(useSiteSession: FirSession): FirRegularClass? { + if (this is FirTypeAlias) return this.expandedConeType?.lookupTag?.toSymbol(useSiteSession)?.fir?.fullyExpandedClass(useSiteSession) + if (this is FirRegularClass) return this + error("Not supported: $this") +} + +fun createQualifierReceiver( + explicitReceiver: FirResolvedQualifier, + useSiteSession: FirSession, + scopeSession: ScopeSession, +): QualifierReceiver? { + + val classId = explicitReceiver.classId + when { + classId != null -> { + val classLikeSymbol = useSiteSession.firSymbolProvider.getClassLikeSymbolByFqName(classId) ?: return null + val classSymbol = classLikeSymbol.fir.fullyExpandedClass(useSiteSession)?.symbol ?: return null + return ClassQualifierReceiver(explicitReceiver, classSymbol, classLikeSymbol, useSiteSession, scopeSession) + } + else -> { + return PackageQualifierReceiver(explicitReceiver, useSiteSession) + } + } +} + +abstract class QualifierReceiver(final override val explicitReceiver: FirExpression) : AbstractExplicitReceiver() { + + abstract fun classifierScope(): FirScope? + abstract fun callableScopes(): List +} + +class ClassQualifierReceiver( + explicitReceiver: FirResolvedQualifier, + val classSymbol: FirRegularClassSymbol, + val originalSymbol: FirClassLikeSymbol<*>, + val useSiteSession: FirSession, + val scopeSession: ScopeSession +) : QualifierReceiver(explicitReceiver) { + + private fun collectSuperTypeScopesComposedByDepth( klass: FirClass<*>, useSiteSession: FirSession, - scopeSession: ScopeSession + scopeSession: ScopeSession, ): List { val result = mutableListOf() val provider = klass.scopeProvider @@ -40,7 +78,7 @@ class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : A val queue = ArrayDeque>() queue.addAll( - lookupSuperTypes(klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession).map { it to 1 } + lookupSuperTypes(klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession).map { it to 1 }, ) val visitedSymbols = mutableSetOf() while (queue.isNotEmpty()) { @@ -55,84 +93,58 @@ class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : A ?: continue if (!visitedSymbols.add(superTypeSymbol)) continue val superTypeScope = provider.getStaticMemberScopeForCallables( - superTypeSymbol.fir, useSiteSession, scopeSession + superTypeSymbol.fir, useSiteSession, scopeSession, ) if (superTypeScope != null) { levelScopes += superTypeScope } queue.addAll( lookupSuperTypes( - superTypeSymbol.fir, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession - ).map { it to currentDepth + 1 } + superTypeSymbol.fir, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, + ).map { it to currentDepth + 1 }, ) } return result } - private fun getClassSymbolWithCallableScopes( - classId: ClassId, + private fun getCallableScopes( useSiteSession: FirSession, - scopeSession: ScopeSession - ): Pair?, List> { - val symbol = useSiteSession.firSymbolProvider.getClassLikeSymbolByFqName(classId) ?: return null to emptyList() - if (symbol is FirTypeAliasSymbol) { - val expansionSymbol = symbol.fir.expandedConeType?.lookupTag?.toSymbol(useSiteSession) - if (expansionSymbol != null) { - return getClassSymbolWithCallableScopes(expansionSymbol.classId, useSiteSession, scopeSession) - } - } else { - return (symbol as? FirClassSymbol<*>)?.let { klassSymbol -> - val klass = klassSymbol.fir - klassSymbol to run { - val result = mutableListOf() - val provider = klass.scopeProvider - val klassScope = provider.getStaticMemberScopeForCallables(klass, useSiteSession, scopeSession) - if (klassScope != null) { - result += klassScope - if (provider is KotlinScopeProvider) return@run result - result += collectSuperTypeScopesComposedByDepth(klass, useSiteSession, scopeSession) - } - result - } - } ?: (null to emptyList()) + scopeSession: ScopeSession, + ): List { + val klass = classSymbol.fir + val result = mutableListOf() + val provider = klass.scopeProvider + val klassScope = provider.getStaticMemberScopeForCallables(klass, useSiteSession, scopeSession) + if (klassScope != null) { + result += klassScope + if (provider is KotlinScopeProvider) return result + result += collectSuperTypeScopesComposedByDepth(klass, useSiteSession, scopeSession) } - - return null to emptyList() + return result } - fun qualifierScopes(useSiteSession: FirSession, scopeSession: ScopeSession): List { - val classId = explicitReceiver.classId ?: return emptyList() - - val (classSymbol, callableScopes) = getClassSymbolWithCallableScopes(classId, useSiteSession, scopeSession) - if (classSymbol != null) { - val klass = classSymbol.fir - val classifierScope = if ((klass as? FirRegularClass)?.hasLazyNestedClassifiers == false) { - nestedClassifierScope(klass) - } else { - useSiteSession.firSymbolProvider.getNestedClassifierScope(classId) - } - - return when { - classifierScope == null -> { - callableScopes.map { FirQualifierScope(it, null) } - } - callableScopes.isEmpty() -> { - listOf(FirQualifierScope(null, classifierScope)) - } - else -> { - listOf( - FirQualifierScope(callableScopes.first(), classifierScope) - ) + - callableScopes.drop(1).map { - FirQualifierScope(it, null) - } - } - } - } - return emptyList() + override fun callableScopes(): List { + return getCallableScopes(useSiteSession, scopeSession) } - override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { - return FirCompositeScope(qualifierScopes(useSiteSession, scopeSession).toMutableList()) + override fun classifierScope(): FirScope? { + val klass = classSymbol.fir + return klass.scopeProvider.getNestedClassifierScope(klass, useSiteSession, scopeSession) } -} \ No newline at end of file + +} + + +class PackageQualifierReceiver( + explicitReceiver: FirResolvedQualifier, + useSiteSession: FirSession +) : QualifierReceiver(explicitReceiver) { + val scope = FirPackageMemberScope(explicitReceiver.packageFqName, useSiteSession) + override fun classifierScope(): FirScope? { + return FirOnlyClassifiersScope(scope) + } + + override fun callableScopes(): List { + return listOf(FirOnlyCallablesScope(scope)) + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerGroup.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerGroup.kt index 9f6a68cfabd..1dd53b01df6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerGroup.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerGroup.kt @@ -10,23 +10,27 @@ sealed class TowerGroupKind(private val index: Int) : Comparable object Start : TowerGroupKind(Integer.MIN_VALUE) - class Weakened(depth: Int) : WithDepth(-10, depth) + class Weakened(depth: Int) : WithDepth(-20, depth) + + object ClassifierPrioritized : TowerGroupKind(-10) class Qualifier(depth: Int) : WithDepth(0, depth) - class TopPrioritized(depth: Int) : WithDepth(1, depth) + object Classifier : TowerGroupKind(10) - object Member : TowerGroupKind(2) + class TopPrioritized(depth: Int) : WithDepth(20, depth) - class Local(depth: Int) : WithDepth(3, depth) + object Member : TowerGroupKind(30) - class Implicit(depth: Int) : WithDepth(4, depth) + class Local(depth: Int) : WithDepth(40, depth) - object InvokeExtension : TowerGroupKind(5) + class Implicit(depth: Int) : WithDepth(50, depth) - class Top(depth: Int) : WithDepth(6, depth) + object InvokeExtension : TowerGroupKind(60) - class Static(depth: Int) : WithDepth(7, depth) + class Top(depth: Int) : WithDepth(70, depth) + + class Static(depth: Int) : WithDepth(80, depth) object Last : TowerGroupKind(Integer.MAX_VALUE) @@ -47,8 +51,12 @@ class TowerGroup private constructor(private val kinds: Array) : val Start = kindOf(TowerGroupKind.Start) + val ClassifierPrioritized = kindOf(TowerGroupKind.ClassifierPrioritized) + fun Qualifier(depth: Int) = kindOf(TowerGroupKind.Qualifier(depth)) + val Classifier = kindOf(TowerGroupKind.Classifier) + val Member = kindOf(TowerGroupKind.Member) fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth)) 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 64158e51276..0c63caf75ea 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 @@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope -import org.jetbrains.kotlin.fir.scopes.impl.FirQualifierScope import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeKotlinType @@ -167,7 +166,8 @@ class ScopeTowerLevel( private val bodyResolveComponents: BodyResolveComponents, val scope: FirScope, val extensionReceiver: ReceiverValue? = null, - private val extensionsOnly: Boolean = false + private val extensionsOnly: Boolean = false, + private val noInnerConstructors: Boolean = false ) : SessionBasedTowerLevel(session) { private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: Receiver?): Boolean = when { @@ -198,7 +198,7 @@ class ScopeTowerLevel( name, session, bodyResolveComponents, - noInnerConstructors = scope is FirQualifierScope + noInnerConstructors = noInnerConstructors ) { candidate -> empty = false if (candidate.hasConsistentReceivers(extensionReceiver)) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirAbstractTreeTransformerWithSuperTypes.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirAbstractTreeTransformerWithSuperTypes.kt index 062de3f48ba..ad77a4e1797 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirAbstractTreeTransformerWithSuperTypes.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirAbstractTreeTransformerWithSuperTypes.kt @@ -7,8 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirStatement -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider -import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes +import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt index 7cce5d4984b..9b1a719bf7b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSyntheticCallGenerator.kt @@ -156,6 +156,7 @@ class FirSyntheticCallGenerator( explicitReceiver = null, arguments = arguments, isSafeCall = false, + isPotentialQualifierPart = false, typeArguments = emptyList(), session = session, containingFile = file, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/KotlinScopeProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/KotlinScopeProvider.kt index 0e2afbde7c2..6f825bc79d1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/KotlinScopeProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/KotlinScopeProvider.kt @@ -66,10 +66,14 @@ class KotlinScopeProvider( scopeSession: ScopeSession ): FirScope? { return when (klass.classKind) { - ClassKind.ENUM_CLASS -> FirStaticScope(declaredMemberScope(klass)) + ClassKind.ENUM_CLASS -> FirOnlyCallablesScope(FirStaticScope(declaredMemberScope(klass))) else -> null } } + + override fun getNestedClassifierScope(klass: FirClass<*>, useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { + return nestedClassifierScope(klass) + } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirOnlyCallablesScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirOnlyCallablesScope.kt new file mode 100644 index 00000000000..196159d97c0 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirOnlyCallablesScope.kt @@ -0,0 +1,21 @@ +/* + * 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.scopes.impl + +import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.name.Name + +class FirOnlyCallablesScope(val delegate: FirScope) : FirScope() { + override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { + return delegate.processFunctionsByName(name, processor) + } + + override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { + return delegate.processPropertiesByName(name, processor) + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirOnlyClassifiersScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirOnlyClassifiersScope.kt new file mode 100644 index 00000000000..fcdcb2f6cfc --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirOnlyClassifiersScope.kt @@ -0,0 +1,16 @@ +/* + * 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.scopes.impl + +import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol +import org.jetbrains.kotlin.name.Name + +class FirOnlyClassifiersScope(val delegate: FirScope) : FirScope() { + override fun processClassifiersByName(name: Name, processor: (FirClassifierSymbol<*>) -> Unit) { + return delegate.processClassifiersByName(name, processor) + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirQualifierScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirQualifierScope.kt deleted file mode 100644 index 6eb8200b30f..00000000000 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirQualifierScope.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.scopes.impl - -import org.jetbrains.kotlin.fir.scopes.FirScope -import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.name.Name - -class FirQualifierScope( - private val delegateCallablesScope: FirScope?, - private val delegateClassifiersScope: FirScope? -) : FirScope() { - override fun processClassifiersByName( - name: Name, - processor: (FirClassifierSymbol<*>) -> Unit - ) { - delegateClassifiersScope?.processClassifiersByName(name) { - if (it is FirRegularClassSymbol) { - processor(it) - } - } - } - - override fun processFunctionsByName( - name: Name, - processor: (FirFunctionSymbol<*>) -> Unit - ) { - delegateCallablesScope?.processFunctionsByName(name, processor) - } - - override fun processPropertiesByName( - name: Name, - processor: (FirVariableSymbol<*>) -> Unit - ) { - delegateCallablesScope?.processPropertiesByName(name, processor) - } -} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScopeProvider.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScopeProvider.kt index 10c0c781fe9..0e7c4a4c813 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScopeProvider.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScopeProvider.kt @@ -21,4 +21,10 @@ abstract class FirScopeProvider { useSiteSession: FirSession, scopeSession: ScopeSession ): FirScope? + + abstract fun getNestedClassifierScope( + klass: FirClass<*>, + useSiteSession: FirSession, + scopeSession: ScopeSession + ): FirScope? } diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/apiVersion/typealiasesAsCompanionObjects.fir.kt b/compiler/testData/diagnostics/tests/sourceCompatibility/apiVersion/typealiasesAsCompanionObjects.fir.kt index 3359f19be86..af4f71dad8c 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/apiVersion/typealiasesAsCompanionObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/apiVersion/typealiasesAsCompanionObjects.fir.kt @@ -10,6 +10,6 @@ class C { typealias CA = C val test1 = CA -val test2 = CA.Companion +val test2 = CA.Companion val test3 = CA.x -val test4 = CA.Companion.x +val test4 = CA.Companion.x diff --git a/compiler/testData/diagnostics/tests/typealias/javaStaticMembersViaTypeAlias.fir.kt b/compiler/testData/diagnostics/tests/typealias/javaStaticMembersViaTypeAlias.fir.kt index b95dc1dd3bc..6e37ba13213 100644 --- a/compiler/testData/diagnostics/tests/typealias/javaStaticMembersViaTypeAlias.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/javaStaticMembersViaTypeAlias.fir.kt @@ -34,8 +34,8 @@ val seeAlsoDerivedFoo: String = JDerived.foo() // Referencing nested classes via type alias should be prohibited // (in type position and in expression position) val testNested1: JT.Nested = JT.Nested() -val testNested2: KT.Nested = KT.Nested() -val testNested3: IT.Nested = IT.Nested() +val testNested2: KT.Nested = KT.Nested() +val testNested3: IT.Nested = IT.Nested() val testInner1: JT.Inner = JT.Inner() val testInner2: KT.Inner = KT.Inner() fun testNestedAsTypeArgument1(x: List) {} diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasesInQualifiers.fir.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasesInQualifiers.fir.kt index d1910623e44..3610ef548bf 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasesInQualifiers.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasesInQualifiers.fir.kt @@ -53,7 +53,7 @@ fun foo( test.ClassAlias::func test.ClassSample.Nested::func - test.ClassAlias.Nested::func + test.ClassAlias.Nested::func test.ObjectSample::Nested test.ObjectAlias::Nested @@ -71,5 +71,5 @@ fun foo( test.EnumAlias::func test.EnumSample.Nested::func - test.EnumAlias.Nested::func + test.EnumAlias.Nested::func } \ No newline at end of file