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:
Denis Zharkov
2020-07-30 15:35:35 +03:00
parent db93b9052b
commit a5a93d00a7
27 changed files with 181 additions and 169 deletions

View File

@@ -50,4 +50,4 @@ fun test_4() {
fun test_5() {
val map = LinkedHashMap<Int, Int>() // should be foo.LinkedHashMap
}
}

View File

@@ -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()<!>
}
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
}
}

View File

@@ -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
)

View File

@@ -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

View File

@@ -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(

View File

@@ -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<*>>
) {

View File

@@ -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")

View File

@@ -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)
}
}

View File

@@ -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)

View File

@@ -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,

View File

@@ -12,4 +12,4 @@ public class C {
class Foo : <!UNRESOLVED_REFERENCE!>Data<!>()
companion object : DerivedAbstract()
}
}

View File

@@ -12,4 +12,4 @@ public class C {
class Foo : <!UNRESOLVED_REFERENCE!>Data<!>()
companion object : DerivedAbstract()
}
}

View File

@@ -79,4 +79,4 @@ object MessageManager15 : Manager<Int> {
var <T : Int> T.y
get() = 10
set(value) {}
}
}

View File

@@ -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>>

View File

@@ -97,4 +97,4 @@ open class C : O.B() {
// DEPRECATED: Classifiers from supertypes of our own companion
open class r : <!UNRESOLVED_REFERENCE!>FromDelta<!>()
}
}

View File

@@ -16,4 +16,4 @@ class Some: <!UNRESOLVED_REFERENCE!>Test<!>()
package b.d
public open class Test
public open class Test

View File

@@ -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)
}

View File

@@ -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> {

View File

@@ -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)
}

View File

@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
open class B<X, Y : X> {
constructor(x: X, y: Y)

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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> {

View File

@@ -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)