diff --git a/compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.kt b/compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.kt index d57847105bd..e8292c347e9 100644 --- a/compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.kt +++ b/compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.kt @@ -50,4 +50,4 @@ fun test_4() { fun test_5() { val map = LinkedHashMap() // should be foo.LinkedHashMap -} \ No newline at end of file +} diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/cyclicConstructorDelegationCall.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/cyclicConstructorDelegationCall.kt index 9405986d625..3e0bcb593bf 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/cyclicConstructorDelegationCall.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/cyclicConstructorDelegationCall.kt @@ -25,7 +25,7 @@ class E { // selection of the proper constructor // but a type mismatch for the first // argument - constructor(e: T, i: Int) : this(i, 10) {} + constructor(e: T, i: Int) : this(i, 10) {} } class I { @@ -33,7 +33,7 @@ class I { // selection of the proper constructor // but a type mismatch for the first // argument - constructor(e: T, i: Int) : this(i, 10) + constructor(e: T, i: Int) : this(i, 10) } class J { @@ -64,4 +64,4 @@ class M { class U : M { constructor() -} \ No newline at end of file +} 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 556d6c4c206..f31f7d8418b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.isInner import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.expressions.* @@ -32,10 +34,13 @@ import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.builder.buildStarProjection +import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind +import org.jetbrains.kotlin.types.Variance class FirCallResolver( private val components: BodyResolveComponents, @@ -291,10 +296,16 @@ class FirCallResolver( fun resolveDelegatingConstructorCall( delegatedConstructorCall: FirDelegatedConstructorCall, - constructorClassSymbol: FirClassSymbol<*>, - typeArguments: List, + constructedType: ConeClassLikeType ): FirDelegatedConstructorCall? { val name = Name.special("") + val symbol = constructedType.lookupTag.toSymbol(components.session) + val typeArguments = + constructedType.typeArguments.take((symbol?.fir as? FirRegularClass)?.typeParameters?.count { it is FirTypeParameter } ?: 0) + .map { + it.toFirTypeProjection() + } + val callInfo = CallInfo( CallKind.DelegatingConstructorCall, name, @@ -307,14 +318,36 @@ class FirCallResolver( containingDeclarations, ) towerResolver.reset() + val result = towerResolver.runResolverForDelegatingConstructor( callInfo, - constructorClassSymbol, + constructedType ) return callResolver.selectDelegatingConstructorCall(delegatedConstructorCall, name, result, callInfo) } + private fun ConeTypeProjection.toFirTypeProjection(): FirTypeProjection = when (this) { + is ConeStarProjection -> buildStarProjection() + else -> { + val type = when (this) { + is ConeKotlinTypeProjectionIn -> type + is ConeKotlinTypeProjectionOut -> type + is ConeStarProjection -> throw IllegalStateException() + else -> this as ConeKotlinType + } + buildTypeProjectionWithVariance { + typeRef = buildResolvedTypeRef { this.type = type } + variance = when (kind) { + ProjectionKind.IN -> Variance.IN_VARIANCE + ProjectionKind.OUT -> Variance.OUT_VARIANCE + ProjectionKind.INVARIANT -> Variance.INVARIANT + ProjectionKind.STAR -> throw IllegalStateException() + } + } + } + } + fun resolveAnnotationCall(annotationCall: FirAnnotationCall): FirAnnotationCall? { val reference = annotationCall.calleeReference as? FirSimpleNamedReference ?: return null annotationCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt index 9cc1e930d23..af9abe526f6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt @@ -57,6 +57,7 @@ interface BodyResolveComponents : SessionHolder { val dataFlowAnalyzer: FirDataFlowAnalyzer<*> val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater + val outerClassManager: FirOuterClassManager val AbstractFirBasedSymbol.phasedFir: D where D : FirDeclaration, D : FirSymbolOwner get() = phasedFir(FirResolvePhase.DECLARATIONS) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirOuterClassManager.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirOuterClassManager.kt new file mode 100644 index 00000000000..3c0646521b9 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirOuterClassManager.kt @@ -0,0 +1,45 @@ +/* + * 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 + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.isInner +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.types.ConeClassLikeType + +class FirOuterClassManager( + private val session: FirSession, + private val outerLocalClassForNested: Map, FirClassLikeSymbol<*>>, +) { + private val symbolProvider = session.firSymbolProvider + + fun outerClass(classSymbol: FirClassLikeSymbol<*>): FirClassLikeSymbol<*>? { + if (classSymbol !is FirClassSymbol<*>) return null + val classId = classSymbol.classId + if (classId.isLocal) return outerLocalClassForNested[classSymbol] + val outerClassId = classId.outerClassId ?: return null + return symbolProvider.getClassLikeSymbolByFqName(outerClassId) + } + + fun outerType(classLikeType: ConeClassLikeType): ConeClassLikeType? { + val fullyExpandedType = classLikeType.fullyExpandedType(session) + + val symbol = fullyExpandedType.lookupTag.toSymbol(session) ?: return null + + if (symbol is FirRegularClassSymbol && !symbol.fir.isInner) return null + + val containingSymbol = outerClass(symbol) ?: return null + val currentTypeArgumentsNumber = (symbol as? FirRegularClassSymbol)?.fir?.typeParameters?.count { it is FirTypeParameter } ?: 0 + + return containingSymbol.constructType( + fullyExpandedType.typeArguments.drop(currentTypeArgumentsNumber).toTypedArray(), + isNullable = false + ) as ConeClassLikeType + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt index 78b99f1d4e2..8240cda8031 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt @@ -21,8 +21,8 @@ import org.jetbrains.kotlin.fir.scopes.scope import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.coneTypeUnsafe import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.coneTypeUnsafe import org.jetbrains.kotlin.name.Name private operator fun Pair?.component1() = this?.first @@ -32,7 +32,6 @@ internal fun FirScope.processConstructorsByName( name: Name, session: FirSession, bodyResolveComponents: BodyResolveComponents, - includeSyntheticConstructors: Boolean, includeInnerConstructors: Boolean, processor: (FirCallableSymbol<*>) -> Unit ) { @@ -51,13 +50,11 @@ internal fun FirScope.processConstructorsByName( includeInnerConstructors ) - if (includeSyntheticConstructors) { - processSyntheticConstructors( - matchedClassSymbol, - processor, - bodyResolveComponents - ) - } + processSyntheticConstructors( + matchedClassSymbol, + processor, + bodyResolveComponents + ) } } @@ -70,7 +67,6 @@ internal fun FirScope.processFunctionsAndConstructorsByName( ) { processConstructorsByName( name, session, bodyResolveComponents, - includeSyntheticConstructors = true, includeInnerConstructors = includeInnerConstructors, processor = processor ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt index c172f3e1644..7a80feb93ec 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolver.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.calls.* -import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.types.ConeClassLikeType class FirTowerResolver( private val components: BodyResolveComponents, @@ -32,12 +32,12 @@ class FirTowerResolver( fun runResolverForDelegatingConstructor( info: CallInfo, - constructorClassSymbol: FirClassSymbol<*>, + constructedType: ConeClassLikeType, ): CandidateCollector { val candidateFactoriesAndCollectors = buildCandidateFactoriesAndCollectors(info, collector) val towerResolverSession = FirTowerResolverSession(components, manager, candidateFactoriesAndCollectors, info) - towerResolverSession.runResolutionForDelegatingConstructor(info, constructorClassSymbol) + towerResolverSession.runResolutionForDelegatingConstructor(info, constructedType) manager.runTasks() return collector diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolverSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolverSession.kt index dae78e01fe9..5d6735ce45b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolverSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolverSession.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.asReversedFrozen import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.declarations.isInner import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier @@ -20,15 +19,15 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe import org.jetbrains.kotlin.fir.scopes.FirCompositeScope import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction -import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol +import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST +import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.util.OperatorNameConventions class FirTowerResolverSession internal constructor( @@ -67,8 +66,11 @@ class FirTowerResolverSession internal constructor( } } - fun runResolutionForDelegatingConstructor(info: CallInfo, constructorClassSymbol: FirClassSymbol<*>) { - manager.enqueueResolverTask { runResolverForDelegatingConstructorCall(info, constructorClassSymbol) } + fun runResolutionForDelegatingConstructor( + info: CallInfo, + constructedType: ConeClassLikeType + ) { + manager.enqueueResolverTask { runResolverForDelegatingConstructorCall(info, constructedType) } } fun runResolution(info: CallInfo) { @@ -138,8 +140,8 @@ class FirTowerResolverSession internal constructor( extensionReceiver, extensionsOnly, includeInnerConstructors ) - private fun FirScope.toConstructorScopeTowerLevel(): ConstructorScopeTowerLevel = - ConstructorScopeTowerLevel(session, this) + private fun FirScope.toConstructorScopeTowerLevel(dispatchReceiver: ImplicitReceiver?): ConstructorScopeTowerLevel = + ConstructorScopeTowerLevel(session, this, dispatchReceiver?.receiver) private fun ReceiverValue.toMemberScopeTowerLevel( extensionReceiver: ReceiverValue? = null, @@ -211,23 +213,25 @@ class FirTowerResolverSession internal constructor( } } - private suspend fun runResolverForDelegatingConstructorCall(info: CallInfo, constructorClassSymbol: FirClassSymbol<*>) { - val scope = constructorClassSymbol.fir.unsubstitutedScope(session, components.scopeSession) - if (constructorClassSymbol is FirRegularClassSymbol && constructorClassSymbol.fir.isInner) { - // Search for inner constructors only - for ((implicitReceiverValue, depth) in implicitReceivers.drop(1)) { - processLevel( - implicitReceiverValue.toMemberScopeTowerLevel(), - info.copy(name = constructorClassSymbol.fir.name), TowerGroup.Implicit(depth) - ) - } - } else { - // Search for non-inner constructors only - processLevel( - scope.toConstructorScopeTowerLevel(), - info, TowerGroup.Member - ) - } + private suspend fun runResolverForDelegatingConstructorCall( + info: CallInfo, + constructedType: ConeClassLikeType + ) { + val outerType = components.outerClassManager.outerType(constructedType) + val scope = constructedType.scope(session, components.scopeSession) ?: return + + val dispatchReceiver = + if (outerType != null) + implicitReceivers.drop(1).firstOrNull { + AbstractTypeChecker.isSubtypeOf(components.session.typeContext, it.receiver.type, outerType) + } ?: return // TODO: report diagnostic about not-found receiver + else + null + + processLevel( + scope.toConstructorScopeTowerLevel(dispatchReceiver), + info, TowerGroup.Member + ) } private suspend fun runResolverForNoReceiver( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt index cde2bc86049..e0b92581613 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt @@ -123,7 +123,7 @@ internal class TowerLevelHandler { } } CallKind.DelegatingConstructorCall -> { - towerLevel.processConstructors(info.name, processor) + towerLevel.processElementsByNameAndStoreResult(TowerScopeLevel.Token.ConstructorsForDelegationCall, info.name, processor) } else -> { throw AssertionError("Unsupported call kind in tower resolver: ${info.callKind}") @@ -153,12 +153,6 @@ internal class TowerLevelHandler { processProperties(name, processor) } - private fun TowerScopeLevel.processConstructors( - name: Name, processor: TowerScopeLevel.TowerScopeLevelProcessor> - ) { - processElementsByNameAndStoreResult(TowerScopeLevel.Token.Constructors, name, processor) - } - private fun TowerScopeLevel.processObjectsAsVariables( name: Name, processor: TowerScopeLevel.TowerScopeLevelProcessor> ) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index 2225a482020..18301a7764f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -35,7 +35,7 @@ interface TowerScopeLevel { sealed class Token> { object Properties : Token>() object Functions : Token>() - object Constructors : Token() + object ConstructorsForDelegationCall : Token() object Objects : Token>() } @@ -79,7 +79,6 @@ class MemberScopeTowerLevel( ) : SessionBasedTowerLevel(session) { private fun > processMembers( output: TowerScopeLevel.TowerScopeLevelProcessor, - forInnerConstructorDelegationCalls: Boolean = false, processScopeMembers: FirScope.(processor: (T) -> Unit) -> Unit ): ProcessorAction { var empty = true @@ -90,9 +89,7 @@ class MemberScopeTowerLevel( (implicitExtensionInvokeMode || candidate.hasConsistentExtensionReceiver(extensionReceiver)) ) { val fir = candidate.fir - if (forInnerConstructorDelegationCalls && candidate !is FirConstructorSymbol) { - return@processScopeMembers - } else if ((fir as? FirConstructor)?.isInner == false) { + if ((fir as? FirConstructor)?.isInner == false) { return@processScopeMembers } val dispatchReceiverValue = NotNullableReceiverValue(dispatchReceiver) @@ -114,7 +111,7 @@ class MemberScopeTowerLevel( } } - if (!forInnerConstructorDelegationCalls && extensionReceiver == null) { + if (extensionReceiver == null) { val withSynthetic = FirSyntheticPropertiesScope(session, scope) withSynthetic.processScopeMembers { symbol -> empty = false @@ -159,17 +156,7 @@ class MemberScopeTowerLevel( consumer(it as T) } } - TowerScopeLevel.Token.Constructors -> processMembers(processor, forInnerConstructorDelegationCalls = true) { consumer -> - this.processConstructorsByName( - name, session, bodyResolveComponents, - includeSyntheticConstructors = false, - includeInnerConstructors = true, - processor = { - @Suppress("UNCHECKED_CAST") - consumer(it as T) - } - ) - } + TowerScopeLevel.Token.ConstructorsForDelegationCall -> error("ConstructorsForDelegationCall should be handled via ConstructorScopeTowerLevel") } } @@ -276,7 +263,7 @@ class ScopeTowerLevel( implicitExtensionReceiverValue = null ) } - TowerScopeLevel.Token.Constructors -> { + TowerScopeLevel.Token.ConstructorsForDelegationCall -> { throw AssertionError("Should not be here") } } @@ -286,7 +273,8 @@ class ScopeTowerLevel( class ConstructorScopeTowerLevel( session: FirSession, - val scope: FirScope + private val scope: FirScope, + private val dispatchReceiver: ImplicitReceiverValue<*>?, ) : SessionBasedTowerLevel(session) { override fun > processElementsByName( token: TowerScopeLevel.Token, @@ -295,17 +283,14 @@ class ConstructorScopeTowerLevel( ): ProcessorAction { var empty = true when (token) { - TowerScopeLevel.Token.Constructors -> scope.processDeclaredConstructors { candidate -> - // NB: here we cannot resolve inner constructors, because they should have dispatch receiver - if (!candidate.fir.isInner) { - empty = false - @Suppress("UNCHECKED_CAST") - processor.consumeCandidate( - candidate as T, - dispatchReceiverValue = null, - implicitExtensionReceiverValue = null - ) - } + TowerScopeLevel.Token.ConstructorsForDelegationCall -> scope.processDeclaredConstructors { candidate -> + empty = false + @Suppress("UNCHECKED_CAST") + processor.consumeCandidate( + candidate as T, + dispatchReceiverValue = dispatchReceiver, + implicitExtensionReceiverValue = null + ) } else -> { throw AssertionError("Should not be here: token = $token") diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt index c77741adb8b..a65a3c61749 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef import org.jetbrains.kotlin.name.Name @@ -104,7 +105,8 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb class BodyResolveContext( val returnTypeCalculator: ReturnTypeCalculator, val dataFlowAnalyzerContext: DataFlowAnalyzerContext, - val targetedLocalClasses: Set> = emptySet() + val targetedLocalClasses: Set> = emptySet(), + val outerLocalClassForNested: MutableMap, FirClassLikeSymbol<*>> = mutableMapOf() ) { val fileImportsScope: MutableList = mutableListOf() @@ -241,7 +243,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb fun createSnapshotForLocalClasses( returnTypeCalculator: ReturnTypeCalculator, targetedLocalClasses: Set> - ) = BodyResolveContext(returnTypeCalculator, dataFlowAnalyzerContext, targetedLocalClasses).apply { + ) = BodyResolveContext(returnTypeCalculator, dataFlowAnalyzerContext, targetedLocalClasses, outerLocalClassForNested).apply { file = this@BodyResolveContext.file towerDataContextForAnonymousFunctions.putAll(this@BodyResolveContext.towerDataContextForAnonymousFunctions) containers = this@BodyResolveContext.containers @@ -291,5 +293,6 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = FirDoubleColonExpressionResolver(session, integerLiteralTypeApproximator) override val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater = IntegerOperatorsTypeUpdater(integerLiteralTypeApproximator) + override val outerClassManager: FirOuterClassManager = FirOuterClassManager(session, context.outerLocalClassForNested) } } 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 9960d35d77f..c80ce43a86c 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 @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic -import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression @@ -31,14 +30,12 @@ import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.symbols.StandardClassIds -import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.* import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.Variance open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) { private inline val builtinTypes: BuiltinTypes get() = session.builtinTypes @@ -757,27 +754,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform } } - private fun ConeTypeProjection.toFirTypeProjection(): FirTypeProjection = when (this) { - is ConeStarProjection -> buildStarProjection() - else -> { - val type = when (this) { - is ConeKotlinTypeProjectionIn -> type - is ConeKotlinTypeProjectionOut -> type - is ConeStarProjection -> throw IllegalStateException() - else -> this as ConeKotlinType - } - buildTypeProjectionWithVariance { - typeRef = buildResolvedTypeRef { this.type = type } - variance = when (kind) { - ProjectionKind.IN -> Variance.IN_VARIANCE - ProjectionKind.OUT -> Variance.OUT_VARIANCE - ProjectionKind.INVARIANT -> Variance.INVARIANT - ProjectionKind.STAR -> throw IllegalStateException() - } - } - } - } - override fun transformDelegatedConstructorCall( delegatedConstructorCall: FirDelegatedConstructorCall, data: ResolutionMode, @@ -814,38 +790,23 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform delegatedConstructorCall.transformChildren(transformer, ResolutionMode.ContextDependent) } - val typeArguments: List val reference = delegatedConstructorCall.calleeReference - val symbol: FirClassSymbol<*> = when (reference) { + val constructorType: ConeClassLikeType = when (reference) { is FirThisReference -> { - typeArguments = emptyList() - if (reference.boundSymbol == null) { - lastDispatchReceiver?.boundSymbol?.also { - reference.replaceBoundSymbol(it) - } ?: return delegatedConstructorCall.compose() - } else { - reference.boundSymbol!! as FirClassSymbol<*> - } + lastDispatchReceiver?.type as? ConeClassLikeType ?: return delegatedConstructorCall.compose() } is FirSuperReference -> { // TODO: unresolved supertype - val supertype = reference.superTypeRef.coneTypeSafe() ?: return delegatedConstructorCall.compose() - val expandedSupertype = supertype.fullyExpandedType(session) - val symbol = - expandedSupertype.lookupTag.toSymbol(session) as? FirClassSymbol<*> ?: return delegatedConstructorCall.compose() - val classTypeParametersCount = - (symbol.fir as? FirTypeParameterRefsOwner)?.typeParameters?.count { it is FirTypeParameter } ?: 0 - typeArguments = expandedSupertype.typeArguments - .takeLast(classTypeParametersCount) // Hack for KT-37525 - .takeIf { it.isNotEmpty() } - ?.map { it.toFirTypeProjection() } - ?: emptyList() - symbol + val supertype = reference.superTypeRef.coneTypeSafe() + ?.takeIf { it !is ConeClassErrorType } ?: return delegatedConstructorCall.compose() + supertype.fullyExpandedType(session) } else -> return delegatedConstructorCall.compose() } - val resolvedCall = callResolver.resolveDelegatingConstructorCall(delegatedConstructorCall, symbol, typeArguments) - ?: return delegatedConstructorCall.compose() + + val resolvedCall = + callResolver.resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType) + ?: return delegatedConstructorCall.compose() if (reference is FirThisReference && reference.boundSymbol == null) { resolvedCall.dispatchReceiver.typeRef.coneTypeSafe()?.lookupTag?.toSymbol(session)?.let { reference.replaceBoundSymbol(it) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt index dbb80f6f5f1..af0980bfe83 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/LocalClassesResolution.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.resolve.ResolutionMode -import org.jetbrains.kotlin.fir.resolve.transformers.contracts.runContractResolveForLocalClass import org.jetbrains.kotlin.fir.resolve.transformers.runStatusResolveForLocalClass import org.jetbrains.kotlin.fir.resolve.transformers.runSupertypeResolvePhaseForLocalClass import org.jetbrains.kotlin.fir.resolve.transformers.runTypeResolvePhaseForLocalClass @@ -22,6 +21,12 @@ fun > F.runAllPhasesForLocalClass( if (this.resolvePhase > FirResolvePhase.RAW_FIR) return this this.transformAnnotations(transformer, ResolutionMode.ContextIndependent) val localClassesNavigationInfo = collectLocalClassesNavigationInfo() + + for ((nested, outer) in localClassesNavigationInfo.parentForClass) { + if (outer == null) continue + components.context.outerLocalClassForNested[nested.symbol] = outer.symbol + } + runSupertypeResolvePhaseForLocalClass( components.session, components.scopeSession, diff --git a/compiler/testData/diagnostics/tests/cyclicHierarchy/withCompanion/noMembers_after.fir.kt b/compiler/testData/diagnostics/tests/cyclicHierarchy/withCompanion/noMembers_after.fir.kt index 5cf15f3455d..cfa5ffa10b9 100644 --- a/compiler/testData/diagnostics/tests/cyclicHierarchy/withCompanion/noMembers_after.fir.kt +++ b/compiler/testData/diagnostics/tests/cyclicHierarchy/withCompanion/noMembers_after.fir.kt @@ -12,4 +12,4 @@ public class C { class Foo : Data() companion object : DerivedAbstract() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/cyclicHierarchy/withCompanion/noMembers_before.fir.kt b/compiler/testData/diagnostics/tests/cyclicHierarchy/withCompanion/noMembers_before.fir.kt index 312bfb39ead..720a92bc5d0 100644 --- a/compiler/testData/diagnostics/tests/cyclicHierarchy/withCompanion/noMembers_before.fir.kt +++ b/compiler/testData/diagnostics/tests/cyclicHierarchy/withCompanion/noMembers_before.fir.kt @@ -12,4 +12,4 @@ public class C { class Foo : Data() companion object : DerivedAbstract() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.fir.kt b/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.fir.kt index f5f9d868b31..c1dbbcefa52 100644 --- a/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/finalUpperBoundWithoutOverride.fir.kt @@ -79,4 +79,4 @@ object MessageManager15 : Manager { var T.y get() = 10 set(value) {} -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/generics/kt5508.fir.kt b/compiler/testData/diagnostics/tests/generics/kt5508.fir.kt index f7b373f9128..7d0c2dfac64 100644 --- a/compiler/testData/diagnostics/tests/generics/kt5508.fir.kt +++ b/compiler/testData/diagnostics/tests/generics/kt5508.fir.kt @@ -6,7 +6,7 @@ abstract class A { public abstract fun bar(x: T) public inner abstract class B : A>() { - public inner class C : B>() + public inner class C : B>() { // Here B> means A.B>.B.B.C>>.B.B>.B.B.C>.C> // while for being a correct override it should be A.B>.B.B.C> diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/inheritedFromDeprecatedOld.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/inheritedFromDeprecatedOld.fir.kt index 51bd88108d3..bb0e84a9aa5 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/inheritedFromDeprecatedOld.fir.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/inheritedFromDeprecatedOld.fir.kt @@ -97,4 +97,4 @@ open class C : O.B() { // DEPRECATED: Classifiers from supertypes of our own companion open class r : FromDelta() -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/scopes/kt1080.fir.kt b/compiler/testData/diagnostics/tests/scopes/kt1080.fir.kt index cb7b10f1d26..3b9adbb86ca 100644 --- a/compiler/testData/diagnostics/tests/scopes/kt1080.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/kt1080.fir.kt @@ -16,4 +16,4 @@ class Some: Test() package b.d -public open class Test \ No newline at end of file +public open class Test diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/generics.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/generics.fir.kt index 7ca3ff8081d..ac12d88ab30 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/generics.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/generics.fir.kt @@ -17,5 +17,5 @@ class A1 : B { } class A2 { - constructor(t: R, i: Int) : this(i, 1) + constructor(t: R, i: Int) : this(i, 1) } diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/generics2.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/generics2.fir.kt index 4d03f2ea5b5..0c16f42cc5b 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/generics2.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/generics2.fir.kt @@ -5,11 +5,11 @@ open class B(x: R1, y: R2) class A0 { constructor(x: T1, y: T2): this(x, y) - constructor(x: T1, y: T2, z: T2): this(x, 1) // ok, delegates to constructor(x: T1, y: Int) + constructor(x: T1, y: T2, z: T2): this(x, 1) // ok, delegates to constructor(x: T1, y: Int) - constructor(x: T1, y: Int): this(x, "") - constructor(x: T1): this(x, 1) - constructor(x: T1, y: T2, z: String): this(y, x) + constructor(x: T1, y: Int): this(x, "") + constructor(x: T1): this(x, 1) + constructor(x: T1, y: T2, z: String): this(y, x) } class A1 : B { diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/generics3.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/generics3.fir.kt deleted file mode 100644 index 81c591a7b40..00000000000 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/generics3.fir.kt +++ /dev/null @@ -1,16 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -open class B { - constructor(x: X, y: Y) - constructor(x: X, s: String) - constructor(y: Y, i: Int) : this(y, "") -} - -class A : B { - constructor(x: T1, y: T2): super(x, y) - constructor(x: T2, y: T2, z: String): super(x, y) - - constructor(x: T2, z: String, z1: String): super(x, "") - constructor(x: T2, z: String, z1: String, z2: String): super(x, 1) - constructor(x: T1, z: String, z1: String, z2: String, z3: String): super(x, "") - constructor(x: T1, z: String, z1: String, z2: String, z3: String, z4: String): super(x, 1) -} diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/generics3.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/generics3.kt index be48be48bdd..db2487cbb9c 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/generics3.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/generics3.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER open class B { constructor(x: X, y: Y) diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/kt6993.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/kt6993.fir.kt index 9b32c097368..490207fb280 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/kt6993.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/kt6993.fir.kt @@ -1,5 +1,5 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER // !WITH_NEW_INFERENCE class X(val t: T) { - constructor(t: T, i: Int) : this(i) -} \ No newline at end of file + constructor(t: T, i: Int) : this(i) +} diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/kt6994.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/kt6994.fir.kt index af8b7419100..89b1ce9431e 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/kt6994.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/kt6994.fir.kt @@ -1,4 +1,4 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER class X { - constructor(t: T, i: Int): this(i, 1) + constructor(t: T, i: Int): this(i, 1) } diff --git a/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.fir.kt b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.fir.kt index 22e8b76378c..6a5c43d9c55 100644 --- a/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/innerClassTypeAliasConstructorInSupertypes.fir.kt @@ -22,16 +22,16 @@ class Generic { open inner class Generic inner class Test1 : GI() - inner class Test2 : GIInt() + inner class Test2 : GIInt() inner class Test3 : GIStar() inner class Test3a : test.Generic<*>.Inner() inner class Test4 : GG() inner class Test5 : GG() - inner class Test6 : GG() - inner class Test7 : GG() - inner class Test8 : GIntG() - inner class Test9 : GGInt() + inner class Test6 : GG() + inner class Test7 : GG() + inner class Test8 : GIntG() + inner class Test9 : GGInt() inner class Test10 : GGInt() inner class Test11 : GG { diff --git a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorInferenceInSupertypesList.fir.kt b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorInferenceInSupertypesList.fir.kt index a2653eecef4..cc45ddb92e4 100644 --- a/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorInferenceInSupertypesList.fir.kt +++ b/compiler/testData/diagnostics/tests/typealias/typeAliasConstructorInferenceInSupertypesList.fir.kt @@ -3,5 +3,5 @@ open class Ref(var x: T) typealias R = Ref // Type inference SHOULD NOT work for type alias constructor in supertypes list -class Test1 : R(0) -class Test2 : R(0) \ No newline at end of file +class Test1 : R(0) +class Test2 : R(0)