mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-03 08:31:29 +00:00
FIR: Rework delegation constructor calls resolution
Make it work independently of being called for inner class (as in FE 1.0)
This commit is contained in:
@@ -50,4 +50,4 @@ fun test_4() {
|
||||
|
||||
fun test_5() {
|
||||
val map = LinkedHashMap<Int, Int>() // should be foo.LinkedHashMap
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class E<T> {
|
||||
// selection of the proper constructor
|
||||
// but a type mismatch for the first
|
||||
// argument
|
||||
constructor(e: T, i: Int) : <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>this<!>(i, 10) {}
|
||||
constructor(e: T, i: Int) : <!INAPPLICABLE_CANDIDATE!>this<!>(i, 10) {}
|
||||
}
|
||||
|
||||
class I<T> {
|
||||
@@ -33,7 +33,7 @@ class I<T> {
|
||||
// selection of the proper constructor
|
||||
// but a type mismatch for the first
|
||||
// argument
|
||||
constructor(e: T, i: Int) : <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>this<!>(i, 10)
|
||||
constructor(e: T, i: Int) : <!INAPPLICABLE_CANDIDATE!>this<!>(i, 10)
|
||||
}
|
||||
|
||||
class J<T> {
|
||||
@@ -64,4 +64,4 @@ class M {
|
||||
|
||||
class U : M {
|
||||
<!INAPPLICABLE_CANDIDATE!>constructor()<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<FirTypeProjection>,
|
||||
constructedType: ConeClassLikeType
|
||||
): FirDelegatedConstructorCall? {
|
||||
val name = Name.special("<init>")
|
||||
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)
|
||||
|
||||
@@ -57,6 +57,7 @@ interface BodyResolveComponents : SessionHolder {
|
||||
val dataFlowAnalyzer: FirDataFlowAnalyzer<*>
|
||||
val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer
|
||||
val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater
|
||||
val outerClassManager: FirOuterClassManager
|
||||
|
||||
val <D> AbstractFirBasedSymbol<D>.phasedFir: D where D : FirDeclaration, D : FirSymbolOwner<D>
|
||||
get() = phasedFir(FirResolvePhase.DECLARATIONS)
|
||||
|
||||
@@ -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<*>, 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
|
||||
}
|
||||
}
|
||||
@@ -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 <T> Pair<T, *>?.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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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<AbstractFirBasedSymbol<*>>
|
||||
) {
|
||||
processElementsByNameAndStoreResult(TowerScopeLevel.Token.Constructors, name, processor)
|
||||
}
|
||||
|
||||
private fun TowerScopeLevel.processObjectsAsVariables(
|
||||
name: Name, processor: TowerScopeLevel.TowerScopeLevelProcessor<AbstractFirBasedSymbol<*>>
|
||||
) {
|
||||
|
||||
@@ -35,7 +35,7 @@ interface TowerScopeLevel {
|
||||
sealed class Token<out T : AbstractFirBasedSymbol<*>> {
|
||||
object Properties : Token<FirVariableSymbol<*>>()
|
||||
object Functions : Token<FirFunctionSymbol<*>>()
|
||||
object Constructors : Token<FirConstructorSymbol>()
|
||||
object ConstructorsForDelegationCall : Token<FirConstructorSymbol>()
|
||||
object Objects : Token<AbstractFirBasedSymbol<*>>()
|
||||
}
|
||||
|
||||
@@ -79,7 +79,6 @@ class MemberScopeTowerLevel(
|
||||
) : SessionBasedTowerLevel(session) {
|
||||
private fun <T : AbstractFirBasedSymbol<*>> processMembers(
|
||||
output: TowerScopeLevel.TowerScopeLevelProcessor<T>,
|
||||
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 <T : AbstractFirBasedSymbol<*>> processElementsByName(
|
||||
token: TowerScopeLevel.Token<T>,
|
||||
@@ -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")
|
||||
|
||||
@@ -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<PersistentFlow>,
|
||||
val targetedLocalClasses: Set<FirClass<*>> = emptySet()
|
||||
val targetedLocalClasses: Set<FirClass<*>> = emptySet(),
|
||||
val outerLocalClassForNested: MutableMap<FirClassLikeSymbol<*>, FirClassLikeSymbol<*>> = mutableMapOf()
|
||||
) {
|
||||
val fileImportsScope: MutableList<FirScope> = mutableListOf()
|
||||
|
||||
@@ -241,7 +243,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
||||
fun createSnapshotForLocalClasses(
|
||||
returnTypeCalculator: ReturnTypeCalculator,
|
||||
targetedLocalClasses: Set<FirClass<*>>
|
||||
) = 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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<FirTypeProjection>
|
||||
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<ConeClassLikeType>() ?: 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<ConeClassLikeType>()
|
||||
?.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<ConeClassLikeType>()?.lookupTag?.toSymbol(session)?.let {
|
||||
reference.replaceBoundSymbol(it)
|
||||
|
||||
@@ -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 : FirClass<F>> 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,
|
||||
|
||||
@@ -12,4 +12,4 @@ public class C {
|
||||
class Foo : <!UNRESOLVED_REFERENCE!>Data<!>()
|
||||
|
||||
companion object : DerivedAbstract()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,4 +12,4 @@ public class C {
|
||||
class Foo : <!UNRESOLVED_REFERENCE!>Data<!>()
|
||||
|
||||
companion object : DerivedAbstract()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,4 +79,4 @@ object MessageManager15 : Manager<Int> {
|
||||
var <T : Int> T.y
|
||||
get() = 10
|
||||
set(value) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ abstract class A<T> {
|
||||
public abstract fun bar(x: T)
|
||||
|
||||
public inner abstract class B<S> : A<B<S>>() {
|
||||
public inner class C<U> : B<C<U>>()
|
||||
public inner class C<U> : <!UNRESOLVED_REFERENCE!>B<C<U>><!>()
|
||||
{
|
||||
// Here B<C<U>> means A<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>>.B<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>.C<U>>
|
||||
// while for being a correct override it should be A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>
|
||||
|
||||
@@ -97,4 +97,4 @@ open class C : O.B() {
|
||||
|
||||
// DEPRECATED: Classifiers from supertypes of our own companion
|
||||
open class r : <!UNRESOLVED_REFERENCE!>FromDelta<!>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,4 +16,4 @@ class Some: <!UNRESOLVED_REFERENCE!>Test<!>()
|
||||
|
||||
package b.d
|
||||
|
||||
public open class Test
|
||||
public open class Test
|
||||
|
||||
@@ -17,5 +17,5 @@ class A1<R> : B<R> {
|
||||
}
|
||||
|
||||
class A2<R> {
|
||||
constructor(t: R, i: Int) : <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>this<!>(i, 1)
|
||||
constructor(t: R, i: Int) : <!INAPPLICABLE_CANDIDATE!>this<!>(i, 1)
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ open class B<R1, R2>(x: R1, y: R2)
|
||||
class A0<T1, T2> {
|
||||
constructor(x: T1, y: T2): <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>this<!>(x, y)
|
||||
|
||||
constructor(x: T1, y: T2, z: T2): <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>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): <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>this<!>(x, "")
|
||||
constructor(x: T1): <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>this<!>(x, 1)
|
||||
constructor(x: T1, y: T2, z: String): <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>this<!>(y, x)
|
||||
constructor(x: T1, y: Int): <!NONE_APPLICABLE!>this<!>(x, "")
|
||||
constructor(x: T1): this(x, 1)
|
||||
constructor(x: T1, y: T2, z: String): <!NONE_APPLICABLE!>this<!>(y, x)
|
||||
}
|
||||
|
||||
class A1<T1, T2> : B<T1, T2> {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
open class B<X, Y : X> {
|
||||
constructor(x: X, y: Y)
|
||||
constructor(x: X, s: String)
|
||||
constructor(y: Y, i: Int) : this(y, "")
|
||||
}
|
||||
|
||||
class A<T1, T2 : T1> : B<T1, T2> {
|
||||
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)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
open class B<X, Y : X> {
|
||||
constructor(x: X, y: Y)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// !WITH_NEW_INFERENCE
|
||||
class X<T>(val t: T) {
|
||||
constructor(t: T, i: Int) : this(i)
|
||||
}
|
||||
constructor(t: T, i: Int) : <!INAPPLICABLE_CANDIDATE!>this<!>(i)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class X<T> {
|
||||
constructor(t: T, i: Int): <!CYCLIC_CONSTRUCTOR_DELEGATION_CALL!>this<!>(i, 1)
|
||||
constructor(t: T, i: Int): <!INAPPLICABLE_CANDIDATE!>this<!>(i, 1)
|
||||
}
|
||||
|
||||
@@ -22,16 +22,16 @@ class Generic<T1> {
|
||||
open inner class Generic<T2>
|
||||
|
||||
inner class Test1 : GI<T1>()
|
||||
inner class Test2 : GIInt()
|
||||
inner class Test2 : <!UNRESOLVED_REFERENCE!>GIInt<!>()
|
||||
inner class Test3 : GIStar()
|
||||
inner class Test3a : test.Generic<*>.Inner()
|
||||
|
||||
inner class Test4<T2> : GG<T1, T2>()
|
||||
inner class Test5 : GG<T1, Int>()
|
||||
inner class Test6 : GG<Int, T1>()
|
||||
inner class Test7 : GG<Int, Int>()
|
||||
inner class Test8 : GIntG<Int>()
|
||||
inner class Test9 : GGInt<Int>()
|
||||
inner class Test6 : <!UNRESOLVED_REFERENCE!>GG<Int, T1><!>()
|
||||
inner class Test7 : <!UNRESOLVED_REFERENCE!>GG<Int, Int><!>()
|
||||
inner class Test8 : <!UNRESOLVED_REFERENCE!>GIntG<Int><!>()
|
||||
inner class Test9 : <!UNRESOLVED_REFERENCE!>GGInt<Int><!>()
|
||||
inner class Test10 : GGInt<T1>()
|
||||
|
||||
inner class Test11 : GG<T1, Int> {
|
||||
|
||||
@@ -3,5 +3,5 @@ open class Ref<T>(var x: T)
|
||||
typealias R<T> = Ref<T>
|
||||
|
||||
// Type inference SHOULD NOT work for type alias constructor in supertypes list
|
||||
class Test1 : R(0)
|
||||
class Test2 : R<Int>(0)
|
||||
class Test1 : <!INAPPLICABLE_CANDIDATE!>R<!>(0)
|
||||
class Test2 : R<Int>(0)
|
||||
|
||||
Reference in New Issue
Block a user