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 66108c62337..993c31d3e00 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -209,9 +209,7 @@ class FirCallResolver( typeArguments.addAll(qualifiedAccess.typeArguments) resultType = if (classId.isLocal) { typeForQualifierByDeclaration(referencedSymbol.fir, resultType, session) - ?: resultType.resolvedTypeFromPrototype( - session.builtinTypes.unitType.type//StandardClassIds.Unit(symbolProvider).constructType(emptyArray(), isNullable = false) - ) + ?: session.builtinTypes.unitType } else { typeForQualifier(this) } @@ -252,7 +250,8 @@ class FirCallResolver( val result = towerResolver.runResolver( implicitReceiverStack.receiversAsReversed(), info, - collector = CandidateCollector(this, resolutionStageRunner) + collector = CandidateCollector(this, resolutionStageRunner), + manager = TowerResolveManager(towerResolver) ) val bestCandidates = result.bestCandidates() val noSuccessfulCandidates = result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED @@ -316,7 +315,7 @@ class FirCallResolver( fun selectCandidateFromGivenCandidates(call: T, name: Name, candidates: Collection): T where T : FirResolvable, T : FirCall { val result = CandidateCollector(this, resolutionStageRunner) - candidates.forEach { result.consumeCandidate(0, it) } + candidates.forEach { result.consumeCandidate(TowerGroup.Start, it) } val bestCandidates = result.bestCandidates() val reducedCandidates = if (result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED) { bestCandidates.toSet() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index f2c31ec6653..6e3b1c56484 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -325,9 +325,7 @@ fun BodyResolveComponents.typeForQualifier(resolvedQualifier: FirResolvedQualifi } } // TODO: Handle no value type here - return resultType.resolvedTypeFromPrototype( - session.builtinTypes.unitType.type - ) + return session.builtinTypes.unitType } internal fun typeForReifiedParameterReference(parameterReference: FirResolvedReifiedParameterReference): FirTypeRef { @@ -361,7 +359,8 @@ internal fun typeForQualifierByDeclaration(declaration: FirDeclaration, resultTy fun BodyResolveComponents.typeFromCallee(access: T): FirResolvedTypeRef { val makeNullable: Boolean by lazy { if (access is FirQualifiedAccess && access.safe) { - val explicitReceiver = access.explicitReceiver!! + val explicitReceiver = access.explicitReceiver + ?: throw AssertionError("Safe call without explicit receiver: ${access.render()}") val receiverResultType = explicitReceiver.resultType if (receiverResultType is FirResolvedTypeRef) { receiverResultType.type.isNullable 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 61c29e67933..e8cd8dabcae 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 @@ -46,22 +46,28 @@ data class CallInfo( ) { val argumentCount get() = arguments.size + fun noStubReceiver(): CallInfo = + if (stubReceiver == null) this else CallInfo( + callKind, name, explicitReceiver, arguments, + isSafeCall, 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 + isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, stubReceiver ) - fun replaceExplicitReceiver(explicitReceiver: FirExpression): CallInfo = + fun replaceExplicitReceiver(explicitReceiver: FirExpression?): CallInfo = CallInfo( callKind, name, explicitReceiver, arguments, - isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs + isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, stubReceiver ) fun withReceiverAsArgument(receiverExpression: FirExpression): CallInfo = CallInfo( callKind, name, explicitReceiver, listOf(receiverExpression) + arguments, - isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs + isSafeCall, typeArguments, session, containingFile, implicitReceiverStack, expectedType, outerCSBuilder, lhs, stubReceiver ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt index 172ad76ee0c..17b5996439a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateCollector.kt @@ -5,39 +5,34 @@ package org.jetbrains.kotlin.fir.resolve.calls -import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression -import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents -import org.jetbrains.kotlin.fir.resolve.transformQualifiedAccessUsingSmartcastInfo -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.types.isExtensionFunctionType -import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind -import org.jetbrains.kotlin.util.OperatorNameConventions open class CandidateCollector( val components: BodyResolveComponents, - val resolutionStageRunner: ResolutionStageRunner + private val resolutionStageRunner: ResolutionStageRunner ) { - private val groupNumbers = mutableListOf() + private val groupNumbers = mutableListOf() private val candidates = mutableListOf() var currentApplicability = CandidateApplicability.HIDDEN private set + private var currentGroup = TowerGroup.Start + fun newDataSet() { groupNumbers.clear() candidates.clear() currentApplicability = CandidateApplicability.HIDDEN } - open fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability { + open fun consumeCandidate(group: TowerGroup, candidate: Candidate): CandidateApplicability { val applicability = resolutionStageRunner.processCandidate(candidate) if (applicability > currentApplicability) { groupNumbers.clear() candidates.clear() currentApplicability = applicability + currentGroup = group } if (applicability == currentApplicability) { @@ -71,58 +66,3 @@ open class CandidateCollector( } } -// Collects properties that potentially could be invoke receivers, like 'propertyName()', -// and initiates further invoke resolution by adding property-bound invoke consumers -class InvokeReceiverCandidateCollector( - private val towerResolver: FirTowerResolver, - private val invokeCallInfo: CallInfo, - components: BodyResolveComponents, - private val invokeConsumer: AccumulatingTowerDataConsumer, - resolutionStageRunner: ResolutionStageRunner -) : CandidateCollector(components, resolutionStageRunner) { - private fun createBoundInvokeConsumer(boundInvokeCallInfo: CallInfo): TowerDataConsumer { - return createSimpleFunctionConsumer( - components.session, OperatorNameConventions.INVOKE, - boundInvokeCallInfo, components, towerResolver.collector - ) - } - - private fun createExplicitReceiverForInvoke(candidate: Candidate): FirQualifiedAccessExpressionImpl { - val symbol = candidate.symbol as FirCallableSymbol<*> - return FirQualifiedAccessExpressionImpl(null).apply { - calleeReference = FirNamedReferenceWithCandidate( - null, - symbol.callableId.callableName, - candidate - ) - dispatchReceiver = candidate.dispatchReceiverExpression() - typeRef = towerResolver.typeCalculator.tryCalculateReturnType(symbol.firUnsafe()) - } - } - - override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability { - val applicability = super.consumeCandidate(group, candidate) - - if (applicability >= CandidateApplicability.SYNTHETIC_RESOLVED) { - val symbol = candidate.symbol as FirCallableSymbol<*> - val extensionReceiverExpression = candidate.extensionReceiverExpression() - val useExtensionReceiverAsArgument = - symbol.fir.receiverTypeRef == null && - candidate.explicitReceiverKind == ExplicitReceiverKind.EXTENSION_RECEIVER && - symbol.fir.returnTypeRef.isExtensionFunctionType() - val explicitReceiver = createExplicitReceiverForInvoke(candidate).apply { - extensionReceiver = extensionReceiverExpression.takeIf { !useExtensionReceiverAsArgument } ?: FirNoReceiverExpression - }.let { - components.transformQualifiedAccessUsingSmartcastInfo(it) - } - val boundInvokeCallInfo = invokeCallInfo.replaceExplicitReceiver(explicitReceiver).let { - if (useExtensionReceiverAsArgument) it.withReceiverAsArgument(extensionReceiverExpression) - else it - } - - invokeConsumer.addConsumerAndProcessAccumulatedData(createBoundInvokeConsumer(boundInvokeCallInfo)) - } - - return applicability - } -} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt index 944193c4c47..2b3ab1dd206 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt @@ -13,19 +13,30 @@ import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind -class CandidateFactory( +class CandidateFactory private constructor( val bodyResolveComponents: BodyResolveComponents, - private val callInfo: CallInfo + val callInfo: CallInfo, + private val baseSystem: ConstraintStorage ) { - private val baseSystem: ConstraintStorage - - init { - val system = bodyResolveComponents.inferenceComponents.createConstraintSystem() - callInfo.arguments.forEach { - system.addSubsystemFromExpression(it) + companion object { + private fun buildBaseSystem(bodyResolveComponents: BodyResolveComponents, callInfo: CallInfo): ConstraintStorage { + val system = bodyResolveComponents.inferenceComponents.createConstraintSystem() + callInfo.arguments.forEach { + system.addSubsystemFromExpression(it) + } + return system.asReadOnlyStorage() } - baseSystem = system.asReadOnlyStorage() + } + + constructor(bodyResolveComponents: BodyResolveComponents, callInfo: CallInfo) : + this(bodyResolveComponents, callInfo, buildBaseSystem(bodyResolveComponents, callInfo)) + + fun replaceCallInfo(callInfo: CallInfo): CandidateFactory { + if (this.callInfo.arguments.size != callInfo.arguments.size) { + throw AssertionError("Incorrect replacement of call info in CandidateFactory") + } + return CandidateFactory(bodyResolveComponents, callInfo, baseSystem) } fun createCandidate( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt deleted file mode 100644 index a83db76d7cb..00000000000 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConsumerFactories.kt +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.resolve.calls - -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents -import org.jetbrains.kotlin.name.Name - -fun createVariableAndObjectConsumer( - session: FirSession, - name: Name, - callInfo: CallInfo, - bodyResolveComponents: BodyResolveComponents, - resultCollector: CandidateCollector -): TowerDataConsumer { - return PrioritizedTowerDataConsumer( - resultCollector, - createSimpleConsumer( - session, - name, - TowerScopeLevel.Token.Properties, - callInfo, - bodyResolveComponents, - resultCollector - ), - createSimpleConsumer( - session, - name, - TowerScopeLevel.Token.Objects, - callInfo, - bodyResolveComponents, - resultCollector - ) - ) -} - -fun createSimpleFunctionConsumer( - session: FirSession, - name: Name, - callInfo: CallInfo, - bodyResolveComponents: BodyResolveComponents, - resultCollector: CandidateCollector -): TowerDataConsumer { - return createSimpleConsumer( - session, - name, - TowerScopeLevel.Token.Functions, - callInfo, - bodyResolveComponents, - resultCollector - ) -} - -fun createFunctionConsumer( - session: FirSession, - name: Name, - callInfo: CallInfo, - bodyResolveComponents: BodyResolveComponents, - resultCollector: CandidateCollector, - towerResolver: FirTowerResolver -): TowerDataConsumer { - val varCallInfo = callInfo.replaceWithVariableAccess() - return PrioritizedTowerDataConsumer( - resultCollector, - createSimpleConsumer( - session, - name, - TowerScopeLevel.Token.Functions, - callInfo, - bodyResolveComponents, - resultCollector - ), - AccumulatingTowerDataConsumer(resultCollector).apply { - initialConsumer = createSimpleConsumer( - session, - name, - TowerScopeLevel.Token.Properties, - varCallInfo, - bodyResolveComponents, - InvokeReceiverCandidateCollector( - towerResolver, - invokeCallInfo = callInfo, - components = bodyResolveComponents, - invokeConsumer = this, - resolutionStageRunner = resultCollector.resolutionStageRunner - ) - ) - } - ) -} - -fun createSimpleConsumer( - session: FirSession, - name: Name, - token: TowerScopeLevel.Token<*>, - callInfo: CallInfo, - bodyResolveComponents: BodyResolveComponents, - resultCollector: CandidateCollector -): TowerDataConsumer { - val factory = CandidateFactory(bodyResolveComponents, callInfo) - val explicitReceiver = callInfo.explicitReceiver - return if (explicitReceiver != null) { - ExplicitReceiverTowerDataConsumer(session, name, token, qualifierOrExpressionReceiver(explicitReceiver), factory, resultCollector) - } else { - NoExplicitReceiverTowerDataConsumer(session, name, token, factory, resultCollector) - } -} - -fun createCallableReferencesConsumer( - session: FirSession, - name: Name, - callInfo: CallInfo, - bodyResolveComponents: BodyResolveComponents, - resultCollector: CandidateCollector -): TowerDataConsumer { - // TODO: Use SamePriorityConsumer - return PrioritizedTowerDataConsumer( - resultCollector, - createSimpleConsumer(session, name, TowerScopeLevel.Token.Functions, callInfo, bodyResolveComponents, resultCollector), - createSimpleConsumer(session, name, TowerScopeLevel.Token.Properties, callInfo, bodyResolveComponents, resultCollector) - ) -} 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 07e126e8df5..e9811ec0a7a 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 @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner import org.jetbrains.kotlin.fir.declarations.expandedConeType import org.jetbrains.kotlin.fir.declarations.impl.FirClassImpl @@ -17,10 +16,8 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirThisReceiverExpressionImpl import org.jetbrains.kotlin.fir.references.impl.FirImplicitThisReference import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.resolve.* -import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.impl.* -import org.jetbrains.kotlin.fir.scopes.scope import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* @@ -57,9 +54,11 @@ class ClassDispatchReceiverValue(klassSymbol: FirClassSymbol<*>) : ReceiverValue } // TODO: should inherit just Receiver, not ReceiverValue -abstract class AbstractExplicitReceiver : ReceiverValue { +abstract class AbstractExplicitReceiver : Receiver { abstract val explicitReceiver: FirExpression +} +abstract class AbstractExplicitReceiverValue : AbstractExplicitReceiver(), ReceiverValue { override val type: ConeKotlinType get() = explicitReceiver.typeRef.coneTypeSafe() ?: ConeKotlinErrorType("No type calculated for: ${explicitReceiver.renderWithType()}") // TODO: assert here @@ -68,11 +67,6 @@ abstract class AbstractExplicitReceiver : ReceiverValue { get() = explicitReceiver } -fun qualifierOrExpressionReceiver(explicitReceiver: FirExpression): AbstractExplicitReceiver<*> { - if (explicitReceiver is FirResolvedQualifier) return QualifierReceiver(explicitReceiver) - return ExpressionReceiverValue(explicitReceiver) -} - class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : AbstractExplicitReceiver() { private fun getClassSymbolWithCallablesScope( classId: ClassId, @@ -95,7 +89,7 @@ class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : A return null to null } - override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { + fun qualifierScope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { val classId = explicitReceiver.classId ?: return null val (classSymbol, callablesScope) = getClassSymbolWithCallablesScope(classId, useSiteSession, scopeSession) @@ -107,22 +101,21 @@ class QualifierReceiver(override val explicitReceiver: FirResolvedQualifier) : A useSiteSession.firSymbolProvider.getNestedClassifierScope(classId) } - val qualifierScope = FirQualifierScope(callablesScope, classifierScope) - if ((klass as? FirRegularClass)?.companionObject == null) { - return qualifierScope - } - val companionScope = super.scope(useSiteSession, scopeSession) ?: return qualifierScope - return FirCompositeScope(qualifierScope, companionScope) + return FirQualifierScope(callablesScope, classifierScope) } - return super.scope(useSiteSession, scopeSession) + return null + } + + override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirScope? { + return qualifierScope(useSiteSession, scopeSession) } } -private class ExpressionReceiverValue( +internal class ExpressionReceiverValue( override val explicitReceiver: FirExpression -) : AbstractExplicitReceiver(), ReceiverValue +) : AbstractExplicitReceiverValue(), ReceiverValue -abstract class ImplicitReceiverValue>( +sealed class ImplicitReceiverValue>( val boundSymbol: S, type: ConeKotlinType, private val useSiteSession: FirSession, @@ -148,20 +141,29 @@ abstract class ImplicitReceiverValue>( } } -class ImplicitDispatchReceiverValue( +internal enum class ImplicitDispatchReceiverKind { + REGULAR, + COMPANION, + COMPANION_FROM_SUPERTYPE +} + +class ImplicitDispatchReceiverValue internal constructor( boundSymbol: FirClassSymbol<*>, type: ConeKotlinType, useSiteSession: FirSession, - scopeSession: ScopeSession + scopeSession: ScopeSession, + private val kind: ImplicitDispatchReceiverKind = ImplicitDispatchReceiverKind.REGULAR ) : ImplicitReceiverValue>(boundSymbol, type, useSiteSession, scopeSession) { - val implicitCompanionScopes: List = run { - val klass = boundSymbol.fir as? FirRegularClass ?: return@run emptyList() - listOfNotNull(klass.companionObject?.scope(ConeSubstitutor.Empty, useSiteSession, scopeSession)) + - lookupSuperTypes(klass, lookupInterfaces = false, deep = true, useSiteSession = useSiteSession).mapNotNull { - val superClass = (it as? ConeClassLikeType)?.lookupTag?.toSymbol(useSiteSession)?.fir as? FirRegularClass - superClass?.companionObject?.scope(ConeSubstitutor.Empty, useSiteSession, scopeSession) - } - } + internal constructor( + boundSymbol: FirClassSymbol<*>, useSiteSession: FirSession, scopeSession: ScopeSession, kind: ImplicitDispatchReceiverKind + ) : this( + boundSymbol, boundSymbol.constructType(typeArguments = emptyArray(), isNullable = false), + useSiteSession, scopeSession, kind + ) + + val implicitCompanion: Boolean get() = kind != ImplicitDispatchReceiverKind.REGULAR + + val companionFromSupertype: Boolean get() = kind == ImplicitDispatchReceiverKind.COMPANION_FROM_SUPERTYPE } class ImplicitExtensionReceiverValue( 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 2e4493590eb..4ca09b7dea0 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 @@ -1,5 +1,5 @@ /* - * 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. */ @@ -10,396 +10,459 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.impl.FirImportImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedImportImpl +import org.jetbrains.kotlin.fir.declarations.isCompanion import org.jetbrains.kotlin.fir.declarations.isInner +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier -import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents -import org.jetbrains.kotlin.fir.resolve.calls.TowerDataKind.* -import org.jetbrains.kotlin.fir.resolve.transformQualifiedAccessUsingSmartcastInfo import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator -import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe import org.jetbrains.kotlin.fir.scopes.FirScope -import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NONE +import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.impl.FirExplicitSimpleImportingScope import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.scopes.impl.FirStaticScope +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType import org.jetbrains.kotlin.fir.types.coneTypeSafe +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 -import org.jetbrains.kotlin.util.OperatorNameConventions - -enum class TowerDataKind { - EMPTY, // Corresponds to stub tower level which is replaced by receiver-related level - TOWER_LEVEL // Corresponds to real tower level which may process elements itself -} class FirTowerResolver( val typeCalculator: ReturnTypeCalculator, val components: BodyResolveComponents, resolutionStageRunner: ResolutionStageRunner, - val topLevelScopes: List, - val localScopes: List + private val topLevelScopes: List, + private val localScopes: List ) { - val session: FirSession get() = components.session + private val session: FirSession get() = components.session + private val collector = CandidateCollector(components, resolutionStageRunner) + private val manager = TowerResolveManager(this) + private lateinit var implicitReceivers: List - private fun processImplicitReceiver( - towerDataConsumer: TowerDataConsumer, - implicitReceiverValue: ImplicitReceiverValue<*>, - nonEmptyLocalScopes: List, - oldGroup: Int - ): Int { - var group = oldGroup - // Member (no explicit receiver) / extension member (with explicit receiver) access via implicit receiver - // class Foo(val x: Int) { - // fun Bar.baz() {} - // fun test() { x } - // fun test(b: Bar) { b.baz() } - // } - towerDataConsumer.consume( - TOWER_LEVEL, - MemberScopeTowerLevel(session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession), - group++ - ) + private data class ImplicitReceiver(val receiver: ImplicitReceiverValue<*>, val usableAsValue: Boolean, val depth: Int) - // class Foo { - // fun foo(block: Foo.() -> Unit) { - // block() - // } - // } - // invokeExtension on local variable - towerDataConsumer.consume( - EMPTY, - TowerScopeLevel.OnlyImplicitReceiver(implicitReceiverValue), - group++ - ) - //TowerData.OnlyImplicitReceiver(implicitReceiver).process()?.let { return it } - - // Same receiver is dispatch & extension -// class Foo { -// fun Foo.bar() {} -// fun test() { bar() } -// } - towerDataConsumer.consume( - TOWER_LEVEL, - MemberScopeTowerLevel( - session, components, - dispatchReceiver = implicitReceiverValue, - implicitExtensionReceiver = implicitReceiverValue, - scopeSession = components.scopeSession - ), - group++ - ) - - for (scope in nonEmptyLocalScopes) { - // Local scope extensions via implicit receiver - // class Foo { - // fun test() { - // fun Foo.bar() {} - // bar() - // } - // } - towerDataConsumer.consume( - TOWER_LEVEL, - ScopeTowerLevel(session, components, scope, implicitExtensionReceiver = implicitReceiverValue), - group++ - ) - } - - var blockDispatchReceivers = false - - for (implicitDispatchReceiverValue in implicitReceiverValues) { - val implicitScope = implicitDispatchReceiverValue.implicitScope - if (implicitScope != null) { - // Extensions in outer object - // object Outer { - // fun Nested.foo() {} - // class Nested { - // fun test() { foo() } - // } - // } - towerDataConsumer.consume( - TOWER_LEVEL, - ScopeTowerLevel(session, components, implicitScope, implicitExtensionReceiver = implicitReceiverValue), - group++ - ) - } - if (implicitDispatchReceiverValue is ImplicitDispatchReceiverValue) { - val implicitCompanionScopes = implicitDispatchReceiverValue.implicitCompanionScopes - for (implicitCompanionScope in implicitCompanionScopes) { - // Extension in companion - // class My { - // companion object { fun My.foo() {} } - // fun test() { foo() } - // } - towerDataConsumer.consume( - TOWER_LEVEL, - ScopeTowerLevel(session, components, implicitCompanionScope, implicitExtensionReceiver = implicitReceiverValue), - group++ - ) - } - if (blockDispatchReceivers) { - continue - } - if ((implicitDispatchReceiverValue.boundSymbol.fir as? FirRegularClass)?.isInner == false) { - blockDispatchReceivers = true + private fun prepareImplicitReceivers(implicitReceiverValues: List>): List { + var depth = 0 + var firstDispatchValue = true + val explicitCompanions = mutableListOf() + implicitReceivers = implicitReceiverValues.mapNotNull { + val usableAsValue = when (it) { + is ImplicitExtensionReceiverValue -> true + is ImplicitDispatchReceiverValue -> { + val symbol = it.boundSymbol + val klass = symbol.fir as? FirRegularClass + if (!it.implicitCompanion && klass?.isCompanion == true) { + explicitCompanions += klass.symbol + } + if (firstDispatchValue) { + if (!it.implicitCompanion && + klass?.isInner == false && + !symbol.classId.isLocal + ) { + firstDispatchValue = false + } + true + } else { + symbol.fir.classKind == ClassKind.OBJECT + } } } - if (implicitDispatchReceiverValue !== implicitReceiverValue) { - // Two different implicit receivers (dispatch & extension) - // class A - // class B { - // fun A.foo() {} - // } - // fun test(a: A, b: B) { - // with(a) { with(b) { foo() } } - // } - towerDataConsumer.consume( - TOWER_LEVEL, - MemberScopeTowerLevel( - session, components, - scopeSession = components.scopeSession, - dispatchReceiver = implicitDispatchReceiverValue, - implicitExtensionReceiver = implicitReceiverValue - ), - group++ - ) - } + if (it is ImplicitDispatchReceiverValue && it.implicitCompanion && it.boundSymbol in explicitCompanions) null + else ImplicitReceiver(it, usableAsValue, depth++) } - - return group + return implicitReceivers } - private fun processTopLevelScope( - towerDataConsumer: TowerDataConsumer, - topLevelScope: FirScope, - oldGroup: Int, - extensionsOnly: Boolean = false - ): Int { - var group = oldGroup - // Top-level extensions via implicit receiver - // fun Foo.bar() {} - // class Foo { - // fun test() { bar() } - // } - for (implicitReceiverValue in implicitReceiverValues) { - if (towerDataConsumer.consume( - TOWER_LEVEL, - ScopeTowerLevel( - session, components, topLevelScope, - implicitExtensionReceiver = implicitReceiverValue, - extensionsOnly = extensionsOnly - ), - group++ - ) == NONE - ) { - return group - } - } - // Member of top-level scope & importing scope - // val x = 0 - // fun test() { x } - towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, topLevelScope), group++) - return group - } - - fun reset() { - collector.newDataSet() - } - - val collector = CandidateCollector(components, resolutionStageRunner) - private lateinit var towerDataConsumer: TowerDataConsumer - private lateinit var implicitReceiverValues: List> - - private fun towerDataConsumer(info: CallInfo, collector: CandidateCollector): TowerDataConsumer { - return when (info.callKind) { - CallKind.VariableAccess -> { - createVariableAndObjectConsumer(session, info.name, info, components, collector) - } - CallKind.Function -> { - createFunctionConsumer(session, info.name, info, components, collector, this) - } - CallKind.CallableReference -> { - if (info.stubReceiver == null) { - createCallableReferencesConsumer(session, info.name, info, components, collector) - } else { - PrioritizedTowerDataConsumer( - collector, - createCallableReferencesConsumer( - session, info.name, info.replaceExplicitReceiver(info.stubReceiver), components, collector - ), - createCallableReferencesConsumer( - session, info.name, info, components, collector - ) - ) - } - } - else -> throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}") - } - } - - private fun createExplicitReceiverForInvoke(candidate: Candidate): FirQualifiedAccessExpressionImpl { - val symbol = candidate.symbol as FirCallableSymbol<*> - return FirQualifiedAccessExpressionImpl(null).apply { - calleeReference = FirNamedReferenceWithCandidate( - null, - symbol.callableId.callableName, - candidate - ) - dispatchReceiver = candidate.dispatchReceiverExpression() - typeRef = typeCalculator.tryCalculateReturnType(symbol.firUnsafe()) - } - } - - // Only case when qualifiedReceiver is a package (no classId) is handled here - private fun runResolverForFullyQualifiedReceiver( - implicitReceiverValues: List>, + private fun runResolverForQualifierReceiver( info: CallInfo, collector: CandidateCollector, - qualifiedReceiver: FirResolvedQualifier + resolvedQualifier: FirResolvedQualifier, + manager: TowerResolveManager ): CandidateCollector { - val qualifierScope = FirExplicitSimpleImportingScope( - listOf( - FirResolvedImportImpl( - FirImportImpl(null, FqName.topLevel(info.name), false, null), - qualifiedReceiver.packageFqName, - qualifiedReceiver.relativeClassFqName - ) - ), session, components.scopeSession - ) - val candidateFactory = CandidateFactory(components, info) + val qualifierScope = if (resolvedQualifier.classId == null) { + FirExplicitSimpleImportingScope( + listOf( + FirResolvedImportImpl( + FirImportImpl(source = null, importedFqName = FqName.topLevel(info.name), isAllUnder = false, aliasName = null), + resolvedQualifier.packageFqName, + relativeClassName = null + ) + ), session, components.scopeSession + ) + } else { + QualifierReceiver(resolvedQualifier).qualifierScope(session, components.scopeSession) + } - when (info.callKind) { - CallKind.VariableAccess -> { - qualifierScope.processPropertiesByName(info.name) { - collector.consumeCandidate(0, candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER)) + if (qualifierScope != null) { + manager.processLevel( + ScopeTowerLevel(session, components, qualifierScope), info.noStubReceiver(), TowerGroup.Qualifier + ) + if (collector.isSuccess()) return collector + } + + if (resolvedQualifier.classId != null) { + val typeRef = resolvedQualifier.typeRef + // NB: yet built-in Unit is used for "no-value" type + if (info.callKind == CallKind.CallableReference) { + if (info.stubReceiver != null || typeRef !is FirImplicitBuiltinTypeRef) { + runResolverForExpressionReceiver(info, collector, resolvedQualifier, manager) } - qualifierScope.processClassifiersByName(info.name) { - if (it is FirClassSymbol<*> && it.fir.classKind == ClassKind.OBJECT) { - collector.consumeCandidate(0, candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER)) + } else { + if (typeRef !is FirImplicitBuiltinTypeRef) { + runResolverForExpressionReceiver(info, collector, resolvedQualifier, manager) + } + } + } + + manager.processQueuedLevelsForInvoke(groupLimit = TowerGroup.Last) + return collector + } + + private fun runResolverForNoReceiver( + info: CallInfo, + collector: CandidateCollector, + manager: TowerResolveManager + ): CandidateCollector { + val shouldProcessExtensionsBeforeMembers = + info.callKind == CallKind.Function && info.name in HIDES_MEMBERS_NAME_LIST + if (shouldProcessExtensionsBeforeMembers) { + // Special case (extension hides member) + for ((index, topLevelScope) in topLevelScopes.withIndex()) { + for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) { + if (!usableAsValue) continue + manager.processLevel( + ScopeTowerLevel( + session, components, topLevelScope, extensionReceiver = implicitReceiverValue, extensionsOnly = true + ), info, TowerGroup.TopPrioritized(index).Implicit(depth) + ) + if (collector.isSuccess()) return collector + } + } + } + val nonEmptyLocalScopes = mutableListOf() + val emptyTopLevelScopes = mutableSetOf() + for ((index, localScope) in localScopes.withIndex()) { + val result = manager.processLevel( + ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index) + ) + if (collector.isSuccess()) return collector + if (result != ProcessorAction.NONE) { + nonEmptyLocalScopes += localScope + } + } + val implicitReceiverValuesWithEmptyScopes = mutableSetOf>() + for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) { + // NB: companions are processed via implicitReceiverValues! + val parentGroup = TowerGroup.Implicit(depth) + + if (usableAsValue) { + val implicitResult = manager.processLevel( + MemberScopeTowerLevel( + session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession + ), info, parentGroup.Member + ) + if (collector.isSuccess()) return collector + if (implicitResult == ProcessorAction.NONE) { + implicitReceiverValuesWithEmptyScopes += implicitReceiverValue + } + for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) { + manager.processLevel( + ScopeTowerLevel( + session, components, localScope, extensionReceiver = implicitReceiverValue + ), info, parentGroup.Local(localIndex) + ) + if (collector.isSuccess()) return collector + } + for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) { + if (!usable) continue + if (implicitDispatchReceiverValue in implicitReceiverValuesWithEmptyScopes) continue + manager.processLevel( + MemberScopeTowerLevel( + session, + components, + dispatchReceiver = implicitDispatchReceiverValue, + extensionReceiver = implicitReceiverValue, + scopeSession = components.scopeSession + ), info, parentGroup.Implicit(dispatchDepth) + ) + if (collector.isSuccess()) return collector + } + for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) { + if (topLevelScope in emptyTopLevelScopes) continue + val result = manager.processLevel( + ScopeTowerLevel( + session, components, topLevelScope, extensionReceiver = implicitReceiverValue + ), info, parentGroup.Top(topIndex) + ) + if (collector.isSuccess()) return collector + if (result == ProcessorAction.NONE) { + emptyTopLevelScopes += topLevelScope } } } - CallKind.Function -> { - qualifierScope.processFunctionsAndConstructorsByName(info.name, session, components) { - collector.consumeCandidate(0, candidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER)) - } - val invokeReceiverCollector = CandidateCollector(components, components.resolutionStageRunner) - val invokeReceiverCandidateFactory = CandidateFactory( - components, - info.replaceWithVariableAccess() - ) - - qualifierScope.processPropertiesByName(info.name) { - invokeReceiverCollector.consumeCandidate( - 0, invokeReceiverCandidateFactory.createCandidate(it, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER) + if (implicitReceiverValue is ImplicitDispatchReceiverValue) { + val scope = implicitReceiverValue.scope(session, components.scopeSession) + if (scope != null) { + manager.processLevel( + ScopeTowerLevel( + session, + components, + FirStaticScope(scope) + ), info, parentGroup.Static(depth) ) } - if (invokeReceiverCollector.isSuccess()) { - for (invokeReceiverCandidate in invokeReceiverCollector.bestCandidates()) { - val invokeReceiverExpression = createExplicitReceiverForInvoke(invokeReceiverCandidate).let { - components.transformQualifiedAccessUsingSmartcastInfo(it) - } - runResolver( - implicitReceiverValues, - info.copy(explicitReceiver = invokeReceiverExpression, name = OperatorNameConventions.INVOKE), - collector - ) - } - } } - CallKind.CallableReference -> return collector - else -> throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}") } + + for ((index, topLevelScope) in topLevelScopes.withIndex()) { + // NB: this check does not work for variables + // because we do not search for objects if we have extension receiver + if (info.callKind != CallKind.VariableAccess && topLevelScope in emptyTopLevelScopes) continue + manager.processLevel( + ScopeTowerLevel(session, components, topLevelScope), info, TowerGroup.Top(index) + ) + if (collector.isSuccess()) return collector + } + + manager.processQueuedLevelsForInvoke(groupLimit = TowerGroup.Last) return collector } + private fun runResolverForExpressionReceiver( + info: CallInfo, + collector: CandidateCollector, + receiver: FirExpression, + manager: TowerResolveManager + ): CandidateCollector { + val explicitReceiverValue = ExpressionReceiverValue(receiver) + + val shouldProcessExtensionsBeforeMembers = + info.callKind == CallKind.Function && info.name in HIDES_MEMBERS_NAME_LIST + if (shouldProcessExtensionsBeforeMembers) { + // Special case (extension hides member) + for ((index, topLevelScope) in topLevelScopes.withIndex()) { + manager.processLevel( + ScopeTowerLevel( + session, components, topLevelScope, extensionReceiver = explicitReceiverValue, extensionsOnly = true + ), info, TowerGroup.TopPrioritized(index), ExplicitReceiverKind.EXTENSION_RECEIVER + ) + if (collector.isSuccess()) return collector + } + } + + manager.processLevel( + MemberScopeTowerLevel( + session, components, dispatchReceiver = explicitReceiverValue, scopeSession = components.scopeSession + ), info, TowerGroup.Member, ExplicitReceiverKind.DISPATCH_RECEIVER + ) + if (collector.isSuccess()) return collector + + val shouldProcessExplicitReceiverScopeOnly = + info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe() != null + if (shouldProcessExplicitReceiverScopeOnly) { + // Special case (integer literal type) + return collector + } + + val nonEmptyLocalScopes = mutableListOf() + for ((index, localScope) in localScopes.withIndex()) { + manager.enqueueLevelForInvoke( + ScopeTowerLevel(session, components, localScope), info, TowerGroup.Local(index), + InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION + ) + val result = manager.processLevel( + ScopeTowerLevel( + session, components, localScope, extensionReceiver = explicitReceiverValue + ), info, TowerGroup.Local(index), ExplicitReceiverKind.EXTENSION_RECEIVER + ) + if (collector.isSuccess()) return collector + if (result != ProcessorAction.NONE) { + nonEmptyLocalScopes += localScope + } + } + for ((implicitReceiverValue, usableAsValue, depth) in implicitReceivers) { + if (!usableAsValue) continue + // NB: companions are processed via implicitReceiverValues! + val parentGroup = TowerGroup.Implicit(depth) + manager.enqueueLevelForInvoke( + MemberScopeTowerLevel( + session, components, dispatchReceiver = implicitReceiverValue, scopeSession = components.scopeSession + ), info, parentGroup.Member, InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION + ) + manager.processLevel( + MemberScopeTowerLevel( + session, components, + dispatchReceiver = implicitReceiverValue, extensionReceiver = explicitReceiverValue, + scopeSession = components.scopeSession + ), info, parentGroup.Member, ExplicitReceiverKind.EXTENSION_RECEIVER + ) + if (collector.isSuccess()) return collector + for ((localIndex, localScope) in nonEmptyLocalScopes.withIndex()) { + manager.enqueueLevelForInvoke( + ScopeTowerLevel( + session, components, localScope, extensionReceiver = implicitReceiverValue + ), info, parentGroup.Local(localIndex), InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION + ) + } + for ((implicitDispatchReceiverValue, usable, dispatchDepth) in implicitReceivers) { + if (!usable) continue + manager.enqueueLevelForInvoke( + MemberScopeTowerLevel( + session, + components, + dispatchReceiver = implicitDispatchReceiverValue, + extensionReceiver = implicitReceiverValue, + scopeSession = components.scopeSession + ), info, parentGroup.Implicit(dispatchDepth), + InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION + ) + } + for ((topIndex, topLevelScope) in topLevelScopes.withIndex()) { + manager.enqueueLevelForInvoke( + ScopeTowerLevel( + session, components, topLevelScope, extensionReceiver = implicitReceiverValue + ), info, parentGroup.Top(topIndex), InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION + ) + } + } + for ((index, topLevelScope) in topLevelScopes.withIndex()) { + manager.enqueueLevelForInvoke( + ScopeTowerLevel(session, components, topLevelScope), info, TowerGroup.Top(index), + InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION + ) + manager.processLevel( + ScopeTowerLevel( + session, components, topLevelScope, extensionReceiver = explicitReceiverValue + ), info, TowerGroup.Top(index), ExplicitReceiverKind.EXTENSION_RECEIVER + ) + if (collector.isSuccess()) return collector + } + + manager.processQueuedLevelsForInvoke(groupLimit = TowerGroup.Last) + return collector + } + + internal fun enqueueResolverForInvoke( + info: CallInfo, + invokeReceiverValue: ExpressionReceiverValue, + manager: TowerResolveManager + ) { + manager.enqueueLevelForInvoke( + MemberScopeTowerLevel( + session, components, dispatchReceiver = invokeReceiverValue, scopeSession = components.scopeSession + ), info, TowerGroup.Member, + InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER, + ExplicitReceiverKind.DISPATCH_RECEIVER + ) + for ((index, localScope) in localScopes.withIndex()) { + manager.enqueueLevelForInvoke( + ScopeTowerLevel( + session, components, localScope, extensionReceiver = invokeReceiverValue + ), info, TowerGroup.Local(index), + InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER, + ExplicitReceiverKind.EXTENSION_RECEIVER + ) + } + for ((implicitReceiverValue, usable, depth) in implicitReceivers) { + if (!usable) continue + // NB: companions are processed via implicitReceiverValues! + val parentGroup = TowerGroup.Implicit(depth) + manager.enqueueLevelForInvoke( + MemberScopeTowerLevel( + session, components, + dispatchReceiver = implicitReceiverValue, extensionReceiver = invokeReceiverValue, + scopeSession = components.scopeSession + ), info, parentGroup.Member, + InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER, + ExplicitReceiverKind.EXTENSION_RECEIVER + ) + } + for ((index, topLevelScope) in topLevelScopes.withIndex()) { + manager.enqueueLevelForInvoke( + ScopeTowerLevel( + session, components, topLevelScope, extensionReceiver = invokeReceiverValue + ), info, TowerGroup.Top(index), + InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER, + ExplicitReceiverKind.EXTENSION_RECEIVER + ) + } + } + + // Here we already know extension receiver for invoke, and it's stated in info as first argument + internal fun enqueueResolverForBuiltinInvokeExtensionWithExplicitArgument( + info: CallInfo, + invokeReceiverValue: ExpressionReceiverValue, + manager: TowerResolveManager + ) { + manager.enqueueLevelForInvoke( + MemberScopeTowerLevel( + session, components, dispatchReceiver = invokeReceiverValue, + scopeSession = components.scopeSession + ), info, TowerGroup.Member, + InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER, + ExplicitReceiverKind.DISPATCH_RECEIVER + ) + } + + // Here we don't know extension receiver for invoke, assuming it's one of implicit receivers + internal fun enqueueResolverForBuiltinInvokeExtensionWithImplicitArgument( + info: CallInfo, + invokeReceiverValue: ExpressionReceiverValue, + manager: TowerResolveManager + ) { + for ((implicitReceiverValue, usable, depth) in implicitReceivers) { + if (!usable) continue + val parentGroup = TowerGroup.Implicit(depth) + manager.enqueueLevelForInvoke( + MemberScopeTowerLevel( + session, components, dispatchReceiver = invokeReceiverValue, + extensionReceiver = implicitReceiverValue, + implicitExtensionInvokeMode = true, + scopeSession = components.scopeSession + ), info, parentGroup.InvokeExtension, + InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER, + ExplicitReceiverKind.DISPATCH_RECEIVER + ) + } + } + fun runResolver( implicitReceiverValues: List>, info: CallInfo, - collector: CandidateCollector = this.collector + collector: CandidateCollector = this.collector, + manager: TowerResolveManager = this.manager ): CandidateCollector { - this.implicitReceiverValues = implicitReceiverValues - - val receiver = info.explicitReceiver - if (receiver is FirResolvedQualifier && receiver.classId == null) { - return runResolverForFullyQualifiedReceiver(implicitReceiverValues, info, collector, receiver) + // TODO: add flag receiver / non-receiver position + prepareImplicitReceivers(implicitReceiverValues) + val candidateFactory = CandidateFactory(components, info) + manager.candidateFactory = candidateFactory + if (info.callKind == CallKind.CallableReference && info.stubReceiver != null) { + manager.stubReceiverCandidateFactory = candidateFactory.replaceCallInfo(info.replaceExplicitReceiver(info.stubReceiver)) } - - towerDataConsumer = towerDataConsumer(info, collector) - val shouldProcessExtensionsBeforeMembers = - info.callKind == CallKind.Function && info.name in HIDES_MEMBERS_NAME_LIST - val shouldProcessExplicitReceiverScopeOnly = - info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe() != null - - var group = 0 - - // Specific case when extension should be processed before members (Kotlin forEach vs Java forEach) - if (shouldProcessExtensionsBeforeMembers) { - for (topLevelScope in topLevelScopes) { - group = processTopLevelScope(towerDataConsumer, topLevelScope, group, extensionsOnly = true) - } - } - - // Member of explicit receiver' type (this stage does nothing without explicit receiver) - // class Foo(val x: Int) - // fun test(f: Foo) { f.x } - towerDataConsumer.consume(EMPTY, TowerScopeLevel.Empty, group++) - - if (shouldProcessExplicitReceiverScopeOnly) { - return collector - } - - // Member of local scope - // fun test(x: Int) = x - val nonEmptyLocalScopes = mutableListOf() - for (scope in localScopes) { - if (towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, scope), group++) != NONE) { - nonEmptyLocalScopes += scope - } - } - - var blockDispatchReceivers = false - - // Member of implicit receiver' type *and* relevant scope - for (implicitReceiverValue in implicitReceiverValues) { - if (!blockDispatchReceivers || implicitReceiverValue !is ImplicitDispatchReceiverValue) { - // Direct use of implicit receiver (see inside) - group = processImplicitReceiver(towerDataConsumer, implicitReceiverValue, nonEmptyLocalScopes, group) - } - val implicitScope = implicitReceiverValue.implicitScope - if (implicitScope != null) { - // Regular implicit receiver scope (outer objects, statics) - // object Outer { - // val x = 0 - // class Nested { val y = x } - // } - towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, implicitScope), group++) - } - if (implicitReceiverValue is ImplicitDispatchReceiverValue) { - val implicitCompanionScopes = implicitReceiverValue.implicitCompanionScopes - for (implicitCompanionScope in implicitCompanionScopes) { - // Companion scope bound to implicit receiver scope - // class Outer { - // companion object { val x = 0 } - // class Nested { val y = x } - // } - towerDataConsumer.consume(TOWER_LEVEL, ScopeTowerLevel(session, components, implicitCompanionScope), group++) - } - if ((implicitReceiverValue.boundSymbol.fir as? FirRegularClass)?.isInner == false) { - blockDispatchReceivers = true + manager.resultCollector = collector + if (info.callKind == CallKind.Function) { + manager.invokeReceiverCollector = CandidateCollector(components, components.resolutionStageRunner) + manager.invokeReceiverCandidateFactory = CandidateFactory(components, info.replaceWithVariableAccess()) + if (info.explicitReceiver != null) { + with(manager.invokeReceiverCandidateFactory) { + manager.invokeBuiltinExtensionReceiverCandidateFactory = replaceCallInfo(callInfo.replaceExplicitReceiver(null)) } } } - for (topLevelScope in topLevelScopes) { - group = processTopLevelScope(towerDataConsumer, topLevelScope, group) + return when (val receiver = info.explicitReceiver) { + is FirResolvedQualifier -> runResolverForQualifierReceiver(info, collector, receiver, manager) + null -> runResolverForNoReceiver(info, collector, manager) + else -> runResolverForExpressionReceiver(info, collector, receiver, manager) } - - return collector } -} + + fun reset() { + collector.newDataSet() + manager.reset() + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/PostponedArgumentsAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/PostponedArgumentsAnalyzer.kt index d95aa941d54..bce310a4013 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/PostponedArgumentsAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/PostponedArgumentsAnalyzer.kt @@ -74,7 +74,8 @@ class PostponedArgumentsAnalyzer( val callableReferenceAccess = atom.reference atom.analyzed = true - val (candidate, applicability) = atom.resultingCandidate ?: Pair(null, CandidateApplicability.INAPPLICABLE) + val (candidate, applicability) = atom.resultingCandidate + ?: Pair(null, CandidateApplicability.INAPPLICABLE) val namedReference = when { candidate == null || applicability < CandidateApplicability.SYNTHETIC_RESOLVED -> diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt index a680d8f5ea0..d308d82adaf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolverParts.kt @@ -40,14 +40,19 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() { // TODO: add invoke cases when (receiverKind) { NO_EXPLICIT_RECEIVER -> { - if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier) + if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier) { return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER) + } } EXTENSION_RECEIVER, DISPATCH_RECEIVER -> { - if (explicitReceiver == null) return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER) + if (explicitReceiver == null) { + return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER) + } } BOTH_RECEIVERS -> { - if (explicitReceiver == null) return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER) + if (explicitReceiver == null) { + return sink.yieldApplicability(CandidateApplicability.WRONG_RECEIVER) + } // Here we should also check additional invoke receiver } } @@ -284,13 +289,11 @@ internal object CheckVisibility : CheckerStage() { private fun ImplicitReceiverStack.canSeePrivateMemberOf(ownerId: ClassId): Boolean { for (implicitReceiverValue in receiversAsReversed()) { if (implicitReceiverValue !is ImplicitDispatchReceiverValue) continue + if (implicitReceiverValue.companionFromSupertype) continue val boundSymbol = implicitReceiverValue.boundSymbol if (boundSymbol.classId.isSame(ownerId)) { return true } - if (boundSymbol is FirRegularClassSymbol && boundSymbol.fir.companionObject?.symbol?.classId?.isSame(ownerId) == true) { - return true - } } return false } @@ -316,6 +319,7 @@ internal object CheckVisibility : CheckerStage() { val visited = mutableSetOf() for (implicitReceiverValue in receiversAsReversed()) { if (implicitReceiverValue !is ImplicitDispatchReceiverValue) continue + if (implicitReceiverValue.companionFromSupertype) continue val boundSymbol = implicitReceiverValue.boundSymbol val superTypes = boundSymbol.fir.superConeTypes for (superType in superTypes) { 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 deleted file mode 100644 index 146e4a74c3e..00000000000 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerDataConsumers.kt +++ /dev/null @@ -1,266 +0,0 @@ -/* - * 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.resolve.calls - -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.resolve.constructClassType -import org.jetbrains.kotlin.fir.scopes.ProcessorAction -import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol -import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.ConeStarProjection -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind -import org.jetbrains.kotlin.types.AbstractTypeChecker - -abstract class TowerDataConsumer { - abstract val resultCollector: CandidateCollector - - abstract fun consume( - kind: TowerDataKind, - towerScopeLevel: TowerScopeLevel, - group: Int - ): ProcessorAction - - private var stopGroup = Int.MAX_VALUE - - fun skipGroup(group: Int): Boolean { - if (stopGroup == Int.MAX_VALUE && resultCollector.isSuccess()) { - stopGroup = group - } - if (group >= stopGroup) return true - return false - } -} - -class PrioritizedTowerDataConsumer( - override val resultCollector: CandidateCollector, - private vararg val consumers: TowerDataConsumer -) : TowerDataConsumer() { - override fun consume( - kind: TowerDataKind, - towerScopeLevel: TowerScopeLevel, - group: Int - ): ProcessorAction { - if (skipGroup(group)) return ProcessorAction.NEXT - var empty = true - for ((index, consumer) in consumers.withIndex()) { - when (val action = consumer.consume(kind, towerScopeLevel, group * consumers.size + index)) { - ProcessorAction.STOP -> return action - ProcessorAction.NEXT -> empty = false - } - } - return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT - } -} - -// Yet is used exclusively for invokes: -// - initialConsumer consumes property which is invoke receiver -// - additionalConsumers consume invoke calls themselves -class AccumulatingTowerDataConsumer( - override val resultCollector: CandidateCollector -) : TowerDataConsumer() { - lateinit var initialConsumer: TowerDataConsumer - - private val additionalConsumers = mutableListOf() - - private data class TowerData(val kind: TowerDataKind, val level: TowerScopeLevel, val group: Int) - - private val accumulatedTowerData = mutableListOf() - - override fun consume( - kind: TowerDataKind, - towerScopeLevel: TowerScopeLevel, - group: Int - ): ProcessorAction { - if (skipGroup(group)) return ProcessorAction.NEXT - accumulatedTowerData += TowerData(kind, towerScopeLevel, group) - - var empty = true - when (val action = initialConsumer.consume(kind, towerScopeLevel, group)) { - ProcessorAction.STOP -> return action - ProcessorAction.NEXT -> empty = false - } - for (consumer in additionalConsumers) { - when (val action = consumer.consume(kind, towerScopeLevel, group)) { - ProcessorAction.STOP -> return action - ProcessorAction.NEXT -> empty = false - } - } - return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT - } - - fun addConsumerAndProcessAccumulatedData(consumer: TowerDataConsumer): ProcessorAction { - additionalConsumers += consumer - if (accumulatedTowerData.isEmpty()) return ProcessorAction.NEXT - for ((kind, level, group) in accumulatedTowerData.asSequence().take(accumulatedTowerData.size - 1)) { - if (consumer.consume(kind, level, group).stop()) { - return ProcessorAction.STOP - } - } - return ProcessorAction.NEXT - } -} - -class ExplicitReceiverTowerDataConsumer>( - val session: FirSession, - val name: Name, - val token: TowerScopeLevel.Token, - val explicitReceiver: AbstractExplicitReceiver<*>, - val candidateFactory: CandidateFactory, - override val resultCollector: CandidateCollector -) : TowerDataConsumer() { - - companion object { - val defaultPackage = Name.identifier("kotlin") - } - - override fun consume( - kind: TowerDataKind, - towerScopeLevel: TowerScopeLevel, - group: Int - ): ProcessorAction { - if (skipGroup(group)) return ProcessorAction.NEXT - return when (kind) { - TowerDataKind.EMPTY -> { - MemberScopeTowerLevel( - session, resultCollector.components, explicitReceiver, - implicitExtensionReceiver = (towerScopeLevel as? TowerScopeLevel.OnlyImplicitReceiver)?.implicitReceiverValue, - implicitExtensionInvokeMode = towerScopeLevel is TowerScopeLevel.OnlyImplicitReceiver, - scopeSession = candidateFactory.bodyResolveComponents.scopeSession - ).processElementsByName( - token, - name, - explicitReceiver = null, - processor = EmptyKindTowerProcessor(group) - ) - } - TowerDataKind.TOWER_LEVEL -> { - if (token == TowerScopeLevel.Token.Objects) return ProcessorAction.NEXT - towerScopeLevel.processElementsByName( - token, - name, - explicitReceiver = explicitReceiver, - processor = TowerLevelKindTowerProcessor(group) - ) - } - } - } - - - private inner class EmptyKindTowerProcessor(val group: Int) : TowerScopeLevel.TowerScopeLevelProcessor { - override fun consumeCandidate( - symbol: T, - dispatchReceiverValue: ReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, - builtInExtensionFunctionReceiverValue: ReceiverValue? - ) { - resultCollector.consumeCandidate( - group, - candidateFactory.createCandidate( - symbol, - ExplicitReceiverKind.DISPATCH_RECEIVER, - dispatchReceiverValue, - implicitExtensionReceiverValue, - builtInExtensionFunctionReceiverValue - ) - ) - } - } - - private inner class TowerLevelKindTowerProcessor(val group: Int) : TowerScopeLevel.TowerScopeLevelProcessor { - override fun consumeCandidate( - symbol: T, - dispatchReceiverValue: ReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, - builtInExtensionFunctionReceiverValue: ReceiverValue? - ) { - if (symbol is FirNamedFunctionSymbol && symbol.callableId.packageName.startsWith(defaultPackage)) { - val explicitReceiverType = explicitReceiver.type - if (dispatchReceiverValue == null && explicitReceiverType is ConeClassLikeType) { - val declarationReceiverTypeRef = - (symbol as? FirCallableSymbol<*>)?.fir?.receiverTypeRef as? FirResolvedTypeRef - val declarationReceiverType = declarationReceiverTypeRef?.type - if (declarationReceiverType is ConeClassLikeType) { - if (!AbstractTypeChecker.isSubtypeOf( - candidateFactory.bodyResolveComponents.inferenceComponents.ctx, - explicitReceiverType, - declarationReceiverType.lookupTag.constructClassType( - declarationReceiverType.typeArguments.map { ConeStarProjection }.toTypedArray(), - isNullable = true - ) - ) - ) { - return - } - } - } - } - val candidate = candidateFactory.createCandidate( - symbol, - ExplicitReceiverKind.EXTENSION_RECEIVER, - dispatchReceiverValue, - implicitExtensionReceiverValue, - builtInExtensionFunctionReceiverValue - ) - - resultCollector.consumeCandidate( - group, - candidate - ) - } - } -} - -class NoExplicitReceiverTowerDataConsumer>( - val session: FirSession, - val name: Name, - val token: TowerScopeLevel.Token, - val candidateFactory: CandidateFactory, - override val resultCollector: CandidateCollector -) : TowerDataConsumer() { - override fun consume( - kind: TowerDataKind, - towerScopeLevel: TowerScopeLevel, - group: Int - ): ProcessorAction { - if (skipGroup(group)) return ProcessorAction.NEXT - return when (kind) { - - TowerDataKind.TOWER_LEVEL -> { - towerScopeLevel.processElementsByName( - token, - name, - explicitReceiver = null, - processor = TowerLevelProcessorImpl(group) - ) - } - else -> ProcessorAction.NEXT - } - } - - private inner class TowerLevelProcessorImpl(val group: Int) : TowerScopeLevel.TowerScopeLevelProcessor { - override fun consumeCandidate( - symbol: T, - dispatchReceiverValue: ReceiverValue?, - implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, - builtInExtensionFunctionReceiverValue: ReceiverValue? - ) { - resultCollector.consumeCandidate( - group, - candidateFactory.createCandidate( - symbol, - ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, - dispatchReceiverValue, - implicitExtensionReceiverValue, - builtInExtensionFunctionReceiverValue - ) - ) - } - } -} 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 new file mode 100644 index 00000000000..954855c7f2e --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerGroup.kt @@ -0,0 +1,104 @@ +/* + * 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.resolve.calls + +sealed class TowerGroupKind(private val index: Int) : Comparable { + abstract class WithDepth(index: Int, val depth: Int) : TowerGroupKind(index) + + object Start : TowerGroupKind(Integer.MIN_VALUE) + + class Weakened(depth: Int) : WithDepth(-10, depth) + + object Qualifier : TowerGroupKind(0) + + class TopPrioritized(depth: Int) : WithDepth(1, depth) + + object Member : TowerGroupKind(2) + + class Local(depth: Int) : WithDepth(3, depth) + + class Implicit(depth: Int) : WithDepth(4, depth) + + object InvokeExtension : TowerGroupKind(5) + + class Top(depth: Int) : WithDepth(6, depth) + + class Static(depth: Int) : WithDepth(7, depth) + + object Last : TowerGroupKind(Integer.MAX_VALUE) + + override fun compareTo(other: TowerGroupKind): Int { + val indexResult = index.compareTo(other.index) + if (indexResult != 0) return indexResult + if (this is WithDepth && other is WithDepth) { + return depth.compareTo(other.depth) + } + return 0 + } +} + +@Suppress("FunctionName", "unused", "PropertyName") +class TowerGroup private constructor(private val list: List) : Comparable { + companion object { + private fun kindOf(kind: TowerGroupKind): TowerGroup = TowerGroup(listOf(kind)) + + val Start = kindOf(TowerGroupKind.Start) + + val Qualifier = kindOf(TowerGroupKind.Qualifier) + + val Member = kindOf(TowerGroupKind.Member) + + fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth)) + + fun Implicit(depth: Int) = kindOf(TowerGroupKind.Implicit(depth)) + + fun Top(depth: Int) = kindOf(TowerGroupKind.Top(depth)) + + fun TopPrioritized(depth: Int) = kindOf(TowerGroupKind.TopPrioritized(depth)) + + fun Static(depth: Int) = kindOf(TowerGroupKind.Static(depth)) + + val Last = kindOf(TowerGroupKind.Last) + } + + private fun kindOf(kind: TowerGroupKind): TowerGroup = TowerGroup(list + kind) + + fun Weakened(depth: Int) = kindOf(TowerGroupKind.Weakened(depth)) + + val Qualifier get() = kindOf(TowerGroupKind.Qualifier) + + val Member get() = kindOf(TowerGroupKind.Member) + + fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth)) + + fun Implicit(depth: Int) = kindOf(TowerGroupKind.Implicit(depth)) + + val InvokeExtension get() = kindOf(TowerGroupKind.InvokeExtension) + + fun Top(depth: Int) = kindOf(TowerGroupKind.Top(depth)) + + fun Static(depth: Int) = kindOf(TowerGroupKind.Static(depth)) + + override fun compareTo(other: TowerGroup): Int { + var index = 0 + while (index < list.size) { + if (index >= other.list.size) return 1 + when { + list[index] < other.list[index] -> return -1 + list[index] > other.list[index] -> return 1 + } + index++ + } + if (index < other.list.size) return -1 + return 0 + } +} + +fun main() { + println(TowerGroup.Member < TowerGroup.Last) + println(TowerGroup.Member < TowerGroup.Member.Weakened(1)) + println(TowerGroup.Member.Weakened(1) < TowerGroup.Member) +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerInvokeResolveQuery.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerInvokeResolveQuery.kt new file mode 100644 index 00000000000..65a947f04b2 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerInvokeResolveQuery.kt @@ -0,0 +1,25 @@ +/* + * 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.resolve.calls + +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind + +internal class TowerInvokeResolveQuery( + val towerLevel: SessionBasedTowerLevel, + val callInfo: CallInfo, + val explicitReceiverKind: ExplicitReceiverKind, + val group: TowerGroup, + val mode: InvokeResolveMode +) : Comparable { + override fun compareTo(other: TowerInvokeResolveQuery): Int { + return group.compareTo(other.group) + } +} + +enum class InvokeResolveMode { + IMPLICIT_CALL_ON_GIVEN_RECEIVER, + RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION +} \ No newline at end of file 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 255573f6164..741e8c821d9 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 @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirConstructor -import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration -import org.jetbrains.kotlin.fir.declarations.isStatic +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.ScopeSession @@ -18,11 +15,11 @@ import org.jetbrains.kotlin.fir.resolve.withNullability 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 import org.jetbrains.kotlin.fir.types.ConeNullability -import org.jetbrains.kotlin.fir.types.isExtensionFunctionType import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.utils.addToStdlib.cast @@ -39,7 +36,6 @@ interface TowerScopeLevel { fun > processElementsByName( token: Token, name: Name, - explicitReceiver: AbstractExplicitReceiver<*>?, processor: TowerScopeLevelProcessor ): ProcessorAction @@ -51,19 +47,6 @@ interface TowerScopeLevel { builtInExtensionFunctionReceiverValue: ReceiverValue? = null ) } - - abstract class StubTowerScopeLevel : TowerScopeLevel { - override fun > processElementsByName( - token: Token, - name: Name, - explicitReceiver: AbstractExplicitReceiver<*>?, - processor: TowerScopeLevelProcessor - ): ProcessorAction = ProcessorAction.NEXT - } - - object Empty : StubTowerScopeLevel() - - class OnlyImplicitReceiver(val implicitReceiverValue: ImplicitReceiverValue<*>) : StubTowerScopeLevel() } abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel { @@ -77,12 +60,11 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel } } - protected fun FirCallableSymbol<*>.hasConsistentExtensionReceiver(extensionReceiver: ReceiverValue?): Boolean { - return when { - extensionReceiver != null -> hasExtensionReceiver() - else -> fir.receiverTypeRef == null - } + protected fun FirCallableSymbol<*>.hasConsistentExtensionReceiver(extensionReceiver: Receiver?): Boolean { + return (extensionReceiver != null) == hasExtensionReceiver() } + + open fun replaceReceiverValue(receiverValue: ReceiverValue) = this } // This is more like "dispatch receiver-based tower level" @@ -93,73 +75,82 @@ abstract class SessionBasedTowerLevel(val session: FirSession) : TowerScopeLevel // or given implicit or explicit receiver, otherwise class MemberScopeTowerLevel( session: FirSession, - val bodyResolveComponents: BodyResolveComponents, + private val bodyResolveComponents: BodyResolveComponents, val dispatchReceiver: ReceiverValue, - val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null, + val extensionReceiver: ReceiverValue? = null, val implicitExtensionInvokeMode: Boolean = false, val scopeSession: ScopeSession ) : SessionBasedTowerLevel(session) { private fun > processMembers( output: TowerScopeLevel.TowerScopeLevelProcessor, - explicitExtensionReceiver: AbstractExplicitReceiver<*>?, processScopeMembers: FirScope.(processor: (T) -> Unit) -> Unit - ) { - if (implicitExtensionReceiver != null && explicitExtensionReceiver != null) return - val extensionReceiver = implicitExtensionReceiver ?: explicitExtensionReceiver - val scope = dispatchReceiver.scope(session, scopeSession) ?: return + ): ProcessorAction { + var empty = true + val scope = dispatchReceiver.scope(session, scopeSession) ?: return ProcessorAction.NONE scope.processScopeMembers { candidate -> + empty = false if (candidate is FirCallableSymbol<*> && (implicitExtensionInvokeMode || candidate.hasConsistentExtensionReceiver(extensionReceiver)) ) { + val fir = candidate.fir + if ((fir as? FirCallableMemberDeclaration<*>)?.isStatic == true || (fir as? FirConstructor)?.isInner == false) { + return@processScopeMembers + } val dispatchReceiverValue = NotNullableReceiverValue(dispatchReceiver) if (implicitExtensionInvokeMode) { output.consumeCandidate( candidate, dispatchReceiverValue, - implicitExtensionReceiverValue = implicitExtensionReceiver + implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*> ) output.consumeCandidate( candidate, dispatchReceiverValue, implicitExtensionReceiverValue = null, - builtInExtensionFunctionReceiverValue = implicitExtensionReceiver + builtInExtensionFunctionReceiverValue = this.extensionReceiver ) } else { - output.consumeCandidate(candidate, dispatchReceiverValue, implicitExtensionReceiver, null) + output.consumeCandidate(candidate, dispatchReceiverValue, extensionReceiver as? ImplicitReceiverValue<*>) } } else if (candidate is FirClassLikeSymbol<*>) { - output.consumeCandidate(candidate, null, implicitExtensionReceiver, null) + output.consumeCandidate(candidate, null, extensionReceiver as? ImplicitReceiverValue<*>) } } val withSynthetic = FirSyntheticPropertiesScope(session, scope) withSynthetic.processScopeMembers { symbol -> - output.consumeCandidate(symbol, NotNullableReceiverValue(dispatchReceiver), implicitExtensionReceiver, null) + output.consumeCandidate(symbol, NotNullableReceiverValue(dispatchReceiver), extensionReceiver as? ImplicitReceiverValue<*>) } + return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT } override fun > processElementsByName( token: TowerScopeLevel.Token, name: Name, - explicitReceiver: AbstractExplicitReceiver<*>?, processor: TowerScopeLevel.TowerScopeLevelProcessor ): ProcessorAction { val isInvoke = name == OperatorNameConventions.INVOKE && token == TowerScopeLevel.Token.Functions if (implicitExtensionInvokeMode && !isInvoke) { return ProcessorAction.NEXT } - val explicitExtensionReceiver = if (dispatchReceiver == explicitReceiver) null else explicitReceiver - val noInnerConstructors = dispatchReceiver is QualifierReceiver - when (token) { - TowerScopeLevel.Token.Properties -> processMembers(processor, explicitExtensionReceiver) { symbol -> + return when (token) { + TowerScopeLevel.Token.Properties -> processMembers(processor) { symbol -> this.processPropertiesByName(name, symbol.cast()) } - TowerScopeLevel.Token.Functions -> processMembers(processor, explicitExtensionReceiver) { symbol -> - this.processFunctionsAndConstructorsByName(name, session, bodyResolveComponents, noInnerConstructors, symbol.cast()) + TowerScopeLevel.Token.Functions -> processMembers(processor) { symbol -> + this.processFunctionsAndConstructorsByName( + name, session, bodyResolveComponents, + noInnerConstructors = false, processor = symbol.cast() + ) } - TowerScopeLevel.Token.Objects -> processMembers(processor, explicitExtensionReceiver) { symbol -> + TowerScopeLevel.Token.Objects -> processMembers(processor) { symbol -> this.processClassifiersByName(name, symbol.cast()) } } - return ProcessorAction.NEXT + } + + override fun replaceReceiverValue(receiverValue: ReceiverValue): SessionBasedTowerLevel { + return MemberScopeTowerLevel( + session, bodyResolveComponents, receiverValue, extensionReceiver, implicitExtensionInvokeMode, scopeSession + ) } } @@ -174,10 +165,10 @@ class ScopeTowerLevel( session: FirSession, private val bodyResolveComponents: BodyResolveComponents, val scope: FirScope, - val implicitExtensionReceiver: ImplicitReceiverValue<*>? = null, + val extensionReceiver: ReceiverValue? = null, private val extensionsOnly: Boolean = false ) : SessionBasedTowerLevel(session) { - private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: ReceiverValue?): Boolean = + private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: Receiver?): Boolean = when { extensionsOnly && !hasExtensionReceiver() -> false !hasConsistentExtensionReceiver(extensionReceiver) -> false @@ -188,43 +179,43 @@ class ScopeTowerLevel( override fun > processElementsByName( token: TowerScopeLevel.Token, name: Name, - explicitReceiver: AbstractExplicitReceiver<*>?, processor: TowerScopeLevel.TowerScopeLevelProcessor ): ProcessorAction { - if (explicitReceiver != null && implicitExtensionReceiver != null) { - return ProcessorAction.NEXT - } - val extensionReceiver = explicitReceiver ?: implicitExtensionReceiver + var empty = true @Suppress("UNCHECKED_CAST") when (token) { TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name) { candidate -> + empty = false if (candidate.hasConsistentReceivers(extensionReceiver)) { processor.consumeCandidate( candidate as T, dispatchReceiverValue = null, - implicitExtensionReceiverValue = implicitExtensionReceiver + implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*> ) } } TowerScopeLevel.Token.Functions -> scope.processFunctionsAndConstructorsByName( name, session, - bodyResolveComponents + bodyResolveComponents, + noInnerConstructors = scope is FirQualifierScope ) { candidate -> + empty = false if (candidate.hasConsistentReceivers(extensionReceiver)) { processor.consumeCandidate( candidate as T, dispatchReceiverValue = null, - implicitExtensionReceiverValue = implicitExtensionReceiver + implicitExtensionReceiverValue = extensionReceiver as? ImplicitReceiverValue<*> ) } } TowerScopeLevel.Token.Objects -> scope.processClassifiersByName(name) { + empty = false processor.consumeCandidate( it as T, dispatchReceiverValue = null, implicitExtensionReceiverValue = null ) } } - return ProcessorAction.NEXT + return if (empty) ProcessorAction.NONE else ProcessorAction.NEXT } } @@ -246,6 +237,5 @@ fun FirCallableDeclaration<*>.dispatchReceiverValue(session: FirSession): ClassD } private fun FirCallableSymbol<*>.hasExtensionReceiver(): Boolean { - if (fir.receiverTypeRef != null) return true - return fir.returnTypeRef.isExtensionFunctionType() + return fir.receiverTypeRef != null } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerResolveManager.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerResolveManager.kt new file mode 100644 index 00000000000..14f45e1698f --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TowerResolveManager.kt @@ -0,0 +1,306 @@ +/* + * 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.resolve.calls + +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier +import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl +import org.jetbrains.kotlin.fir.resolve.constructClassType +import org.jetbrains.kotlin.fir.resolve.transformQualifiedAccessUsingSmartcastInfo +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe +import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind +import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.util.OperatorNameConventions +import java.util.* + +class TowerResolveManager internal constructor(private val towerResolver: FirTowerResolver) { + private val queue = PriorityQueue() + + private var group = TowerGroup.Start + + lateinit var candidateFactory: CandidateFactory + + lateinit var invokeOnGivenReceiverCandidateFactory: CandidateFactory + + lateinit var invokeReceiverCandidateFactory: CandidateFactory + + lateinit var invokeBuiltinExtensionReceiverCandidateFactory: CandidateFactory + + lateinit var stubReceiverCandidateFactory: CandidateFactory + + lateinit var resultCollector: CandidateCollector + + lateinit var invokeReceiverCollector: CandidateCollector + + private class TowerScopeLevelProcessor( + val explicitReceiver: FirExpression?, + val explicitReceiverKind: ExplicitReceiverKind, + val resultCollector: CandidateCollector, + val candidateFactory: CandidateFactory, + val group: TowerGroup + ) : TowerScopeLevel.TowerScopeLevelProcessor> { + override fun consumeCandidate( + symbol: AbstractFirBasedSymbol<*>, + dispatchReceiverValue: ReceiverValue?, + implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, + builtInExtensionFunctionReceiverValue: ReceiverValue? + ) { + // Check explicit extension receiver for default package members + if (symbol is FirNamedFunctionSymbol && dispatchReceiverValue == null && + (implicitExtensionReceiverValue == null) != (explicitReceiver == null) && + explicitReceiver !is FirResolvedQualifier && + symbol.callableId.packageName.startsWith(defaultPackage) + ) { + val extensionReceiverType = explicitReceiver?.typeRef?.coneTypeSafe() + ?: implicitExtensionReceiverValue?.type as? ConeClassLikeType + if (extensionReceiverType != null) { + val declarationReceiverTypeRef = + (symbol as? FirCallableSymbol<*>)?.fir?.receiverTypeRef as? FirResolvedTypeRef + val declarationReceiverType = declarationReceiverTypeRef?.type + if (declarationReceiverType is ConeClassLikeType) { + if (!AbstractTypeChecker.isSubtypeOf( + candidateFactory.bodyResolveComponents.inferenceComponents.ctx, + extensionReceiverType, + declarationReceiverType.lookupTag.constructClassType( + declarationReceiverType.typeArguments.map { ConeStarProjection }.toTypedArray(), + isNullable = true + ) + ) + ) { + return + } + } + } + } + // --- + resultCollector.consumeCandidate( + group, candidateFactory.createCandidate( + symbol, + explicitReceiverKind, + dispatchReceiverValue, + implicitExtensionReceiverValue, + builtInExtensionFunctionReceiverValue + ) + ) + } + + companion object { + val defaultPackage = Name.identifier("kotlin") + } + } + + + private inner class LevelHandler( + val info: CallInfo, + val explicitReceiverKind: ExplicitReceiverKind, + val group: TowerGroup + ) { + private fun createExplicitReceiverForInvoke(candidate: Candidate): FirQualifiedAccessExpressionImpl { + val symbol = candidate.symbol as FirCallableSymbol<*> + return FirQualifiedAccessExpressionImpl(null).apply { + calleeReference = FirNamedReferenceWithCandidate( + null, + symbol.callableId.callableName, + candidate + ) + dispatchReceiver = candidate.dispatchReceiverExpression() + typeRef = towerResolver.typeCalculator.tryCalculateReturnType(symbol.firUnsafe()) + } + } + + fun SessionBasedTowerLevel.handleLevel(invokeResolveMode: InvokeResolveMode? = null): ProcessorAction { + var result = ProcessorAction.NONE + val processor = + TowerScopeLevelProcessor( + info.explicitReceiver, + explicitReceiverKind, + resultCollector, + // TODO: performance? + if (invokeResolveMode == InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER) { + invokeOnGivenReceiverCandidateFactory + } else candidateFactory, + group + ) + when (info.callKind) { + CallKind.VariableAccess -> { + result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor) + // TODO: more accurate condition, or process properties/object in some other way + if (!resultCollector.isSuccess() && + (this !is ScopeTowerLevel || this.extensionReceiver == null) + ) { + result += processElementsByName(TowerScopeLevel.Token.Objects, info.name, processor) + } + } + CallKind.Function -> { + val invokeBuiltinExtensionMode = + invokeResolveMode == InvokeResolveMode.RECEIVER_FOR_INVOKE_BUILTIN_EXTENSION + if (!invokeBuiltinExtensionMode) { + result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor) + } + if (invokeResolveMode == InvokeResolveMode.IMPLICIT_CALL_ON_GIVEN_RECEIVER || + resultCollector.isSuccess() + ) { + return result + } + + val invokeReceiverProcessor = TowerScopeLevelProcessor( + info.explicitReceiver, + explicitReceiverKind, + invokeReceiverCollector, + if (invokeBuiltinExtensionMode) invokeBuiltinExtensionReceiverCandidateFactory + else invokeReceiverCandidateFactory, + group + ) + invokeReceiverCollector.newDataSet() + result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, invokeReceiverProcessor) + + if (invokeReceiverCollector.isSuccess()) { + for (invokeReceiverCandidate in invokeReceiverCollector.bestCandidates()) { + + val symbol = invokeReceiverCandidate.symbol as FirCallableSymbol<*> + val isExtensionFunctionType = symbol.fir.returnTypeRef.isExtensionFunctionType() + if (invokeBuiltinExtensionMode && !isExtensionFunctionType) { + continue + } + val extensionReceiverExpression = invokeReceiverCandidate.extensionReceiverExpression() + val useImplicitReceiverAsBuiltinInvokeArgument = + !invokeBuiltinExtensionMode && isExtensionFunctionType && + invokeReceiverCandidate.explicitReceiverKind == ExplicitReceiverKind.NO_EXPLICIT_RECEIVER + + val invokeReceiverExpression = createExplicitReceiverForInvoke(invokeReceiverCandidate).let { + if (!invokeBuiltinExtensionMode) { + it.extensionReceiver = extensionReceiverExpression + // NB: this should fix problem in DFA (KT-36014) + it.explicitReceiver = info.explicitReceiver + it.safe = info.isSafeCall + } + towerResolver.components.transformQualifiedAccessUsingSmartcastInfo(it) + } + + val invokeFunctionInfo = + info.copy(explicitReceiver = invokeReceiverExpression, name = OperatorNameConventions.INVOKE).let { + when { + invokeBuiltinExtensionMode -> it.withReceiverAsArgument(info.explicitReceiver!!) + else -> it + } + } + + val explicitReceiver = ExpressionReceiverValue(invokeReceiverExpression) + invokeOnGivenReceiverCandidateFactory = CandidateFactory(towerResolver.components, invokeFunctionInfo) + when { + invokeBuiltinExtensionMode -> { + towerResolver.enqueueResolverForBuiltinInvokeExtensionWithExplicitArgument( + invokeFunctionInfo, explicitReceiver, this@TowerResolveManager + ) + } + useImplicitReceiverAsBuiltinInvokeArgument -> { + towerResolver.enqueueResolverForBuiltinInvokeExtensionWithImplicitArgument( + invokeFunctionInfo, explicitReceiver, this@TowerResolveManager + ) + towerResolver.enqueueResolverForInvoke( + invokeFunctionInfo, explicitReceiver, this@TowerResolveManager + ) + } + else -> { + towerResolver.enqueueResolverForInvoke( + invokeFunctionInfo, explicitReceiver, this@TowerResolveManager + ) + } + } + } + processQueuedLevelsForInvoke() + } + } + CallKind.CallableReference -> { + val stubReceiver = info.stubReceiver + if (stubReceiver != null) { + val stubReceiverValue = ExpressionReceiverValue(stubReceiver) + val stubProcessor = TowerScopeLevelProcessor( + info.explicitReceiver, + if (this is MemberScopeTowerLevel && dispatchReceiver is AbstractExplicitReceiver<*>) { + ExplicitReceiverKind.DISPATCH_RECEIVER + } else { + ExplicitReceiverKind.EXTENSION_RECEIVER + }, + resultCollector, + stubReceiverCandidateFactory, group + ) + val towerLevelWithStubReceiver = replaceReceiverValue(stubReceiverValue) + with(towerLevelWithStubReceiver) { + result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, stubProcessor) + result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, stubProcessor) + } + // NB: we don't perform this for implicit Unit + if (!resultCollector.isSuccess() && info.explicitReceiver?.typeRef !is FirImplicitBuiltinTypeRef) { + result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor) + result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor) + } + } else { + result += processElementsByName(TowerScopeLevel.Token.Functions, info.name, processor) + result += processElementsByName(TowerScopeLevel.Token.Properties, info.name, processor) + } + } + else -> { + throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}") + } + } + return result + } + } + + fun reset() { + queue.clear() + group = TowerGroup.Start + } + + fun processLevel( + towerLevel: SessionBasedTowerLevel, + callInfo: CallInfo, + group: TowerGroup, + explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER + ): ProcessorAction { + assert(group > this.group) { + "Incorrect TowerGroup processing order (c) Mikhail Glukhikh" + } + this.group = group + val result = with(LevelHandler(callInfo, explicitReceiverKind, group)) { + towerLevel.handleLevel() + } + processQueuedLevelsForInvoke() + return result + } + + fun enqueueLevelForInvoke( + towerLevel: SessionBasedTowerLevel, + callInfo: CallInfo, + group: TowerGroup, + mode: InvokeResolveMode, + explicitReceiverKind: ExplicitReceiverKind = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER + ) { + if (callInfo.callKind == CallKind.Function) { + queue.add(TowerInvokeResolveQuery(towerLevel, callInfo, explicitReceiverKind, group, mode)) + } + } + + fun processQueuedLevelsForInvoke(groupLimit: TowerGroup = this.group) { + while (queue.isNotEmpty()) { + if (queue.peek().group > groupLimit) { + break + } + val query = queue.poll() + with(LevelHandler(query.callInfo, query.explicitReceiverKind, query.group)) { + query.towerLevel.handleLevel(invokeResolveMode = query.mode) + } + } + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 034e7ece91d..d404166be8d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -15,8 +15,7 @@ import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.resolve.* -import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue -import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue +import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.calls.extractLambdaInfoFromFunctionalType import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.* @@ -493,8 +492,24 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) type: ConeKotlinType, block: () -> T ): T { + val implicitCompanionValues = mutableListOf>() val implicitReceiverValue = when (owner) { is FirClass<*> -> { + // Questionable: performance + (owner as? FirRegularClass)?.companionObject?.let { companion -> + implicitCompanionValues += ImplicitDispatchReceiverValue( + companion.symbol, session, scopeSession, kind = ImplicitDispatchReceiverKind.COMPANION + ) + } + lookupSuperTypes(owner, lookupInterfaces = false, deep = true, useSiteSession = session).mapNotNull { + val superClass = (it as? ConeClassLikeType)?.lookupTag?.toSymbol(session)?.fir as? FirRegularClass + superClass?.companionObject?.let { companion -> + implicitCompanionValues += ImplicitDispatchReceiverValue( + companion.symbol, session, scopeSession, kind = ImplicitDispatchReceiverKind.COMPANION_FROM_SUPERTYPE + ) + } + } + // --- ImplicitDispatchReceiverValue(owner.symbol, type, session, scopeSession) } is FirFunction<*> -> { @@ -507,9 +522,15 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) throw IllegalArgumentException("Incorrect label & receiver owner: ${owner.javaClass}") } } + for (implicitCompanionValue in implicitCompanionValues.asReversed()) { + implicitReceiverStack.add(null, implicitCompanionValue) + } implicitReceiverStack.add(labelName, implicitReceiverValue) val result = block() implicitReceiverStack.pop(labelName) + for (implicitCompanionValue in implicitCompanionValues) { + implicitReceiverStack.pop(null) + } return result } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index dda6bce71d8..c241879eebf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -14,10 +14,7 @@ import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirFunctionCallImpl import org.jetbrains.kotlin.fir.expressions.impl.FirVariableAssignmentImpl -import org.jetbrains.kotlin.fir.references.FirDelegateFieldReference -import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference -import org.jetbrains.kotlin.fir.references.FirSuperReference -import org.jetbrains.kotlin.fir.references.FirThisReference +import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl import org.jetbrains.kotlin.fir.references.impl.FirExplicitThisReference import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference 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 4b594c03f56..e20fdccdd2b 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 @@ -81,8 +81,6 @@ class KotlinScopeProvider( ): FirScope? { return when (klass.classKind) { ClassKind.ENUM_CLASS -> FirStaticScope(declaredMemberScope(klass)) - // TODO: should be wrapped with FirStaticScope, non-static callables should be processed separately - ClassKind.OBJECT -> getUseSiteMemberScope(klass, ConeSubstitutor.Empty, useSiteSession, scopeSession) else -> null } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStaticScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStaticScope.kt index 903cfe335e6..50a1ce3f34a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStaticScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStaticScope.kt @@ -10,11 +10,18 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.isStatic import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.name.Name class FirStaticScope(private val delegateScope: FirScope) : FirScope() { + override fun processClassifiersByName(name: Name, processor: (FirClassifierSymbol<*>) -> Unit) { + delegateScope.processClassifiersByName(name) { + processor(it) + } + } + override fun processFunctionsByName( name: Name, processor: (FirFunctionSymbol<*>) -> Unit diff --git a/compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt b/compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt new file mode 100644 index 00000000000..6754542d7a0 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt @@ -0,0 +1,30 @@ +package org.jetbrains.kotlin.codegen.range.inExpression + +class CallBasedInExpressionGenerator( + val codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression +) : InExpressionGenerator { + private val resolvedCall = operatorReference.getResolvedCallWithAssert(codegen.bindingContext) + private val isInverted = operatorReference.getReferencedNameElementType() == KtTokens.NOT_IN + + override fun generate(argument: StackValue): BranchedValue = + gen(argument).let { if (isInverted) Invert(it) else it } + + private fun gen(argument: StackValue): BranchedValue = + object : BranchedValue(argument, null, argument.type, Opcodes.IFEQ) { + override fun putSelector(type: Type, kotlinType: KotlinType?, v: InstructionAdapter) { + invokeFunction(v) + coerceTo(type, kotlinType, v) + } + + override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { + invokeFunction(v) + v.visitJumpInsn(if (jumpIfFalse) Opcodes.IFEQ else Opcodes.IFNE, jumpLabel) + } + + private fun invokeFunction(v: InstructionAdapter) { + val result = codegen.invokeFunction(resolvedCall.call, resolvedCall, none()) + result.put(result.type, result.kotlinType, v) + } + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.txt b/compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.txt new file mode 100644 index 00000000000..79fd11b8c5b --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.txt @@ -0,0 +1,64 @@ +FILE: CallBasedInExpressionGenerator.kt + public final class CallBasedInExpressionGenerator : R|class error: Symbol not found, for `InExpressionGenerator`| { + public constructor(codegen: R|class error: Symbol not found, for `ExpressionCodegen`|, operatorReference: R|class error: Symbol not found, for `KtSimpleNameExpression`|): R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator| { + super() + } + + public final val codegen: R|class error: Symbol not found, for `ExpressionCodegen`| = R|/codegen| + public get(): R|class error: Symbol not found, for `ExpressionCodegen`| + + private final val resolvedCall: = R|/operatorReference|.#(R|/codegen|.#) + private get(): + + private final val isInverted: R|kotlin/Boolean| = ==(R|/operatorReference|.#(), #.#) + private get(): R|kotlin/Boolean| + + public final override fun generate(argument: R|class error: Symbol not found, for `StackValue`|): R|class error: Symbol not found, for `BranchedValue`| { + ^generate R?C|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.gen|(R|/argument|).#( = let@fun (): R|class error: Can't resolve when expression| { + when () { + this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.isInverted| -> { + #(#) + } + else -> { + # + } + } + + } + ) + } + + private final fun gen(argument: R|class error: Symbol not found, for `StackValue`|): R|class error: Symbol not found, for `BranchedValue`| { + ^gen object : R|class error: Symbol not found, for `BranchedValue`| { + private constructor(): R|class error: Symbol not found, for `BranchedValue`| { + super(R|/argument|, Null(null), R|/argument|.#, #.#) + } + + public final override fun putSelector(type: R|class error: Symbol not found, for `Type`|, kotlinType: R|class error: Symbol not found, for `KotlinType?`|, v: R|class error: Symbol not found, for `InstructionAdapter`|): R|kotlin/Unit| { + this@R|/anonymous|.R|/anonymous.invokeFunction|(R|/v|) + #(R|/type|, R|/kotlinType|, R|/v|) + } + + public final override fun condJump(jumpLabel: R|class error: Symbol not found, for `Label`|, v: R|class error: Symbol not found, for `InstructionAdapter`|, jumpIfFalse: R|kotlin/Boolean|): R|kotlin/Unit| { + this@R|/anonymous|.R|/anonymous.invokeFunction|(R|/v|) + R|/v|.#(when () { + R|/jumpIfFalse| -> { + #.# + } + else -> { + #.# + } + } + , R|/jumpLabel|) + } + + private final fun invokeFunction(v: R|class error: Symbol not found, for `InstructionAdapter`|): R|kotlin/Unit| { + lval result: = this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.codegen|.#(this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.resolvedCall|.#, this@R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator|.R|org/jetbrains/kotlin/codegen/range/inExpression/CallBasedInExpressionGenerator.resolvedCall|, #()) + R|/result|.#(R|/result|.#, R|/result|.#, R|/v|) + } + + } + + } + + } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.kt b/compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.kt new file mode 100644 index 00000000000..3f73c6112e9 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.kt @@ -0,0 +1,10 @@ +class Factory { + sealed class Function { + object Default + } + + companion object { + val f = Function + val x = Function.Default + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.txt b/compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.txt new file mode 100644 index 00000000000..275b5f6f055 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.txt @@ -0,0 +1,34 @@ +FILE: classifierAccessFromCompanion.kt + public final class Factory : R|kotlin/Any| { + public constructor(): R|Factory| { + super() + } + + public sealed class Function : R|kotlin/Any| { + public constructor(): R|Factory.Function| { + super() + } + + public final object Default : R|kotlin/Any| { + private constructor(): R|Factory.Function.Default| { + super() + } + + } + + } + + public final companion object Companion : R|kotlin/Any| { + private constructor(): R|Factory.Companion| { + super() + } + + public final val f: R|kotlin/Unit| = Q|Factory.Function| + public get(): R|kotlin/Unit| + + public final val x: R|Factory.Function.Default| = Q|Factory.Function.Default| + public get(): R|Factory.Function.Default| + + } + + } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/companion.txt b/compiler/fir/resolve/testData/resolve/expresssions/companion.txt index d1e9297592d..27b77514e9a 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/companion.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/companion.txt @@ -18,7 +18,7 @@ FILE: companion.kt } public final fun bar(): R|kotlin/Unit| { - R|/A.Companion.foo|() + this@R|/A.Companion|.R|/A.Companion.foo|() } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/companionExtension.txt b/compiler/fir/resolve/testData/resolve/expresssions/companionExtension.txt index 93324fcc168..61d6dbe45de 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/companionExtension.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/companionExtension.txt @@ -15,7 +15,7 @@ FILE: companionExtension.kt } public final fun test(): R|kotlin/Unit| { - this@R|/My|.R|/My.Companion.foo|() + (this@R|/My.Companion|, this@R|/My|).R|/My.Companion.foo|() } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/errCallable.kt b/compiler/fir/resolve/testData/resolve/expresssions/errCallable.kt index b9bd7de05e4..4ac3e2c8aa0 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/errCallable.kt +++ b/compiler/fir/resolve/testData/resolve/expresssions/errCallable.kt @@ -9,5 +9,5 @@ class My { } fun Your.foo() { - val x = ::Nested // Still should be error + val x = ::Nested // Still should be error } \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/errCallable.txt b/compiler/fir/resolve/testData/resolve/expresssions/errCallable.txt index 2a0c11a1297..4943d4d9a9f 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/errCallable.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/errCallable.txt @@ -23,5 +23,5 @@ FILE: errCallable.kt } public final fun R|Your|.foo(): R|kotlin/Unit| { - lval x: R|kotlin/reflect/KFunction0| = ::R|/Your.Nested.Nested| + lval x: = ::# } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.kt b/compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.kt new file mode 100644 index 00000000000..a5ba70cba68 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.kt @@ -0,0 +1,13 @@ +open class Base { + companion object { + val some = 0 + } +} + +class Outer { + val codegen = "" + + inner class Inner : Base() { + val c = codegen + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.txt b/compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.txt new file mode 100644 index 00000000000..84e38410f01 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.txt @@ -0,0 +1,36 @@ +FILE: innerWithSuperCompanion.kt + public open class Base : R|kotlin/Any| { + public constructor(): R|Base| { + super() + } + + public final companion object Companion : R|kotlin/Any| { + private constructor(): R|Base.Companion| { + super() + } + + public final val some: R|kotlin/Int| = Int(0) + public get(): R|kotlin/Int| + + } + + } + public final class Outer : R|kotlin/Any| { + public constructor(): R|Outer| { + super() + } + + public final val codegen: R|kotlin/String| = String() + public get(): R|kotlin/String| + + public final inner class Inner : R|Base| { + public constructor(): R|Outer.Inner| { + super() + } + + public final val c: R|kotlin/String| = this@R|/Outer|.R|/Outer.codegen| + public get(): R|kotlin/String| + + } + + } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.kt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.kt new file mode 100644 index 00000000000..a983627d6a8 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.kt @@ -0,0 +1,10 @@ +object X + +class Y { + fun f(op: X.() -> Unit) { + X.op() + + val x = X + x.op() + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.txt new file mode 100644 index 00000000000..e06749e0a33 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.txt @@ -0,0 +1,19 @@ +FILE: extensionOnObject.kt + public final object X : R|kotlin/Any| { + private constructor(): R|X| { + super() + } + + } + public final class Y : R|kotlin/Any| { + public constructor(): R|Y| { + super() + } + + public final fun f(op: R|X.() -> kotlin/Unit|): R|kotlin/Unit| { + R|/op|.R|FakeOverride|(Q|X|) + lval x: R|X| = Q|X| + R|/op|.R|FakeOverride|(R|/x|) + } + + } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/incorrectInvokeReceiver.kt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/incorrectInvokeReceiver.kt index 04963615a7d..26d938dd8d8 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/incorrectInvokeReceiver.kt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/incorrectInvokeReceiver.kt @@ -1,8 +1,10 @@ -fun String.invoke() = this +operator fun String.invoke() = this val some = "" fun sss() { val some = 10 - some() // Should be inapplicable + // Should be resolved to top-level some, + // because with local some invoke isn't applicable + some() } \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/incorrectInvokeReceiver.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/incorrectInvokeReceiver.txt index 96103fb0d58..75bf88e246c 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/incorrectInvokeReceiver.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/incorrectInvokeReceiver.txt @@ -1,10 +1,10 @@ FILE: incorrectInvokeReceiver.kt - public final fun R|kotlin/String|.invoke(): R|kotlin/String| { + public final operator fun R|kotlin/String|.invoke(): R|kotlin/String| { ^invoke this@R|/invoke| } public final val some: R|kotlin/String| = String() public get(): R|kotlin/String| public final fun sss(): R|kotlin/Unit| { lval some: R|kotlin/Int| = Int(10) - #() + R|/some|.R|/invoke|() } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt index 34db4610ae4..e5081adbb98 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt @@ -12,10 +12,11 @@ class Foo { val Buz.foobar: Bar get() = Bar() fun FooBar.chk(buz: Buz) { + // NB: really this example is unresolvable (in old FE too) // local/buz is extension receiver of foobar // this@Foo is dispatch receiver of foobar // Foo/foobar is dispatch receiver of invoke // this@chk is extension receiver of invoke - buz.foobar() + buz.foobar() } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.txt index 8c8ce2b21ad..8a1be596659 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.txt @@ -32,7 +32,7 @@ FILE: threeReceivers.kt } public final fun R|FooBar|.chk(buz: R|Buz|): R|kotlin/Unit| { - ((this@R|/Foo|, R|/buz|).R|/Foo.foobar|, this@R|/Foo.chk|).R|/Bar.invoke|() + R|/buz|.#() } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.kt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.kt new file mode 100644 index 00000000000..f933a1bf3ed --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.kt @@ -0,0 +1,26 @@ +class C + +class B + +class A { + val B.foo: C.() -> Unit get() = null +} + +fun with(arg: T, f: T.() -> R): R = arg.f() + +fun test(a: A, b: B, c: C) { + with(a) { + with(c) { + b.foo(c) + // [this@a,b].foo.invoke(c) + } + with(b) { + c.foo() + // [this@a,this@b].foo.invoke(c) + with(c) { + foo() + // [this@a,this@b].foo.invoke(this@c) + } + } + } +} diff --git a/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.txt b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.txt new file mode 100644 index 00000000000..cbfe92b1d67 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.txt @@ -0,0 +1,44 @@ +FILE: threeReceiversCorrect.kt + public final class C : R|kotlin/Any| { + public constructor(): R|C| { + super() + } + + } + public final class B : R|kotlin/Any| { + public constructor(): R|B| { + super() + } + + } + public final class A : R|kotlin/Any| { + public constructor(): R|A| { + super() + } + + public final val R|B|.foo: R|C.() -> kotlin/Unit| + public get(): R|C.() -> kotlin/Unit| { + ^ Null(null) + } + + } + public final fun with(arg: R|T|, f: R|T.() -> R|): R|R| { + ^with R|/f|.R|FakeOverride|(R|/arg|) + } + public final fun test(a: R|A|, b: R|B|, c: R|C|): R|kotlin/Unit| { + R|/with|(R|/a|, = with@fun R|A|.(): R|kotlin/Unit| { + R|/with|(R|/c|, = with@fun R|C|.(): R|kotlin/Unit| { + (this@R|special/anonymous|, R|/b|).R|/A.foo|.R|FakeOverride|(R|/c|) + } + ) + R|/with|(R|/b|, = with@fun R|B|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|/A.foo|.R|FakeOverride|(R|/c|) + R|/with|(R|/c|, = with@fun R|C|.(): R|kotlin/Unit| { + (this@R|special/anonymous|, this@R|special/anonymous|).R|/A.foo|.R|FakeOverride|(this@R|special/anonymous|) + } + ) + } + ) + } + ) + } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.txt b/compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.txt index c26af7d5396..2ffa96454fd 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.txt @@ -1,5 +1,5 @@ FILE: test.kt public final fun test(): R|kotlin/Unit| { - lval staticReference: R|kotlin/reflect/KMutableProperty1!>| = Q|JavaClass|::R|/JavaClass.staticField| + lval staticReference: R|kotlin/reflect/KMutableProperty0!>| = Q|JavaClass|::R|/JavaClass.staticField| lval nonStaticReference: R|kotlin/reflect/KMutableProperty1!>| = Q|JavaClass|::R|/JavaClass.nonStaticField| } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.kt b/compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.kt new file mode 100644 index 00000000000..a5c288b6127 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.kt @@ -0,0 +1,11 @@ +class Outer { + fun foo() { + class Local { + fun bar() { + val x = y + } + } + } + + val y = "" +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.txt b/compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.txt new file mode 100644 index 00000000000..baac226e0cd --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.txt @@ -0,0 +1,24 @@ +FILE: localClassAccessesContainingClass.kt + public final class Outer : R|kotlin/Any| { + public constructor(): R|Outer| { + super() + } + + public final fun foo(): R|kotlin/Unit| { + local final class Local : R|kotlin/Any| { + public constructor(): R|Outer.Local| { + super() + } + + public final fun bar(): R|kotlin/Unit| { + lval x: R|kotlin/String| = this@R|/Outer|.R|/Outer.y| + } + + } + + } + + public final val y: R|kotlin/String| = String() + public get(): R|kotlin/String| + + } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.kt b/compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.kt new file mode 100644 index 00000000000..6cb0aa1b602 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.kt @@ -0,0 +1,8 @@ +class A { + class Nested + + fun main() { + val x = ::Nested + val y = A::Nested + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.txt b/compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.txt new file mode 100644 index 00000000000..e80f4b21bc2 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.txt @@ -0,0 +1,19 @@ +FILE: nestedConstructorCallable.kt + public final class A : R|kotlin/Any| { + public constructor(): R|A| { + super() + } + + public final class Nested : R|kotlin/Any| { + public constructor(): R|A.Nested| { + super() + } + + } + + public final fun main(): R|kotlin/Unit| { + lval x: R|kotlin/reflect/KFunction0| = ::R|/A.Nested.Nested| + lval y: R|kotlin/reflect/KFunction0| = Q|A|::R|/A.Nested.Nested| + } + + } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.kt b/compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.kt new file mode 100644 index 00000000000..139732c1e6d --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.kt @@ -0,0 +1,10 @@ +object A { + object B { + object A + } +} + +object B + +val err = B.A.B +val correct = A.B.A \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.txt b/compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.txt new file mode 100644 index 00000000000..1658ffdabfc --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.txt @@ -0,0 +1,31 @@ +FILE: nestedObjects.kt + public final object A : R|kotlin/Any| { + private constructor(): R|A| { + super() + } + + public final object B : R|kotlin/Any| { + private constructor(): R|A.B| { + super() + } + + public final object A : R|kotlin/Any| { + private constructor(): R|A.B.A| { + super() + } + + } + + } + + } + public final object B : R|kotlin/Any| { + private constructor(): R|B| { + super() + } + + } + public final val err: = Q|B|.#.# + public get(): + public final val correct: R|A.B.A| = Q|A.B.A| + public get(): R|A.B.A| diff --git a/compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.kt b/compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.kt new file mode 100644 index 00000000000..4ada07d50e5 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.kt @@ -0,0 +1,45 @@ +// FILE: Base.java + +public class Base { + protected String foo() { return ""; } +} + +// FILE: O.kt + +open class Wrapper(val b: Boolean) + +object O { + private class Derived(private val bar: Int) : Base() { + private inner class Some(val z: Boolean) { + fun test() { + val x = bar + val o = object : Wrapper(z) { + fun local() { + val y = foo() + } + val oo = object { + val zz = z + } + } + } + } + fun test() { + val x = bar + val o = object { + fun local() { + val y = foo() + } + } + } + } +} + +class Generator(val codegen: Any) { + private fun gen(): Any = + object : Wrapper(true) { + private fun invokeFunction() { + val c = codegen + val cc = codegen.hashCode() + } + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.txt b/compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.txt new file mode 100644 index 00000000000..eafb9542bb1 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.txt @@ -0,0 +1,102 @@ +FILE: O.kt + public open class Wrapper : R|kotlin/Any| { + public constructor(b: R|kotlin/Boolean|): R|Wrapper| { + super() + } + + public final val b: R|kotlin/Boolean| = R|/b| + public get(): R|kotlin/Boolean| + + } + public final object O : R|kotlin/Any| { + private constructor(): R|O| { + super() + } + + private final class Derived : R|Base| { + public constructor(bar: R|kotlin/Int|): R|O.Derived| { + super() + } + + private final val bar: R|kotlin/Int| = R|/bar| + private get(): R|kotlin/Int| + + private final inner class Some : R|kotlin/Any| { + public constructor(z: R|kotlin/Boolean|): R|O.Derived.Some| { + super() + } + + public final val z: R|kotlin/Boolean| = R|/z| + public get(): R|kotlin/Boolean| + + public final fun test(): R|kotlin/Unit| { + lval x: R|kotlin/Int| = this@R|/O.Derived|.R|/O.Derived.bar| + lval o: R|anonymous| = object : R|Wrapper| { + private constructor(): R|Wrapper| { + super(this@R|/O.Derived.Some|.R|/O.Derived.Some.z|) + } + + public final fun local(): R|kotlin/Unit| { + lval y: R|ft!| = this@R|/O.Derived|.R|/Base.foo|() + } + + public final val oo: R|anonymous| = object : R|kotlin/Any| { + private constructor(): R|kotlin/Any| { + super() + } + + public final val zz: R|kotlin/Boolean| = R|/z| + public get(): R|kotlin/Boolean| + + } + + public get(): R|anonymous| + + } + + } + + } + + public final fun test(): R|kotlin/Unit| { + lval x: R|kotlin/Int| = this@R|/O.Derived|.R|/O.Derived.bar| + lval o: R|anonymous| = object : R|kotlin/Any| { + private constructor(): R|kotlin/Any| { + super() + } + + public final fun local(): R|kotlin/Unit| { + lval y: R|ft!| = this@R|/O.Derived|.R|/Base.foo|() + } + + } + + } + + } + + } + public final class Generator : R|kotlin/Any| { + public constructor(codegen: R|kotlin/Any|): R|Generator| { + super() + } + + public final val codegen: R|kotlin/Any| = R|/codegen| + public get(): R|kotlin/Any| + + private final fun gen(): R|kotlin/Any| { + ^gen object : R|Wrapper| { + private constructor(): R|Wrapper| { + super(Boolean(true)) + } + + private final fun invokeFunction(): R|kotlin/Unit| { + lval c: R|kotlin/Any| = this@R|/Generator|.R|/Generator.codegen| + lval cc: R|kotlin/Int| = this@R|/Generator|.R|/Generator.codegen|.R|kotlin/Any.hashCode|() + } + + } + + } + + } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/outerObject.txt b/compiler/fir/resolve/testData/resolve/expresssions/outerObject.txt index 38a77e90c5c..90a58eb9711 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/outerObject.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/outerObject.txt @@ -15,11 +15,11 @@ FILE: outerObject.kt super() } - public final val y: R|kotlin/Int| = R|/Outer.x| + public final val y: R|kotlin/Int| = this@R|/Outer|.R|/Outer.x| public get(): R|kotlin/Int| public final fun test(): R|kotlin/Unit| { - this@R|/Outer.Nested|.R|/Outer.foo|() + (this@R|/Outer|, this@R|/Outer.Nested|).R|/Outer.foo|() } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/privateVisibility.txt b/compiler/fir/resolve/testData/resolve/expresssions/privateVisibility.txt index 632ddd07027..993a8dcd1bd 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/privateVisibility.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/privateVisibility.txt @@ -11,8 +11,8 @@ FILE: first.kt public final fun baz(): R|kotlin/Unit| { this@R|/Private|.R|/Private.bar|() - this@R|/Private|.R|/Private.Nested.Nested|() - R|/Private.Companion.fromCompanion|() + R|/Private.Nested.Nested|() + this@R|/Private.Companion|.R|/Private.Companion.fromCompanion|() Q|Private.NotCompanion|.#() } @@ -23,7 +23,7 @@ FILE: first.kt public final fun foo(): R|kotlin/Unit| { this@R|/Private|.R|/Private.bar|() - R|/Private.Companion.fromCompanion|() + this@R|/Private.Companion|.R|/Private.Companion.fromCompanion|() Q|Private.NotCompanion|.#() } @@ -35,7 +35,7 @@ FILE: first.kt } public final fun foo(): R|kotlin/Unit| { - R|/Private.Companion.fromCompanion|() + this@R|/Private.Companion|.R|/Private.Companion.fromCompanion|() Q|Private.NotCompanion|.#() } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/protectedVisibility.txt b/compiler/fir/resolve/testData/resolve/expresssions/protectedVisibility.txt index 2e334e3731e..8edcf6d4704 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/protectedVisibility.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/protectedVisibility.txt @@ -9,7 +9,7 @@ FILE: protectedVisibility.kt public final fun baz(): R|kotlin/Unit| { this@R|/Protected|.R|/Protected.bar|() - this@R|/Protected|.R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|() + R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|() } public final inner class Inner : R|kotlin/Any| { @@ -58,9 +58,9 @@ FILE: protectedVisibility.kt public final fun foo(): R|kotlin/Unit| { this@R|/Derived|.R|/Protected.bar|() - this@R|/Derived|.R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|() - this@R|/Derived|.R|/Protected.Nested.Nested|().#() - R|/Protected.Companion.fromCompanion|() + R|/Protected.Nested.Nested|().R|/Protected.Nested.foo|() + R|/Protected.Nested.Nested|().#() + this@R|/Protected.Companion|.R|/Protected.Companion.fromCompanion|() #() } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/qualifierPriority.kt b/compiler/fir/resolve/testData/resolve/expresssions/qualifierPriority.kt index acc5f54baf0..7cb46d454a7 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/qualifierPriority.kt +++ b/compiler/fir/resolve/testData/resolve/expresssions/qualifierPriority.kt @@ -10,7 +10,7 @@ class A { } val ab = A.B // property -val abc = A.B.C // object +val abc = A.B.C // object object D { class E { @@ -34,5 +34,5 @@ enum class G { } } -val gh = G.H // companion property -val gv = G.values() // static function +val gh = G.H // companion property +val gv = G.values() // static function diff --git a/compiler/fir/resolve/testData/resolve/expresssions/qualifierPriority.txt b/compiler/fir/resolve/testData/resolve/expresssions/qualifierPriority.txt index 5be61bbd650..7c30f55684e 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/qualifierPriority.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/qualifierPriority.txt @@ -29,10 +29,10 @@ FILE: qualifierPriority.kt } } - public final val ab: R|kotlin/String| = Q|A|.R|/A.Companion.B| - public get(): R|kotlin/String| - public final val abc: = Q|A|.R|/A.Companion.B|.# - public get(): + public final val ab: R|A.B| = Q|A.B| + public get(): R|A.B| + public final val abc: R|A.B.C| = Q|A.B.C| + public get(): R|A.B.C| public final object D : R|kotlin/Any| { private constructor(): R|D| { super() @@ -94,7 +94,7 @@ FILE: qualifierPriority.kt } } - public final val gh: = Q|G|.# - public get(): - public final val gv: = Q|G|.#() - public get(): + public final val gh: R|G| = Q|G|.R|/G.H| + public get(): R|G| + public final val gv: R|kotlin/Array| = Q|G|.R|/G.values|() + public get(): R|kotlin/Array| diff --git a/compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.kt b/compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.kt index 13e05010555..714ba2fcbc1 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.kt +++ b/compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.kt @@ -6,7 +6,7 @@ class C { class Nested { fun test() { - err() + err() } } } diff --git a/compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.txt b/compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.txt index 10391b82a6e..59c45cc154d 100644 --- a/compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.txt +++ b/compiler/fir/resolve/testData/resolve/expresssions/receiverConsistency.txt @@ -18,7 +18,7 @@ FILE: receiverConsistency.kt } public final fun test(): R|kotlin/Unit| { - R|/C.err|() + #() } } diff --git a/compiler/fir/resolve/testData/resolve/fromBuilder/enums.txt b/compiler/fir/resolve/testData/resolve/fromBuilder/enums.txt index a8c370fc194..b998d7178f2 100644 --- a/compiler/fir/resolve/testData/resolve/fromBuilder/enums.txt +++ b/compiler/fir/resolve/testData/resolve/fromBuilder/enums.txt @@ -76,7 +76,7 @@ FILE: enums.kt } - public final val g: R|kotlin/Double| = R|/Planet.Companion.G|.R|kotlin/Double.times|(R|/m|).R|kotlin/Double.div|(R|/r|.R|kotlin/Double.times|(R|/r|)) + public final val g: R|kotlin/Double| = this@R|/Planet.Companion|.R|/Planet.Companion.G|.R|kotlin/Double.times|(R|/m|).R|kotlin/Double.div|(R|/r|.R|kotlin/Double.times|(R|/r|)) public get(): R|kotlin/Double| public abstract fun sayHello(): R|kotlin/Unit| diff --git a/compiler/fir/resolve/testData/resolve/localObject.txt b/compiler/fir/resolve/testData/resolve/localObject.txt index 31e0e253b42..42691219966 100644 --- a/compiler/fir/resolve/testData/resolve/localObject.txt +++ b/compiler/fir/resolve/testData/resolve/localObject.txt @@ -64,14 +64,14 @@ FILE: localObject.kt ^ Int(1) } - public final val z: R|kotlin/Int| = R|/run|( = run@fun (): R|kotlin/Int| { + public final val z: R|kotlin/Int| = this@R|/TestProperty|.R|kotlin/run|( = run@fun R|TestProperty|.(): R|kotlin/Int| { lval obj: R|anonymous| = object : R|Foo| { private constructor(): R|kotlin/Any| { super() } public final override fun foo(): R|kotlin/Int| { - ^foo this@R|/TestProperty|.R|/TestProperty.x|.R|kotlin/Int.plus|(Int(1)) + ^foo this@R|special/anonymous|.R|/TestProperty.x|.R|kotlin/Int.plus|(Int(1)) } } diff --git a/compiler/fir/resolve/testData/resolve/nested/simple.kt b/compiler/fir/resolve/testData/resolve/nested/simple.kt index 6a3bb45f1ca..a42556effec 100644 --- a/compiler/fir/resolve/testData/resolve/nested/simple.kt +++ b/compiler/fir/resolve/testData/resolve/nested/simple.kt @@ -22,7 +22,7 @@ class Owner { } fun err() { - foo() + foo() this.foo() } } diff --git a/compiler/fir/resolve/testData/resolve/nested/simple.txt b/compiler/fir/resolve/testData/resolve/nested/simple.txt index 8387d032c5b..88a102e31e5 100644 --- a/compiler/fir/resolve/testData/resolve/nested/simple.txt +++ b/compiler/fir/resolve/testData/resolve/nested/simple.txt @@ -10,7 +10,7 @@ FILE: simple.kt } public final fun bar(): R|kotlin/Unit| { - lval n: R|Owner.Nested| = this@R|/Owner|.R|/Owner.Nested.Nested|() + lval n: R|Owner.Nested| = R|/Owner.Nested.Nested|() R|/n|.R|/Owner.Nested.baz|() } @@ -30,7 +30,7 @@ FILE: simple.kt } public final fun err(): R|kotlin/Unit| { - R|/Owner.foo|() + #() this@R|/Owner.Nested|.#() } diff --git a/compiler/fir/resolve/testData/resolve/nestedClassNameClash.txt b/compiler/fir/resolve/testData/resolve/nestedClassNameClash.txt index 751dac1b420..53fdcb8cdae 100644 --- a/compiler/fir/resolve/testData/resolve/nestedClassNameClash.txt +++ b/compiler/fir/resolve/testData/resolve/nestedClassNameClash.txt @@ -40,12 +40,12 @@ FILE: nestedClassNameClash.kt } public final fun test_5(): R|kotlin/Unit| { - lval result: R|Foo.Result| = this@R|/Foo|.R|/Foo.Result.Result|() + lval result: R|Foo.Result| = R|/Foo.Result.Result|() this@R|/Foo|.R|/Foo.saveResult|(R|/result|) } private final fun getResult(): R|Foo.Result| { - ^getResult this@R|/Foo|.R|/Foo.Result.Result|() + ^getResult R|/Foo.Result.Result|() } private final fun saveResults(results: R|kotlin/collections/List|): R|kotlin/Unit| { diff --git a/compiler/fir/resolve/testData/resolve/nestedReturnType.txt b/compiler/fir/resolve/testData/resolve/nestedReturnType.txt index 7fb9c5362ea..16ae9f2e92e 100644 --- a/compiler/fir/resolve/testData/resolve/nestedReturnType.txt +++ b/compiler/fir/resolve/testData/resolve/nestedReturnType.txt @@ -12,7 +12,7 @@ FILE: nestedReturnType.kt } public final fun foo(): R|Some.Nested| { - ^foo this@R|/Some|.R|/Some.Nested.Nested|() + ^foo R|/Some.Nested.Nested|() } } diff --git a/compiler/fir/resolve/testData/resolve/problems/nestedClassContructor.txt b/compiler/fir/resolve/testData/resolve/problems/nestedClassContructor.txt index 05d7d037077..0c47ccc57b1 100644 --- a/compiler/fir/resolve/testData/resolve/problems/nestedClassContructor.txt +++ b/compiler/fir/resolve/testData/resolve/problems/nestedClassContructor.txt @@ -10,7 +10,7 @@ FILE: nestedClassContructor.kt } public final fun copy(): R|A.B| { - ^copy this@R|/A.B|.R|/A.B.B|() + ^copy R|/A.B.B|() } } @@ -46,7 +46,7 @@ FILE: nestedClassContructor.kt public final fun foo(): R|kotlin/Unit| { lval a: R|A| = R|/A.A|() - lval c: R|A.C| = this@R|/E|.R|/A.C.C|() + lval c: R|A.C| = R|/A.C.C|() } } diff --git a/compiler/fir/resolve/testData/resolve/qualifierWithCompanion.txt b/compiler/fir/resolve/testData/resolve/qualifierWithCompanion.txt index c25149157ab..7bd638708f8 100644 --- a/compiler/fir/resolve/testData/resolve/qualifierWithCompanion.txt +++ b/compiler/fir/resolve/testData/resolve/qualifierWithCompanion.txt @@ -24,5 +24,5 @@ FILE: qualifierWithCompanion.kt local final fun R|my/A|.invoke(): R|kotlin/Unit| { } - R|my/xx|.R|/invoke|() + Q|my|.R|my/xx|.R|/invoke|() } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/callableReferences/companions.kt b/compiler/fir/resolve/testData/resolve/stdlib/callableReferences/companions.kt index c27db539762..6b358f8f5a7 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/callableReferences/companions.kt +++ b/compiler/fir/resolve/testData/resolve/stdlib/callableReferences/companions.kt @@ -30,13 +30,16 @@ fun foo3(x: (String) -> Int) {} fun main() { foo1(KotlinClass::baz) foo2(KotlinClass::baz) + // Ambiguity (companion/class) foo3(KotlinClass::baz) + // Type mismatch foo1(KotlinClass::bar) foo2(KotlinClass::bar) foo3(KotlinClass::bar) foo1(KotlinClass2::bar) + // Type mismatch foo2(KotlinClass2::bar) foo3(KotlinClass2::bar) } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/callableReferences/companions.txt b/compiler/fir/resolve/testData/resolve/stdlib/callableReferences/companions.txt index 9b419c1cbe7..a704b4dfce2 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/callableReferences/companions.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/callableReferences/companions.txt @@ -57,6 +57,6 @@ FILE: main.kt R|/foo2|(Q|KotlinClass|::R|/JavaClass.bar|) R|/foo3|(Q|KotlinClass|::R|/JavaClass.bar|) R|/foo1|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|) - #(Q|KotlinClass2|::R|/JavaClass.bar|) + #(Q|KotlinClass2|::R|/KotlinClass2.bar|) R|/foo3|(Q|KotlinClass2|::R|/KotlinClass2.Companion.bar|) } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/hashTableWithForEach.txt b/compiler/fir/resolve/testData/resolve/stdlib/hashTableWithForEach.txt index 99b5969ae1e..46d4c1bb674 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/hashTableWithForEach.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/hashTableWithForEach.txt @@ -15,7 +15,7 @@ FILE: hashTableWithForEach.kt R|/DEBUG| -> { ^ Q|java/util/Collections|.R|java/util/Collections.unmodifiableSet||>(R|kotlin/collections/mutableSetOf||>().R|kotlin/apply|>|>( = apply@fun R|kotlin/collections/MutableSet>|.(): R|kotlin/Unit| { this@R|/SomeHashTable|.R|FakeOverride|( = forEach@fun (key: R|K|, value: R|V|): R|kotlin/Unit| { - this@R|special/anonymous|.R|FakeOverride|(this@R|/SomeHashTable|.R|/SomeHashTable.Entry.Entry|(R|/key|, R|/value|)) + this@R|special/anonymous|.R|FakeOverride|(R|/SomeHashTable.Entry.Entry|(R|/key|, R|/value|)) } ) } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.txt b/compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.txt index 42c577e64e5..a229b66099e 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.txt @@ -31,7 +31,7 @@ FILE: implicitReceiverOrder.kt R|kotlin/with|(R|/b|, = with@fun R|B|.(): R|kotlin/Int| { R|kotlin/with|(R|/a|, = with@fun R|A|.(): R|kotlin/Int| { this@R|special/anonymous|.R|/A.foo|() - this@R|special/anonymous|.R|/B.bar|() + (this@R|special/anonymous|, this@R|special/anonymous|).R|/B.bar|() } ) } @@ -39,7 +39,7 @@ FILE: implicitReceiverOrder.kt R|kotlin/with|(R|/a|, = with@fun R|A|.(): R|kotlin/Int| { R|kotlin/with|(R|/b|, = with@fun R|B|.(): R|kotlin/Int| { this@R|special/anonymous|.R|/B.foo|() - this@R|special/anonymous|.R|/A.bar|() + (this@R|special/anonymous|, this@R|special/anonymous|).R|/A.bar|() } ) } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/j+k/StaticClassConstructorFromBaseClass.txt b/compiler/fir/resolve/testData/resolve/stdlib/j+k/StaticClassConstructorFromBaseClass.txt index b8d96ef4b67..b69dd41a9f7 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/j+k/StaticClassConstructorFromBaseClass.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/j+k/StaticClassConstructorFromBaseClass.txt @@ -5,7 +5,7 @@ FILE: User.kt } public final fun foo(): R|kotlin/Unit| { - lval sc: R|AbstractClass.StaticClass| = this@R|/User|.R|/AbstractClass.StaticClass.StaticClass|() + lval sc: R|AbstractClass.StaticClass| = R|/AbstractClass.StaticClass.StaticClass|() } } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/multipleImplicitReceivers.txt b/compiler/fir/resolve/testData/resolve/stdlib/multipleImplicitReceivers.txt index a64b6b2d2d7..ca23965485b 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/multipleImplicitReceivers.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/multipleImplicitReceivers.txt @@ -27,9 +27,9 @@ FILE: multipleImplicitReceivers.kt public final fun test(fooImpl: R|IFoo|, invokeImpl: R|IInvoke|): R|kotlin/Unit| { R|kotlin/with|(Q|A|, = with@fun R|A|.(): R|kotlin/Int| { R|kotlin/with|(R|/fooImpl|, = with@fun R|IFoo|.(): R|kotlin/Int| { - this@R|special/anonymous|.R|/IFoo.foo| + (this@R|special/anonymous|, this@R|special/anonymous|).R|/IFoo.foo| R|kotlin/with|(R|/invokeImpl|, = with@fun R|IInvoke|.(): R|kotlin/Int| { - (this@R|special/anonymous|, this@R|special/anonymous|.R|/IFoo.foo|).R|/IInvoke.invoke|() + (this@R|special/anonymous|, (this@R|special/anonymous|, this@R|special/anonymous|).R|/IFoo.foo|).R|/IInvoke.invoke|() } ) } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index 7f9615c397b..2662c32bc28 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -434,11 +434,21 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/resolve/expresssions/baseQualifier.kt"); } + @TestMetadata("CallBasedInExpressionGenerator.kt") + public void testCallBasedInExpressionGenerator() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt"); + } + @TestMetadata("checkArguments.kt") public void testCheckArguments() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/checkArguments.kt"); } + @TestMetadata("classifierAccessFromCompanion.kt") + public void testClassifierAccessFromCompanion() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.kt"); + } + @TestMetadata("companion.kt") public void testCompanion() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/companion.kt"); @@ -514,6 +524,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt"); } + @TestMetadata("innerWithSuperCompanion.kt") + public void testInnerWithSuperCompanion() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.kt"); + } + @TestMetadata("javaFieldCallable.kt") public void testJavaFieldCallable() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.kt"); @@ -529,6 +544,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/resolve/expresssions/lambdaWithReceiver.kt"); } + @TestMetadata("localClassAccessesContainingClass.kt") + public void testLocalClassAccessesContainingClass() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.kt"); + } + @TestMetadata("localConstructor.kt") public void testLocalConstructor() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/localConstructor.kt"); @@ -574,6 +594,16 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/resolve/expresssions/memberExtension.kt"); } + @TestMetadata("nestedConstructorCallable.kt") + public void testNestedConstructorCallable() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.kt"); + } + + @TestMetadata("nestedObjects.kt") + public void testNestedObjects() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.kt"); + } + @TestMetadata("nestedVisibility.kt") public void testNestedVisibility() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedVisibility.kt"); @@ -594,6 +624,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/resolve/expresssions/objects.kt"); } + @TestMetadata("outerMemberAccesses.kt") + public void testOuterMemberAccesses() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.kt"); + } + @TestMetadata("outerObject.kt") public void testOuterObject() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/outerObject.kt"); @@ -724,6 +759,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.kt"); } + @TestMetadata("extensionOnObject.kt") + public void testExtensionOnObject() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.kt"); + } + @TestMetadata("farInvokeExtension.kt") public void testFarInvokeExtension() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.kt"); @@ -763,6 +803,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { public void testThreeReceivers() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt"); } + + @TestMetadata("threeReceiversCorrect.kt") + public void testThreeReceiversCorrect() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.kt"); + } } @TestMetadata("compiler/fir/resolve/testData/resolve/expresssions/operators") diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 642dd19c25c..44b5aac812c 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -434,11 +434,21 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/resolve/testData/resolve/expresssions/baseQualifier.kt"); } + @TestMetadata("CallBasedInExpressionGenerator.kt") + public void testCallBasedInExpressionGenerator() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/CallBasedInExpressionGenerator.kt"); + } + @TestMetadata("checkArguments.kt") public void testCheckArguments() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/checkArguments.kt"); } + @TestMetadata("classifierAccessFromCompanion.kt") + public void testClassifierAccessFromCompanion() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/classifierAccessFromCompanion.kt"); + } + @TestMetadata("companion.kt") public void testCompanion() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/companion.kt"); @@ -514,6 +524,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/resolve/testData/resolve/expresssions/innerQualifier.kt"); } + @TestMetadata("innerWithSuperCompanion.kt") + public void testInnerWithSuperCompanion() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/innerWithSuperCompanion.kt"); + } + @TestMetadata("javaFieldCallable.kt") public void testJavaFieldCallable() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/javaFieldCallable.kt"); @@ -529,6 +544,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/resolve/testData/resolve/expresssions/lambdaWithReceiver.kt"); } + @TestMetadata("localClassAccessesContainingClass.kt") + public void testLocalClassAccessesContainingClass() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/localClassAccessesContainingClass.kt"); + } + @TestMetadata("localConstructor.kt") public void testLocalConstructor() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/localConstructor.kt"); @@ -574,6 +594,16 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/resolve/testData/resolve/expresssions/memberExtension.kt"); } + @TestMetadata("nestedConstructorCallable.kt") + public void testNestedConstructorCallable() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedConstructorCallable.kt"); + } + + @TestMetadata("nestedObjects.kt") + public void testNestedObjects() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedObjects.kt"); + } + @TestMetadata("nestedVisibility.kt") public void testNestedVisibility() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/nestedVisibility.kt"); @@ -594,6 +624,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/resolve/testData/resolve/expresssions/objects.kt"); } + @TestMetadata("outerMemberAccesses.kt") + public void testOuterMemberAccesses() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/outerMemberAccesses.kt"); + } + @TestMetadata("outerObject.kt") public void testOuterObject() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/outerObject.kt"); @@ -724,6 +759,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extension.kt"); } + @TestMetadata("extensionOnObject.kt") + public void testExtensionOnObject() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/extensionOnObject.kt"); + } + @TestMetadata("farInvokeExtension.kt") public void testFarInvokeExtension() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/farInvokeExtension.kt"); @@ -763,6 +803,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos public void testThreeReceivers() throws Exception { runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceivers.kt"); } + + @TestMetadata("threeReceiversCorrect.kt") + public void testThreeReceiversCorrect() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/expresssions/invoke/threeReceiversCorrect.kt"); + } } @TestMetadata("compiler/fir/resolve/testData/resolve/expresssions/operators") diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt index f541b80f6ce..67d4cfd84bd 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirScope.kt @@ -43,4 +43,9 @@ enum class ProcessorAction { fun stop() = this == STOP fun next() = this != STOP + + operator fun plus(other: ProcessorAction): ProcessorAction { + if (this == NEXT || other == NEXT) return NEXT + return this + } } diff --git a/compiler/testData/diagnostics/tests/ExtensionCallInvoke.fir.kt b/compiler/testData/diagnostics/tests/ExtensionCallInvoke.fir.kt index bc32e7c13c4..3a414132176 100644 --- a/compiler/testData/diagnostics/tests/ExtensionCallInvoke.fir.kt +++ b/compiler/testData/diagnostics/tests/ExtensionCallInvoke.fir.kt @@ -2,6 +2,6 @@ fun bar(doIt: Int.() -> Int) { 1.doIt() 1?.doIt() val i: Int? = 1 - i.doIt() + i.doIt() i?.doIt() } diff --git a/compiler/testData/diagnostics/tests/PackageInExpressionPosition.fir.kt b/compiler/testData/diagnostics/tests/PackageInExpressionPosition.fir.kt index 9813fcd7181..02b225b0fd2 100644 --- a/compiler/testData/diagnostics/tests/PackageInExpressionPosition.fir.kt +++ b/compiler/testData/diagnostics/tests/PackageInExpressionPosition.fir.kt @@ -5,7 +5,7 @@ class X {} val s = java val ss = System val sss = X -val x = "${System}" +val x = "${System}" val xs = java.lang val xss = java.lang.System val xsss = foo.X diff --git a/compiler/testData/diagnostics/tests/callableReference/bound/innerNested.fir.kt b/compiler/testData/diagnostics/tests/callableReference/bound/innerNested.fir.kt index 07582d6980f..38d896fa31a 100644 --- a/compiler/testData/diagnostics/tests/callableReference/bound/innerNested.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/bound/innerNested.fir.kt @@ -5,5 +5,5 @@ class Outer { fun test() { Outer()::Inner - Outer()::Nested + Outer()::Nested } diff --git a/compiler/testData/diagnostics/tests/callableReference/bound/referenceToStaticMethodOnInstance.fir.kt b/compiler/testData/diagnostics/tests/callableReference/bound/referenceToStaticMethodOnInstance.fir.kt index 656a0a5d6dc..85ad58b93c1 100644 --- a/compiler/testData/diagnostics/tests/callableReference/bound/referenceToStaticMethodOnInstance.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/bound/referenceToStaticMethodOnInstance.fir.kt @@ -9,6 +9,6 @@ public class A { enum class E { EN } fun test() { - A()::test - E.EN::valueOf + A()::test + E.EN::valueOf } diff --git a/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.fir.kt index 4c218d67696..80272aa2263 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/constructorOfNestedClassInObject.fir.kt @@ -16,6 +16,6 @@ fun test() { Outer.Companion::Wrapper (Outer.Companion)::Wrapper - Outer::Wrapper - (Outer)::Wrapper + Outer::Wrapper + (Outer)::Wrapper } diff --git a/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.fir.kt index 719a03b5e61..d7ff99df247 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/extensionToSupertype.fir.kt @@ -15,5 +15,5 @@ fun take(f: () -> Unit) {} fun test() { B::foo checkType { _>() } - take(B::foo) + take(B::foo) } diff --git a/compiler/testData/diagnostics/tests/callableReference/function/javaStaticMethod.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/javaStaticMethod.fir.kt index 405cf28f0f5..1cc92a66444 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/javaStaticMethod.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/javaStaticMethod.fir.kt @@ -18,7 +18,7 @@ import test.A fun foo(args: Array) { val main2 = A::main - checkSubtype, Unit>>(main2) - main2(args) - (A::main)(args) + checkSubtype, Unit>>(main2) + main2(args) + (A::main)(args) } diff --git a/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromClass.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromClass.fir.kt index 98a7a6f7137..33e0fe03898 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromClass.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromClass.fir.kt @@ -10,7 +10,7 @@ class A { val y = A::Nested checkSubtype>(x) - checkSubtype>(y) + checkSubtype>(y) } companion object { @@ -18,7 +18,7 @@ class A { ::Nested val y = A::Nested - checkSubtype>(y) + checkSubtype>(y) } } } @@ -28,6 +28,6 @@ class B { ::Nested val y = A::Nested - checkSubtype>(y) + checkSubtype>(y) } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromExtension.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromExtension.fir.kt index 3e0361b3185..68f56eb0ae7 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromExtension.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromExtension.fir.kt @@ -7,15 +7,15 @@ class A { } fun A.main() { - ::Nested + ::Nested val y = A::Nested - checkSubtype>(y) + checkSubtype>(y) } fun Int.main() { ::Nested val y = A::Nested - checkSubtype>(y) + checkSubtype>(y) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromTopLevel.fir.kt b/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromTopLevel.fir.kt index 42ce7b8d21c..1a7e3240ca9 100644 --- a/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromTopLevel.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/function/nestedConstructorFromTopLevel.fir.kt @@ -9,5 +9,5 @@ class A { fun main() { val x = A::Nested - checkSubtype>(x) + checkSubtype>(x) } diff --git a/compiler/testData/diagnostics/tests/callableReference/packageInLhs.fir.kt b/compiler/testData/diagnostics/tests/callableReference/packageInLhs.fir.kt index 6d81b0b3f52..9a280b8ae57 100644 --- a/compiler/testData/diagnostics/tests/callableReference/packageInLhs.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/packageInLhs.fir.kt @@ -4,7 +4,7 @@ package foo fun test() { - foo::test + foo::test } // FILE: qualifiedName.kt @@ -12,5 +12,5 @@ fun test() { package foo.bar fun test() { - foo.bar::test + foo.bar::test } diff --git a/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.fir.kt b/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.fir.kt index 0b8f7d52ee7..6d5fab08587 100644 --- a/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/resolve/withExtFun.fir.kt @@ -14,14 +14,14 @@ class A { fun A.foo(): String = "A" -val x0 = A::foo +val x0 = A::foo val x1 = ofType<(A) -> Unit>(A::foo) val x2 = ofType>(A::foo) val x3: KProperty1 = A::foo val x4: (A) -> String = A::foo -val y0 = A::bar +val y0 = A::bar val y1 = ofType<(A) -> Unit>(A::bar) val y2 = ofType>(A::bar) val y3: KProperty1 = A::bar diff --git a/compiler/testData/diagnostics/tests/classObjects/ClassObjectCannotAccessClassFields.fir.kt b/compiler/testData/diagnostics/tests/classObjects/ClassObjectCannotAccessClassFields.fir.kt index 6f5e7ff9794..a76c28aba66 100644 --- a/compiler/testData/diagnostics/tests/classObjects/ClassObjectCannotAccessClassFields.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/ClassObjectCannotAccessClassFields.fir.kt @@ -4,6 +4,6 @@ class A() { val x = 1 companion object { - val y = x + val y = x } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum_after.fir.kt b/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum_after.fir.kt index 3ae1e157093..bd84df04f12 100644 --- a/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum_after.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum_after.fir.kt @@ -21,7 +21,7 @@ enum class C { C.A() A() //TODO: should be resolved with error - this.A() + this.A() } }; @@ -34,7 +34,7 @@ enum class C { fun f() { C.E1.A - C.E1.A() + C.E1.A() C.E2.B() C.E2.O diff --git a/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum_before.fir.kt b/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum_before.fir.kt index a4acf6fb5d0..b4178c69923 100644 --- a/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum_before.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/InnerClassAccessThroughEnum_before.fir.kt @@ -21,7 +21,7 @@ enum class C { C.A() A() //TODO: should be resolved with error - this.A() + this.A() } }; @@ -34,7 +34,7 @@ enum class C { fun f() { C.E1.A - C.E1.A() + C.E1.A() C.E2.B() C.E2.O diff --git a/compiler/testData/diagnostics/tests/classObjects/resolveFunctionInsideClassObject.fir.kt b/compiler/testData/diagnostics/tests/classObjects/resolveFunctionInsideClassObject.fir.kt index 3f4c5d1c00a..498426201be 100644 --- a/compiler/testData/diagnostics/tests/classObjects/resolveFunctionInsideClassObject.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/resolveFunctionInsideClassObject.fir.kt @@ -4,6 +4,6 @@ class Test { fun test(): Int = 12 companion object { - val a = test() // Check if resolver will be able to infer type of a variable + val a = test() // Check if resolver will be able to infer type of a variable } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/constructorConsistency/companion.fir.kt b/compiler/testData/diagnostics/tests/constructorConsistency/companion.fir.kt index a32bd422020..5b0313198a6 100644 --- a/compiler/testData/diagnostics/tests/constructorConsistency/companion.fir.kt +++ b/compiler/testData/diagnostics/tests/constructorConsistency/companion.fir.kt @@ -8,7 +8,7 @@ class My { companion object { - val y = foo() + val y = foo() val u = bar() diff --git a/compiler/testData/diagnostics/tests/deprecated/nestedTypesUsage.fir.kt b/compiler/testData/diagnostics/tests/deprecated/nestedTypesUsage.fir.kt index 08721d085ce..6309291069a 100644 --- a/compiler/testData/diagnostics/tests/deprecated/nestedTypesUsage.fir.kt +++ b/compiler/testData/diagnostics/tests/deprecated/nestedTypesUsage.fir.kt @@ -14,5 +14,5 @@ class TopLevel { fun useNested() { val d = TopLevel.Nested.use() TopLevel.Nested.Nested2() - TopLevel.Nested.CompanionNested2() + TopLevel.Nested.CompanionNested2() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized/enumValuesValueOf.fir.kt b/compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized/enumValuesValueOf.fir.kt index 56528c8094c..6fcbe5814f9 100644 --- a/compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized/enumValuesValueOf.fir.kt +++ b/compiler/testData/diagnostics/tests/duplicateJvmSignature/synthesized/enumValuesValueOf.fir.kt @@ -2,7 +2,7 @@ enum class A { A1, A2; - fun valueOf(s: String): A = valueOf(s) + fun valueOf(s: String): A = valueOf(s) fun valueOf() = "OK" diff --git a/compiler/testData/diagnostics/tests/enum/javaEnumWithNameClashing.fir.kt b/compiler/testData/diagnostics/tests/enum/javaEnumWithNameClashing.fir.kt index d06fca45d28..67de39f40e7 100644 --- a/compiler/testData/diagnostics/tests/enum/javaEnumWithNameClashing.fir.kt +++ b/compiler/testData/diagnostics/tests/enum/javaEnumWithNameClashing.fir.kt @@ -10,6 +10,6 @@ public enum A { fun main() { val c: A = A.ENTRY - val c2: String? = c.ENTRY - val c3: String? = A.ANOTHER.ENTRY + val c2: String? = c.ENTRY + val c3: String? = A.ANOTHER.ENTRY } diff --git a/compiler/testData/diagnostics/tests/extensions/noClassObjectsInJava.fir.kt b/compiler/testData/diagnostics/tests/extensions/noClassObjectsInJava.fir.kt index e95008cb979..619baea05d3 100644 --- a/compiler/testData/diagnostics/tests/extensions/noClassObjectsInJava.fir.kt +++ b/compiler/testData/diagnostics/tests/extensions/noClassObjectsInJava.fir.kt @@ -7,5 +7,5 @@ public class A { // FILE: B.kt fun Any?.bar() = 42 -fun f1() = A.bar() -fun f2() = A.Nested.bar() +fun f1() = A.bar() +fun f2() = A.Nested.bar() diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.fir.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.fir.kt index 5f41403ca68..b2a0a2a1c64 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt32862_both.fir.kt @@ -12,5 +12,5 @@ fun G.foo(vararg values: V2) = build() fun forReference(ref: Any?) {} fun test() { - forReference(G::foo) + forReference(G::foo) } diff --git a/compiler/testData/diagnostics/tests/inner/extensionFun.fir.kt b/compiler/testData/diagnostics/tests/inner/extensionFun.fir.kt index f43b8b80566..6515d9c486c 100644 --- a/compiler/testData/diagnostics/tests/inner/extensionFun.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/extensionFun.fir.kt @@ -23,6 +23,6 @@ class Outer { fun Outer.foo() { Outer() - Nested() + Nested() Inner() } diff --git a/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.fir.kt b/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.fir.kt index 26cc4552eae..f91ff272ef0 100644 --- a/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.fir.kt @@ -12,8 +12,8 @@ class Test { fun more(): InnerClass { val b = InnerClass() - val testVal = inClass - foo() + val testVal = inClass + foo() return b } diff --git a/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.fir.kt b/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.fir.kt index a768d51e1a0..0e447b286f5 100644 --- a/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.fir.kt @@ -12,8 +12,8 @@ class Test { fun more(): InnerClass { val b = InnerClass() - val testVal = inClass - foo() + val testVal = inClass + foo() return b } diff --git a/compiler/testData/diagnostics/tests/inner/localClassInsideNested.fir.kt b/compiler/testData/diagnostics/tests/inner/localClassInsideNested.fir.kt index ef86abbccc1..a7eefec3262 100644 --- a/compiler/testData/diagnostics/tests/inner/localClassInsideNested.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/localClassInsideNested.fir.kt @@ -2,7 +2,7 @@ class Outer { class Nested { fun foo() { class Local { - val state = outerState + val state = outerState } } } diff --git a/compiler/testData/diagnostics/tests/inner/nestedClassAccessedViaInstanceReference.fir.kt b/compiler/testData/diagnostics/tests/inner/nestedClassAccessedViaInstanceReference.fir.kt index 72a896dde77..41abe184ac5 100644 --- a/compiler/testData/diagnostics/tests/inner/nestedClassAccessedViaInstanceReference.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/nestedClassAccessedViaInstanceReference.fir.kt @@ -24,30 +24,30 @@ object Obj { } fun test(with: WithClassObject, without: WithoutClassObject, obj: Obj) { - with.Nested() + with.Nested() with.NestedWithClassObject - with.NestedWithClassObject() + with.NestedWithClassObject() with.NestedWithClassObject.foo() with.NestedEnum.A with.NestedObj - with.NestedObj() + with.NestedObj() with.NestedObj.foo() - without.Nested() + without.Nested() without.NestedWithClassObject - without.NestedWithClassObject() + without.NestedWithClassObject() without.NestedWithClassObject.foo() without.NestedEnum.A without.NestedObj - without.NestedObj() + without.NestedObj() without.NestedObj.foo() - obj.Nested() + obj.Nested() obj.NestedWithClassObject - obj.NestedWithClassObject() + obj.NestedWithClassObject() obj.NestedWithClassObject.foo() obj.NestedEnum.A obj.NestedObj - obj.NestedObj() + obj.NestedObj() obj.NestedObj.foo() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.fir.kt b/compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.fir.kt index ce056e37502..e3806c9636d 100644 --- a/compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.fir.kt @@ -5,8 +5,8 @@ class Outer { val property = "" class Nested { - fun f() = function() - fun g() = property + fun f() = function() + fun g() = property fun h() = this@Outer.function() fun i() = this@Outer.property } diff --git a/compiler/testData/diagnostics/tests/inner/outerSuperClassMember.fir.kt b/compiler/testData/diagnostics/tests/inner/outerSuperClassMember.fir.kt index 01e06409fda..dae32f58c4f 100644 --- a/compiler/testData/diagnostics/tests/inner/outerSuperClassMember.fir.kt +++ b/compiler/testData/diagnostics/tests/inner/outerSuperClassMember.fir.kt @@ -4,6 +4,6 @@ open class Base { class Derived : Base() { class Nested { - fun bar() = foo() + fun bar() = foo() } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesWithQualificationNew.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesWithQualificationNew.fir.kt index 2145890ee7f..4a72ff41864 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesWithQualificationNew.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesWithQualificationNew.fir.kt @@ -119,8 +119,8 @@ class C : O.B() { val b = O.A::foo // DEPRECATED: Classifiers from companions of direct superclasses - val e = O.A.Companion.FromCompanionA::foo - val f = O.B.Companion.FromCompanionB::foo + val e = O.A.Companion.FromCompanionA::foo + val f = O.B.Companion.FromCompanionB::foo // INVISIBLE: "cousin" supertypes themselves val g = O.Alpha::foo diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesWithQualificationOld.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesWithQualificationOld.fir.kt index 0d19aa10ead..365ce45f7b7 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesWithQualificationOld.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesWithQualificationOld.fir.kt @@ -119,8 +119,8 @@ class C : O.B() { val b = O.A::foo // DEPRECATED: Classifiers from companions of direct superclasses - val e = O.A.Companion.FromCompanionA::foo - val f = O.B.Companion.FromCompanionB::foo + val e = O.A.Companion.FromCompanionA::foo + val f = O.B.Companion.FromCompanionB::foo // INVISIBLE: "cousin" supertypes themselves val g = O.Alpha::foo diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaNew.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaNew.fir.kt index afc01878696..503e8ef0da5 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaNew.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaNew.fir.kt @@ -34,8 +34,8 @@ class Derived : Base() { syntheticSam { } // Instance members shouldn't be affected, but we check them, just in case - val y = instanceSyntheticProperty - instanceSyntheticProperty = 43 + val y = instanceSyntheticProperty + instanceSyntheticProperty = 43 // Note that statics actually aren't converted into synthetic property in Kotlin val x = syntheticProperty diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaOld.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaOld.fir.kt index e7b795b7daf..d0fcffa0b87 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaOld.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaOld.fir.kt @@ -34,8 +34,8 @@ class Derived : Base() { syntheticSam { } // Instance members shouldn't be affected, but we check them, just in case - val y = instanceSyntheticProperty - instanceSyntheticProperty = 43 + val y = instanceSyntheticProperty + instanceSyntheticProperty = 43 // Note that statics actually aren't converted into synthetic property in Kotlin val x = syntheticProperty diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaWithQualificationNew.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaWithQualificationNew.fir.kt index 7ffea50e305..ca2d5e72a55 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaWithQualificationNew.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaWithQualificationNew.fir.kt @@ -39,8 +39,8 @@ class Derived : Base() { syntheticSam { } // Instance members shouldn't be affected, but we check them, just in case - val y = instanceSyntheticProperty - instanceSyntheticProperty = 43 + val y = instanceSyntheticProperty + instanceSyntheticProperty = 43 // Note that statics actually aren't converted into synthetic property in Kotlin val x = syntheticProperty diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaWithQualificationOld.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaWithQualificationOld.fir.kt index 5ecec00f0a2..0d15c35222d 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaWithQualificationOld.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/staticsFromJavaWithQualificationOld.fir.kt @@ -39,8 +39,8 @@ class Derived : Base() { syntheticSam { } // Instance members shouldn't be affected, but we check them, just in case - val y = instanceSyntheticProperty - instanceSyntheticProperty = 43 + val y = instanceSyntheticProperty + instanceSyntheticProperty = 43 // Note that statics actually aren't converted into synthetic property in Kotlin val x = syntheticProperty diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/useDeprecatedConstructorWithQualificationNew.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/useDeprecatedConstructorWithQualificationNew.fir.kt index 605356b2a8f..2a1da9d91d3 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/useDeprecatedConstructorWithQualificationNew.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/useDeprecatedConstructorWithQualificationNew.fir.kt @@ -77,8 +77,8 @@ class C : O.B() { val b = O.B() // DEPRECATED: Classifiers from companions of direct superclasses - val e = O.A.Companion.FromCompanionA() - val f = O.B.Companion.FromCompanionB() + val e = O.A.Companion.FromCompanionA() + val f = O.B.Companion.FromCompanionB() // INVISIBLE: "cousin" supertypes themselves val g = O.Alpha() diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/useDeprecatedConstructorWithQualificationOld.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/useDeprecatedConstructorWithQualificationOld.fir.kt index 16f4361d02c..ab80273e1c2 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/useDeprecatedConstructorWithQualificationOld.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/useDeprecatedConstructorWithQualificationOld.fir.kt @@ -77,8 +77,8 @@ class C : O.B() { val b = O.B() // DEPRECATED: Classifiers from companions of direct superclasses - val e = O.A.Companion.FromCompanionA() - val f = O.B.Companion.FromCompanionB() + val e = O.A.Companion.FromCompanionA() + val f = O.B.Companion.FromCompanionB() // INVISIBLE: "cousin" supertypes themselves val g = O.Alpha() diff --git a/compiler/testData/diagnostics/tests/regressions/kt31975.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt31975.fir.kt index d7ac5e67b92..34b6f6f2254 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt31975.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt31975.fir.kt @@ -11,7 +11,7 @@ interface TypeConstructor class Refiner { val memoizedFunctionLambda = createMemoizedFunction { it.foo() } // error type infered, no diagnostic, BAD, backend fails - val memoizedFunctionReference = createMemoizedFunction(TypeConstructor::foo) // EXTENSION_IN_CLASS_REFERENCE_IS_NOT_ALLOWED, fine + val memoizedFunctionReference = createMemoizedFunction(TypeConstructor::foo) // EXTENSION_IN_CLASS_REFERENCE_IS_NOT_ALLOWED, fine val memoizedFunctionTypes = createMemoizedFunction { it.foo() } // works fine private fun TypeConstructor.foo(): Boolean = true diff --git a/compiler/testData/diagnostics/tests/regressions/kt5362.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt5362.fir.kt index 052dedb2828..273270909f5 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt5362.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt5362.fir.kt @@ -2,7 +2,7 @@ // KT-5362 Compiler crashes on access to extension method from nested class class Outer { class Nested{ - fun foo(s: String) = s.extension() + fun foo(s: String) = s.extension() } private fun String.extension(): String = this @@ -12,7 +12,7 @@ class Outer { fun Activity.toast() = Unit class Activity(){ class Fragment{ - fun call() = toast() + fun call() = toast() } } diff --git a/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers2.fir.kt b/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers2.fir.kt index 9345d87e3bc..cb6b70fbac7 100644 --- a/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers2.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/dslMarker/threeImplicitReceivers2.fir.kt @@ -55,7 +55,7 @@ fun test() { with(D()) { x() } - A().x() + A().x() } foo2 { diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/errors/wrongReceiverForInvokeOnExpression.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/errors/wrongReceiverForInvokeOnExpression.fir.kt index d616e9d6153..8aea96e9043 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/errors/wrongReceiverForInvokeOnExpression.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/errors/wrongReceiverForInvokeOnExpression.fir.kt @@ -6,8 +6,8 @@ fun test1() { } fun test2(f: String.(Int) -> Unit) { - 11.(f)(1) - 11.(f)() + 11.(f)(1) + 11.(f)() } fun test3() { diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/functionExpectedWhenSeveralInvokesExist.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/functionExpectedWhenSeveralInvokesExist.fir.kt index 5beb96a3b06..b98a5e324ac 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/functionExpectedWhenSeveralInvokesExist.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/functionExpectedWhenSeveralInvokesExist.fir.kt @@ -10,5 +10,5 @@ fun test(identifier: SomeClass, fn: String.() -> Unit) { identifier() identifier(123) identifier(1, 2) - 1.fn() + 1.fn() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/invokeAndSmartCast.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAndSmartCast.fir.kt index 0951bbf7fc1..3a5a8a49df6 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/invokeAndSmartCast.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAndSmartCast.fir.kt @@ -15,8 +15,8 @@ fun test(a: A) { a.x() (a.x)() if (a.x != null) { - a.x() // todo - (a.x)() + a.x() // todo + (a.x)() } } } diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/invokeOnVariableWithExtensionFunctionType.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/invokeOnVariableWithExtensionFunctionType.fir.kt index 581f29c57f5..3a4dbb8fdbb 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/invokeOnVariableWithExtensionFunctionType.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/invokeOnVariableWithExtensionFunctionType.fir.kt @@ -13,9 +13,9 @@ fun test(a: A, b: B) { a.foo(b) with(a) { - b.foo() + b.foo() - b.(foo)() + b.(foo)() (b.foo)() @@ -24,10 +24,10 @@ fun test(a: A, b: B) { } with(b) { - a.foo() - a.(foo)() + a.foo() + a.(foo)() - (a.foo)() + (a.foo)() (a.foo)(this) a.foo(this) @@ -59,17 +59,17 @@ fun test(a: A, b: B) { b.(foo)() - (b.foo)() + (b.foo)() foo(b) (foo)(b) } with(b) { - a.foo() - a.(foo)() + a.foo() + a.(foo)() - (a.foo)() + (a.foo)() (a.foo)(this) a.foo(this) diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/kt3772.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/kt3772.fir.kt index 5e9a39f6280..fe070fc191d 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/kt3772.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/kt3772.fir.kt @@ -20,7 +20,7 @@ val D.attr: B fun main() { val b = D() - b.attr {} // overload resolution ambiguity + b.attr {} // overload resolution ambiguity val d = b.attr d {} // no error diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/kt9805.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/kt9805.fir.kt index 0b17b6e94b7..a0e0b9c1208 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/kt9805.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/kt9805.fir.kt @@ -6,11 +6,11 @@ class B fun test(a: A, b: B) { with(b) { - a.foo() // here must be error, because a is not extension receiver + a.foo() // here must be error, because a is not extension receiver a.foo(this) - (a.foo)() + (a.foo)() (a.foo)(this) } diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/reportFunctionExpectedWhenOneInvokeExist.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/reportFunctionExpectedWhenOneInvokeExist.fir.kt index f71a3eceb98..47c99beab08 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/reportFunctionExpectedWhenOneInvokeExist.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/reportFunctionExpectedWhenOneInvokeExist.fir.kt @@ -9,5 +9,5 @@ fun test(identifier: SomeClass, fn: String.() -> Unit) { identifier() identifier(123) identifier(1, 2) - 1.fn() + 1.fn() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/noCandidates/resolvedToClassifierWithReceiver.fir.kt b/compiler/testData/diagnostics/tests/resolve/noCandidates/resolvedToClassifierWithReceiver.fir.kt index d5a24a8d485..692b447b83a 100644 --- a/compiler/testData/diagnostics/tests/resolve/noCandidates/resolvedToClassifierWithReceiver.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/noCandidates/resolvedToClassifierWithReceiver.fir.kt @@ -34,6 +34,6 @@ fun test(x: X) { val interface_as_fun = x.A() val interface_as_val = x.A - val object_as_fun = x.B() + val object_as_fun = x.B() val class_as_val = x.C } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/priority/kt9965.fir.kt b/compiler/testData/diagnostics/tests/resolve/priority/kt9965.fir.kt index 83044f795c9..0be29b963af 100644 --- a/compiler/testData/diagnostics/tests/resolve/priority/kt9965.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/priority/kt9965.fir.kt @@ -12,9 +12,9 @@ enum class Foo { } fun test() { - Foo.values() checkType { _>() } + Foo.values() checkType { _>() } Foo.Companion.values() checkType { _() } - Foo.valueOf("") checkType { _() } + Foo.valueOf("") checkType { _() } Foo.Companion.valueOf("") checkType { _() } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/companionObject.fir.kt b/compiler/testData/diagnostics/tests/scopes/inheritance/companionObject.fir.kt index f34525428d6..e6168faef1a 100644 --- a/compiler/testData/diagnostics/tests/scopes/inheritance/companionObject.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/companionObject.fir.kt @@ -24,7 +24,7 @@ class C: B(), A { C.foo() A_() - A.A_() + A.A_() A.Companion.A_() C.A_() @@ -34,7 +34,7 @@ class C: B(), A { C.bar() B_() - B.B_() + B.B_() B.Companion.B_() C.B_() } diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/companionObjectAfterJava.fir.kt b/compiler/testData/diagnostics/tests/scopes/inheritance/companionObjectAfterJava.fir.kt index d2a44995123..1f0af8b342a 100644 --- a/compiler/testData/diagnostics/tests/scopes/inheritance/companionObjectAfterJava.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/companionObjectAfterJava.fir.kt @@ -32,7 +32,7 @@ class D: C() { D.foo() A_() - A.A_() + A.A_() A.Companion.A_() C.A_() D.A_() @@ -44,7 +44,7 @@ class D: C() { D.bar() B_() - B.B_() + B.B_() B.Companion.B_() C.B_() D.B_() diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/companionObjectsOrder.fir.kt b/compiler/testData/diagnostics/tests/scopes/inheritance/companionObjectsOrder.fir.kt index d3102b829fb..ace81e1a17c 100644 --- a/compiler/testData/diagnostics/tests/scopes/inheritance/companionObjectsOrder.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/companionObjectsOrder.fir.kt @@ -4,7 +4,7 @@ open class A { fun bar() = 1 } init { - val a: Int = foo() + val a: Int = foo() val b: Int = bar() } } @@ -14,7 +14,7 @@ open class B: A() { fun bar() = "" } init { - val a: String = foo() + val a: String = foo() val b: String = bar() } } @@ -24,14 +24,14 @@ fun B.Companion.foo() = "" class C: A() { init { - val a: Int = foo() + val a: Int = foo() val b: Int = bar() } } class D: B() { init { - val a: String = foo() + val a: String = foo() val b: String = bar() } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/staticVsMember.fir.kt b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/staticVsMember.fir.kt index 9db4a94b46d..434f1c18063 100644 --- a/compiler/testData/diagnostics/tests/scopes/inheritance/statics/staticVsMember.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/inheritance/statics/staticVsMember.fir.kt @@ -27,14 +27,14 @@ open class C: A() { init { val a: String = foo() - val b: String = bar + val b: String = bar } } class E: C() { init { val a: String = foo() - val b: String = bar + val b: String = bar } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/CallCompanionProtectedNonStatic.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/CallCompanionProtectedNonStatic.fir.kt index f01dce22d1f..18847d59ada 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/CallCompanionProtectedNonStatic.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/CallCompanionProtectedNonStatic.fir.kt @@ -5,7 +5,7 @@ open class VeryBase { open class Base { protected fun foo() { bar() // Ok - baz() // Ok + baz() // Ok } inner class Inner { @@ -13,7 +13,7 @@ open class Base { foo() // Ok bar() // Ok gav() // Ok - baz() // Ok + baz() // Ok } } @@ -22,7 +22,7 @@ open class Base { foo() // Ok bar() // Ok gav() // Ok - baz() // Ok + baz() // Ok } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/javaClassOnCompanion.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/javaClassOnCompanion.fir.kt index 1a1936414f9..c8e364c7d98 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/javaClassOnCompanion.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/javaClassOnCompanion.fir.kt @@ -21,7 +21,7 @@ val a5 = A.Companion::class.java val o0 = O.javaClass val o1 = O::class.java -val e0 = E.javaClass +val e0 = E.javaClass val e1 = E::class.java val e2 = E.ENTRY.javaClass