diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescription.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescription.kt index 0a58abe132f..e606f15898f 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescription.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescription.kt @@ -38,10 +38,10 @@ interface ContractDescriptionElement { interface EffectDeclaration : ContractDescriptionElement { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitEffectDeclaration(this, data) + contractDescriptionVisitor.visitEffectDeclaration(this, data) } interface BooleanExpression : ContractDescriptionElement { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitBooleanExpression(this, data) + contractDescriptionVisitor.visitBooleanExpression(this, data) } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescriptionRenderer.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescriptionRenderer.kt index b2d06945c33..d1d0a2c8ddf 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescriptionRenderer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescriptionRenderer.kt @@ -74,7 +74,7 @@ class ContractDescriptionRenderer(private val builder: StringBuilder) : Contract } private fun ContractDescriptionElement.isAtom(): Boolean = - this is VariableReference || this is ConstantReference || this is IsNullPredicate || this is IsInstancePredicate + this is VariableReference || this is ConstantReference || this is IsNullPredicate || this is IsInstancePredicate private fun needsBrackets(parent: ContractDescriptionElement, child: ContractDescriptionElement): Boolean { if (child.isAtom()) return false @@ -87,8 +87,7 @@ class ContractDescriptionRenderer(private val builder: StringBuilder) : Contract builder.append("(") block() builder.append(")") - } - else { + } else { block() } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescriptionVisitor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescriptionVisitor.kt index 0b1a0836696..c146f5be5c6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescriptionVisitor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/ContractDescriptionVisitor.kt @@ -25,7 +25,10 @@ interface ContractDescriptionVisitor { // Effects fun visitEffectDeclaration(effectDeclaration: EffectDeclaration, data: D): R = visitContractDescriptionElement(effectDeclaration, data) - fun visitConditionalEffectDeclaration(conditionalEffect: ConditionalEffectDeclaration, data: D): R = visitEffectDeclaration(conditionalEffect, data) + + fun visitConditionalEffectDeclaration(conditionalEffect: ConditionalEffectDeclaration, data: D): R = + visitEffectDeclaration(conditionalEffect, data) + fun visitReturnsEffectDeclaration(returnsEffect: ReturnsEffectDeclaration, data: D): R = visitEffectDeclaration(returnsEffect, data) fun visitCallsEffectDeclaration(callsEffect: CallsEffectDeclaration, data: D): R = visitEffectDeclaration(callsEffect, data) @@ -43,7 +46,10 @@ interface ContractDescriptionVisitor { fun visitValue(value: ContractDescriptionValue, data: D): R = visitContractDescriptionElement(value, data) fun visitConstantDescriptor(constantReference: ConstantReference, data: D): R = visitValue(constantReference, data) - fun visitBooleanConstantDescriptor(booleanConstantDescriptor: BooleanConstantReference, data: D): R = visitConstantDescriptor(booleanConstantDescriptor, data) + fun visitBooleanConstantDescriptor(booleanConstantDescriptor: BooleanConstantReference, data: D): R = + visitConstantDescriptor(booleanConstantDescriptor, data) + fun visitVariableReference(variableReference: VariableReference, data: D): R = visitValue(variableReference, data) - fun visitBooleanVariableReference(booleanVariableReference: BooleanVariableReference, data: D): R = visitVariableReference(booleanVariableReference, data) + fun visitBooleanVariableReference(booleanVariableReference: BooleanVariableReference, data: D): R = + visitVariableReference(booleanVariableReference, data) } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/Effects.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/Effects.kt index c07b00cc04b..721336efd39 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/Effects.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/Effects.kt @@ -35,7 +35,7 @@ import org.jetbrains.kotlin.contracts.description.expressions.VariableReference */ class ConditionalEffectDeclaration(val effect: EffectDeclaration, val condition: BooleanExpression) : EffectDeclaration { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitConditionalEffectDeclaration(this, data) + contractDescriptionVisitor.visitConditionalEffectDeclaration(this, data) } @@ -44,7 +44,7 @@ class ConditionalEffectDeclaration(val effect: EffectDeclaration, val condition: */ class ReturnsEffectDeclaration(val value: ConstantReference) : EffectDeclaration { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitReturnsEffectDeclaration(this, data) + contractDescriptionVisitor.visitReturnsEffectDeclaration(this, data) } @@ -55,7 +55,7 @@ class ReturnsEffectDeclaration(val value: ConstantReference) : EffectDeclaration */ class CallsEffectDeclaration(val variableReference: VariableReference, val kind: InvocationKind) : EffectDeclaration { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitCallsEffectDeclaration(this, data) + contractDescriptionVisitor.visitCallsEffectDeclaration(this, data) } enum class InvocationKind { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/LazyContractProvider.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/LazyContractProvider.kt index f6b14587b22..8b68fc5c902 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/LazyContractProvider.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/LazyContractProvider.kt @@ -46,7 +46,7 @@ class LazyContractProvider(private val computation: () -> Any?) : ContractProvid companion object { fun createInitialized(contract: ContractDescription?): LazyContractProvider = - LazyContractProvider({}).apply { setContractDescription(contract) } + LazyContractProvider({}).apply { setContractDescription(contract) } } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/LogicalCombinators.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/LogicalCombinators.kt index 84da555c71d..94b5e32f7a3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/LogicalCombinators.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/LogicalCombinators.kt @@ -21,15 +21,15 @@ import org.jetbrains.kotlin.contracts.description.ContractDescriptionVisitor class LogicalOr(val left: BooleanExpression, val right: BooleanExpression) : BooleanExpression { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitLogicalOr(this, data) + contractDescriptionVisitor.visitLogicalOr(this, data) } class LogicalAnd(val left: BooleanExpression, val right: BooleanExpression) : BooleanExpression { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitLogicalAnd(this, data) + contractDescriptionVisitor.visitLogicalAnd(this, data) } class LogicalNot(val arg: BooleanExpression) : BooleanExpression { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitLogicalNot(this, data) + contractDescriptionVisitor.visitLogicalNot(this, data) } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/Predicates.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/Predicates.kt index 988ee481b62..9bb3364e5c5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/Predicates.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/Predicates.kt @@ -22,14 +22,14 @@ import org.jetbrains.kotlin.types.KotlinType class IsInstancePredicate(val arg: VariableReference, val type: KotlinType, val isNegated: Boolean) : BooleanExpression { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitIsInstancePredicate(this, data) + contractDescriptionVisitor.visitIsInstancePredicate(this, data) fun negated(): IsInstancePredicate = IsInstancePredicate(arg, type, isNegated.not()) } class IsNullPredicate(val arg: VariableReference, val isNegated: Boolean) : BooleanExpression { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitIsNullPredicate(this, data) + contractDescriptionVisitor.visitIsNullPredicate(this, data) fun negated(): IsNullPredicate = IsNullPredicate(arg, isNegated.not()) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/Values.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/Values.kt index 34b0315c3f3..21a752c33c9 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/Values.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/expressions/Values.kt @@ -24,12 +24,12 @@ import org.jetbrains.kotlin.descriptors.ParameterDescriptor interface ContractDescriptionValue : ContractDescriptionElement { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitValue(this, data) + contractDescriptionVisitor.visitValue(this, data) } open class ConstantReference(val name: String) : ContractDescriptionValue { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitConstantDescriptor(this, data) + contractDescriptionVisitor.visitConstantDescriptor(this, data) companion object { val NULL = ConstantReference("NULL") @@ -40,7 +40,7 @@ open class ConstantReference(val name: String) : ContractDescriptionValue { class BooleanConstantReference(name: String) : ConstantReference(name), BooleanExpression { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitBooleanConstantDescriptor(this, data) + contractDescriptionVisitor.visitBooleanConstantDescriptor(this, data) companion object { val TRUE = BooleanConstantReference("TRUE") @@ -50,10 +50,10 @@ class BooleanConstantReference(name: String) : ConstantReference(name), BooleanE open class VariableReference(val descriptor: ParameterDescriptor) : ContractDescriptionValue { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D) = - contractDescriptionVisitor.visitVariableReference(this, data) + contractDescriptionVisitor.visitVariableReference(this, data) } class BooleanVariableReference(descriptor: ParameterDescriptor) : VariableReference(descriptor), BooleanExpression { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = - contractDescriptionVisitor.visitBooleanVariableReference(this, data) + contractDescriptionVisitor.visitBooleanVariableReference(this, data) } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ConditionInterpreter.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ConditionInterpreter.kt index 693e35098b6..6e53195ec31 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ConditionInterpreter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ConditionInterpreter.kt @@ -22,7 +22,8 @@ import org.jetbrains.kotlin.contracts.model.ESExpression import org.jetbrains.kotlin.contracts.model.functors.IsFunctor import org.jetbrains.kotlin.contracts.model.structure.* -internal class ConditionInterpreter(private val dispatcher: ContractInterpretationDispatcher) : ContractDescriptionVisitor { +internal class ConditionInterpreter(private val dispatcher: ContractInterpretationDispatcher) : + ContractDescriptionVisitor { override fun visitLogicalOr(logicalOr: LogicalOr, data: Unit): ESExpression? { val left = logicalOr.left.accept(this, data) ?: return null val right = logicalOr.right.accept(this, data) ?: return null @@ -51,8 +52,8 @@ internal class ConditionInterpreter(private val dispatcher: ContractInterpretati } override fun visitBooleanConstantDescriptor(booleanConstantDescriptor: BooleanConstantReference, data: Unit): ESExpression? = - dispatcher.interpretConstant(booleanConstantDescriptor) + dispatcher.interpretConstant(booleanConstantDescriptor) override fun visitBooleanVariableReference(booleanVariableReference: BooleanVariableReference, data: Unit): ESExpression? = - dispatcher.interpretVariable(booleanVariableReference) + dispatcher.interpretVariable(booleanVariableReference) } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ConstantValuesInterpreter.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ConstantValuesInterpreter.kt index d9b3cad1af3..d228050f6d2 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ConstantValuesInterpreter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ConstantValuesInterpreter.kt @@ -25,7 +25,7 @@ internal class ConstantValuesInterpreter { fun interpretConstant(constantReference: ConstantReference): ESConstant? = when (constantReference) { BooleanConstantReference.TRUE -> true.lift() BooleanConstantReference.FALSE -> false.lift() - ConstantReference.NULL-> ESConstant.NULL + ConstantReference.NULL -> ESConstant.NULL ConstantReference.NOT_NULL -> ESConstant.NOT_NULL ConstantReference.WILDCARD -> ESConstant.WILDCARD else -> null diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ContractInterpretationDispatcher.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ContractInterpretationDispatcher.kt index 128f457b247..2e2db4d8752 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ContractInterpretationDispatcher.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/interpretation/ContractInterpretationDispatcher.kt @@ -35,9 +35,10 @@ class ContractInterpretationDispatcher { private val conditionInterpreter = ConditionInterpreter(this) private val conditionalEffectInterpreter = ConditionalEffectInterpreter(this) private val effectsInterpreters: List = listOf( - ReturnsEffectInterpreter(this), - CallsEffectInterpreter(this) + ReturnsEffectInterpreter(this), + CallsEffectInterpreter(this) ) + fun resolveFunctor(functionDescriptor: FunctionDescriptor): Functor? { val contractDescriptor = functionDescriptor.getUserData(ContractProviderKey)?.getContractDescription() ?: return null return convertContractDescriptorToFunctor(contractDescriptor) @@ -47,8 +48,7 @@ class ContractInterpretationDispatcher { val resultingClauses = contractDescription.effects.map { effect -> if (effect is ConditionalEffectDeclaration) { conditionalEffectInterpreter.interpret(effect) ?: return null - } - else { + } else { effectsInterpreters.mapNotNull { it.tryInterpret(effect) }.singleOrNull() ?: return null } } @@ -62,10 +62,10 @@ class ContractInterpretationDispatcher { } internal fun interpretConstant(constantReference: ConstantReference): ESConstant? = - constantsInterpreter.interpretConstant(constantReference) + constantsInterpreter.interpretConstant(constantReference) internal fun interpretCondition(booleanExpression: BooleanExpression): ESExpression? = - booleanExpression.accept(conditionInterpreter, Unit) + booleanExpression.accept(conditionInterpreter, Unit) internal fun interpretVariable(variableReference: VariableReference): ESVariable? = ESVariable(variableReference.descriptor) } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/MutableContextInfo.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/MutableContextInfo.kt index f44ff2c0359..22cbb213ca3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/MutableContextInfo.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/MutableContextInfo.kt @@ -29,20 +29,20 @@ import org.jetbrains.kotlin.types.KotlinType * Also, it's abstracted away from PSI */ class MutableContextInfo private constructor( - val firedEffects: MutableList, - val subtypes: MutableMap>, - val notSubtypes: MutableMap>, - val equalValues: MutableMap>, - val notEqualValues: MutableMap> + val firedEffects: MutableList, + val subtypes: MutableMap>, + val notSubtypes: MutableMap>, + val equalValues: MutableMap>, + val notEqualValues: MutableMap> ) { companion object { val EMPTY: MutableContextInfo get() = MutableContextInfo( - firedEffects = mutableListOf(), - subtypes = mutableMapOf(), - notSubtypes = mutableMapOf(), - equalValues = mutableMapOf(), - notEqualValues = mutableMapOf() + firedEffects = mutableListOf(), + subtypes = mutableMapOf(), + notSubtypes = mutableMapOf(), + equalValues = mutableMapOf(), + notEqualValues = mutableMapOf() ) } @@ -63,19 +63,19 @@ class MutableContextInfo private constructor( fun fire(effect: ESEffect) = apply { firedEffects += effect } fun or(other: MutableContextInfo): MutableContextInfo = MutableContextInfo( - firedEffects = firedEffects.intersect(other.firedEffects).toMutableList(), - subtypes = subtypes.intersect(other.subtypes), - notSubtypes = notSubtypes.intersect(other.notSubtypes), - equalValues = equalValues.intersect(other.equalValues), - notEqualValues = notEqualValues.intersect(other.notEqualValues) + firedEffects = firedEffects.intersect(other.firedEffects).toMutableList(), + subtypes = subtypes.intersect(other.subtypes), + notSubtypes = notSubtypes.intersect(other.notSubtypes), + equalValues = equalValues.intersect(other.equalValues), + notEqualValues = notEqualValues.intersect(other.notEqualValues) ) fun and(other: MutableContextInfo): MutableContextInfo = MutableContextInfo( - firedEffects = firedEffects.union(other.firedEffects).toMutableList(), - subtypes = subtypes.union(other.subtypes), - notSubtypes = notSubtypes.union(other.notSubtypes), - equalValues = equalValues.union(other.equalValues), - notEqualValues = notEqualValues.union(other.notEqualValues) + firedEffects = firedEffects.union(other.firedEffects).toMutableList(), + subtypes = subtypes.union(other.subtypes), + notSubtypes = notSubtypes.union(other.notSubtypes), + equalValues = equalValues.union(other.equalValues), + notEqualValues = notEqualValues.union(other.notEqualValues) ) private fun MutableMap>.intersect(that: MutableMap>): MutableMap> { @@ -120,7 +120,7 @@ class MutableContextInfo private constructor( } append("Fired effects: ") - append(info.firedEffects.joinToString(separator = ", " )) + append(info.firedEffects.joinToString(separator = ", ")) appendln("") subtypes.printMapEntriesWithSeparator("is") diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractBinaryFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractBinaryFunctor.kt index 880f832e020..a21b2200c27 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractBinaryFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractBinaryFunctor.kt @@ -56,5 +56,8 @@ abstract class AbstractBinaryFunctor : AbstractReducingFunctor() { } protected abstract fun invokeWithConstant(computation: Computation, constant: ESConstant): List - protected abstract fun invokeWithReturningEffects(left: List, right: List): List + protected abstract fun invokeWithReturningEffects( + left: List, + right: List + ): List } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractReducingFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractReducingFunctor.kt index a30d387ea4a..a6208c2638b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractReducingFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AbstractReducingFunctor.kt @@ -30,5 +30,5 @@ abstract class AbstractReducingFunctor : Functor { override fun invokeWithArguments(arguments: List): List = reducer.reduceEffects(doInvocation(arguments)) - abstract protected fun doInvocation(arguments: List): List + protected abstract fun doInvocation(arguments: List): List } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AndFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AndFunctor.kt index 5e253a68d9b..5f22925e5cc 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AndFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/AndFunctor.kt @@ -30,7 +30,7 @@ class AndFunctor : AbstractBinaryFunctor() { ESConstant.TRUE -> computation.effects ESConstant.FALSE -> emptyList() - // This means that expression isn't typechecked properly + // This means that expression isn't typechecked properly else -> computation.effects } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/EqualsFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/EqualsFunctor.kt index 90f1fa7ef07..7f94b11c81e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/EqualsFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/EqualsFunctor.kt @@ -84,7 +84,11 @@ class EqualsFunctor(val isNegated: Boolean) : AbstractReducingFunctor() { resultingClauses.add(trueClause) } - if (effect.simpleEffect.value != constant && effect.simpleEffect.value is ESConstant && isSafeToProduceFalse(call, effect.simpleEffect.value, constant)) { + if (effect.simpleEffect.value != constant && effect.simpleEffect.value is ESConstant && isSafeToProduceFalse( + call, + effect.simpleEffect.value, + constant + )) { val falseClause = ConditionalEffect(effect.condition, ESReturns(isNegated.lift())) resultingClauses.add(falseClause) } @@ -96,10 +100,10 @@ class EqualsFunctor(val isNegated: Boolean) : AbstractReducingFunctor() { // It is safe to produce false if we're comparing types which are isomorphic to Boolean. For such types we can be sure, that // if leftConstant != rightConstant, then this is the only way to produce 'false'. private fun isSafeToProduceFalse(leftCall: Computation, leftConstant: ESConstant, rightConstant: ESConstant): Boolean = when { - // Comparison of Boolean + // Comparison of Boolean KotlinBuiltIns.isBoolean(rightConstant.type) && leftCall.type != null && KotlinBuiltIns.isBoolean(leftCall.type!!) -> true - // Comparison of NULL/NOT_NULL, which is essentially Boolean + // Comparison of NULL/NOT_NULL, which is essentially Boolean leftConstant.isNullConstant() && rightConstant.isNullConstant() -> true else -> false @@ -107,8 +111,8 @@ class EqualsFunctor(val isNegated: Boolean) : AbstractReducingFunctor() { private fun equateValues(left: ESValue, right: ESValue): List { return listOf( - ConditionalEffect(ESEqual(left, right, isNegated), ESReturns(true.lift())), - ConditionalEffect(ESEqual(left, right, isNegated.not()), ESReturns(false.lift())) + ConditionalEffect(ESEqual(left, right, isNegated), ESReturns(true.lift())), + ConditionalEffect(ESEqual(left, right, isNegated.not()), ESReturns(false.lift())) ) } } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/FunctorsUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/FunctorsUtils.kt index 16872e09315..e4ab6b7fe3f 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/FunctorsUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/FunctorsUtils.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.contracts.model.ESExpression * Applies [operation] to [first] and [second] if both not-null, otherwise returns null */ internal fun applyIfBothNotNull(first: F?, second: S?, operation: (F, S) -> R): R? = - if (first == null || second == null) null else operation(first, second) + if (first == null || second == null) null else operation(first, second) /** * If both [first] and [second] are null, then return null @@ -40,15 +40,18 @@ internal fun applyWithDefault(first: F?, second: S?, operation } internal fun foldConditionsWithOr(list: List): ESExpression? = - if (list.isEmpty()) - null - else - list.map { it.condition }.reduce { acc, condition -> ESOr(acc, condition) } + if (list.isEmpty()) + null + else + list.map { it.condition }.reduce { acc, condition -> ESOr(acc, condition) } /** * Places all clauses that equal to `firstModel` into first list, and all clauses that equal to `secondModel` into second list */ -internal fun List.strictPartition(firstModel: ESEffect, secondModel: ESEffect): Pair, List> { +internal fun List.strictPartition( + firstModel: ESEffect, + secondModel: ESEffect +): Pair, List> { val first = mutableListOf() val second = mutableListOf() diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/OrFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/OrFunctor.kt index 02b4df96956..39675379b07 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/OrFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/OrFunctor.kt @@ -30,7 +30,7 @@ class OrFunctor : AbstractBinaryFunctor() { ESConstant.FALSE -> computation.effects ESConstant.TRUE -> emptyList() - // This means that expression isn't typechecked properly + // This means that expression isn't typechecked properly else -> computation.effects } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/SubstitutingFunctor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/SubstitutingFunctor.kt index 35aa8fcfc59..456dd6178f4 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/SubstitutingFunctor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/functors/SubstitutingFunctor.kt @@ -30,11 +30,13 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ValueDescriptor import org.jetbrains.kotlin.utils.addIfNotNull -class SubstitutingFunctor(private val basicEffects: List, private val ownerFunction: FunctionDescriptor) : AbstractReducingFunctor() { +class SubstitutingFunctor(private val basicEffects: List, private val ownerFunction: FunctionDescriptor) : + AbstractReducingFunctor() { override fun doInvocation(arguments: List): List { if (basicEffects.isEmpty()) return emptyList() - val receiver = listOfNotNull(ownerFunction.dispatchReceiverParameter?.toESVariable(), ownerFunction.extensionReceiverParameter?.toESVariable()) + val receiver = + listOfNotNull(ownerFunction.dispatchReceiverParameter?.toESVariable(), ownerFunction.extensionReceiverParameter?.toESVariable()) val parameters = receiver + ownerFunction.valueParameters.map { it.toESVariable() } assert(parameters.size == arguments.size) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt index d74e233afef..648b1548b48 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.contracts.model.ESEffect import org.jetbrains.kotlin.contracts.model.ESValue import org.jetbrains.kotlin.contracts.model.SimpleEffect -data class ESCalls(val callable: ESValue, val kind: InvocationKind): SimpleEffect() { +data class ESCalls(val callable: ESValue, val kind: InvocationKind) : SimpleEffect() { override fun isImplies(other: ESEffect): Boolean? { if (other !is ESCalls) return null @@ -33,7 +33,7 @@ data class ESCalls(val callable: ESValue, val kind: InvocationKind): SimpleEffec } -data class ESReturns(val value: ESValue): SimpleEffect() { +data class ESReturns(val value: ESValue) : SimpleEffect() { override fun isImplies(other: ESEffect): Boolean? { if (other !is ESReturns) return null diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Operators.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Operators.kt index 73899fefc0d..8d96c281114 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Operators.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Operators.kt @@ -22,28 +22,28 @@ import org.jetbrains.kotlin.contracts.model.ESOperator import org.jetbrains.kotlin.contracts.model.ESValue import org.jetbrains.kotlin.contracts.model.functors.* -class ESAnd(val left: ESExpression, val right: ESExpression): ESOperator { +class ESAnd(val left: ESExpression, val right: ESExpression) : ESOperator { override val functor: AndFunctor = AndFunctor() override fun accept(visitor: ESExpressionVisitor): T = visitor.visitAnd(this) } -class ESOr(val left: ESExpression, val right: ESExpression): ESOperator { +class ESOr(val left: ESExpression, val right: ESExpression) : ESOperator { override val functor: OrFunctor = OrFunctor() override fun accept(visitor: ESExpressionVisitor): T = visitor.visitOr(this) } -class ESNot(val arg: ESExpression): ESOperator { +class ESNot(val arg: ESExpression) : ESOperator { override val functor = NotFunctor() override fun accept(visitor: ESExpressionVisitor): T = visitor.visitNot(this) } -class ESIs(val left: ESValue, override val functor: IsFunctor): ESOperator { +class ESIs(val left: ESValue, override val functor: IsFunctor) : ESOperator { val type = functor.type override fun accept(visitor: ESExpressionVisitor): T = visitor.visitIs(this) } -class ESEqual(val left: ESValue, val right: ESValue, isNegated: Boolean): ESOperator { +class ESEqual(val left: ESValue, val right: ESValue, isNegated: Boolean) : ESOperator { override val functor: EqualsFunctor = EqualsFunctor(isNegated) override fun accept(visitor: ESExpressionVisitor): T = visitor.visitEqual(this) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/InfoCollector.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/InfoCollector.kt index 39f13f0f2d2..4c3ba876898 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/InfoCollector.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/InfoCollector.kt @@ -24,7 +24,9 @@ class InfoCollector(private val observedEffect: ESEffect) : ESExpressionVisitor< private var isInverted: Boolean = false fun collectFromSchema(schema: List): MutableContextInfo = - schema.mapNotNull { collectFromEffect(it) }.fold(MutableContextInfo.EMPTY, { resultingInfo, clauseInfo -> resultingInfo.and(clauseInfo) }) + schema.mapNotNull { collectFromEffect(it) }.fold( + MutableContextInfo.EMPTY, + { resultingInfo, clauseInfo -> resultingInfo.and(clauseInfo) }) private fun collectFromEffect(effect: ESEffect): MutableContextInfo? { if (effect !is ConditionalEffect) { @@ -33,16 +35,19 @@ class InfoCollector(private val observedEffect: ESEffect) : ESExpressionVisitor< // Check for information from conditional effects return when (observedEffect.isImplies(effect.simpleEffect)) { - // observed effect implies clause's effect => clause's effect was fired => clause's condition is true + // observed effect implies clause's effect => clause's effect was fired => clause's condition is true true -> effect.condition.accept(this) - // Observed effect *may* or *doesn't* implies clause's - no useful information + // Observed effect *may* or *doesn't* implies clause's - no useful information null, false -> null } } override fun visitIs(isOperator: ESIs): MutableContextInfo = with(isOperator) { - if (functor.isNegated != isInverted) MutableContextInfo.EMPTY.notSubtype(left, type) else MutableContextInfo.EMPTY.subtype(left, type) + if (functor.isNegated != isInverted) MutableContextInfo.EMPTY.notSubtype(left, type) else MutableContextInfo.EMPTY.subtype( + left, + type + ) } override fun visitEqual(equal: ESEqual): MutableContextInfo = with(equal) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt index 8ab5453465c..c7397272531 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Reducer.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf */ class Reducer : ESExpressionVisitor { fun reduceEffects(schema: List): List = - schema.mapNotNull { reduceEffect(it) } + schema.mapNotNull { reduceEffect(it) } private fun reduceEffect(effect: ESEffect): ESEffect? { when (effect) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Substitutor.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Substitutor.kt index cc3d436c7af..8a0479d9088 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Substitutor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/visitors/Substitutor.kt @@ -54,8 +54,7 @@ class Substitutor(private val substitutions: Map) : ESE return CallComputation(DefaultBuiltIns.Instance.booleanType, or.functor.invokeWithArguments(left, right)) } - override fun visitVariable(esVariable: ESVariable): Computation? - = substitutions[esVariable] ?: esVariable + override fun visitVariable(esVariable: ESVariable): Computation? = substitutions[esVariable] ?: esVariable override fun visitConstant(esConstant: ESConstant): Computation? = esConstant } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt index 64a9b043105..6f2db27860e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinCallResolver.kt @@ -28,29 +28,35 @@ import java.lang.UnsupportedOperationException class KotlinCallResolver( - private val towerResolver: TowerResolver, - private val kotlinCallCompleter: KotlinCallCompleter, - private val overloadingConflictResolver: NewOverloadingConflictResolver, - private val callComponents: KotlinCallComponents + private val towerResolver: TowerResolver, + private val kotlinCallCompleter: KotlinCallCompleter, + private val overloadingConflictResolver: NewOverloadingConflictResolver, + private val callComponents: KotlinCallComponents ) { fun resolveCall( - scopeTower: ImplicitScopeTower, - resolutionCallbacks: KotlinResolutionCallbacks, - kotlinCall: KotlinCall, - expectedType: UnwrappedType?, - factoryProviderForInvoke: CandidateFactoryProviderForInvoke, - collectAllCandidates: Boolean + scopeTower: ImplicitScopeTower, + resolutionCallbacks: KotlinResolutionCallbacks, + kotlinCall: KotlinCall, + expectedType: UnwrappedType?, + factoryProviderForInvoke: CandidateFactoryProviderForInvoke, + collectAllCandidates: Boolean ): CallResolutionResult { kotlinCall.checkCallInvariants() val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall) - val processor = when(kotlinCall.callKind) { + val processor = when (kotlinCall.callKind) { KotlinCallKind.VARIABLE -> { createVariableAndObjectProcessor(scopeTower, kotlinCall.name, candidateFactory, kotlinCall.explicitReceiver?.receiver) } KotlinCallKind.FUNCTION -> { - createFunctionProcessor(scopeTower, kotlinCall.name, candidateFactory, factoryProviderForInvoke, kotlinCall.explicitReceiver?.receiver) + createFunctionProcessor( + scopeTower, + kotlinCall.name, + candidateFactory, + factoryProviderForInvoke, + kotlinCall.explicitReceiver?.receiver + ) } KotlinCallKind.UNSUPPORTED -> throw UnsupportedOperationException() } @@ -60,18 +66,23 @@ class KotlinCallResolver( return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks) } - val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = kotlinCall.callKind != KotlinCallKind.UNSUPPORTED, name = kotlinCall.name) + val candidates = towerResolver.runResolve( + scopeTower, + processor, + useOrder = kotlinCall.callKind != KotlinCallKind.UNSUPPORTED, + name = kotlinCall.name + ) return choseMostSpecific(candidateFactory, resolutionCallbacks, expectedType, candidates) } fun resolveGivenCandidates( - scopeTower: ImplicitScopeTower, - resolutionCallbacks: KotlinResolutionCallbacks, - kotlinCall: KotlinCall, - expectedType: UnwrappedType?, - givenCandidates: Collection, - collectAllCandidates: Boolean + scopeTower: ImplicitScopeTower, + resolutionCallbacks: KotlinResolutionCallbacks, + kotlinCall: KotlinCall, + expectedType: UnwrappedType?, + givenCandidates: Collection, + collectAllCandidates: Boolean ): CallResolutionResult { kotlinCall.checkCallInvariants() val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall) @@ -79,23 +90,27 @@ class KotlinCallResolver( val resolutionCandidates = givenCandidates.map { candidateFactory.createCandidate(it).forceResolution() } if (collectAllCandidates) { - val allCandidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates), - TowerResolver.AllCandidatesCollector(), - useOrder = false) + val allCandidates = towerResolver.runWithEmptyTowerData( + KnownResultProcessor(resolutionCandidates), + TowerResolver.AllCandidatesCollector(), + useOrder = false + ) return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks) } - val candidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates), - TowerResolver.SuccessfulResultCollector(), - useOrder = true) + val candidates = towerResolver.runWithEmptyTowerData( + KnownResultProcessor(resolutionCandidates), + TowerResolver.SuccessfulResultCollector(), + useOrder = true + ) return choseMostSpecific(candidateFactory, resolutionCallbacks, expectedType, candidates) } private fun choseMostSpecific( - candidateFactory: SimpleCandidateFactory, - resolutionCallbacks: KotlinResolutionCallbacks, - expectedType: UnwrappedType?, - candidates: Collection + candidateFactory: SimpleCandidateFactory, + resolutionCallbacks: KotlinResolutionCallbacks, + expectedType: UnwrappedType?, + candidates: Collection ): CallResolutionResult { val isDebuggerContext = candidateFactory.scopeTower.isDebuggerContext @@ -108,10 +123,11 @@ class KotlinCallResolver( } val maximallySpecificCandidates = overloadingConflictResolver.chooseMaximallySpecificCandidates( - refinedCandidates, - CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, - discriminateGenerics = true, // todo - isDebuggerContext = isDebuggerContext) + refinedCandidates, + CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, + discriminateGenerics = true, // todo + isDebuggerContext = isDebuggerContext + ) return kotlinCallCompleter.runCompletion(candidateFactory, maximallySpecificCandidates, expectedType, resolutionCallbacks) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt index 999c2af7cdd..5cbc4ff2c48 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt @@ -89,7 +89,7 @@ object NewCommonSuperTypeCalculator { private fun commonSuperTypeForNotNullTypes(types: List, depth: Int): SimpleType { val uniqueTypes = types.uniquify() val filteredType = uniqueTypes.filterNot { type -> - uniqueTypes.any { other -> type != other && NewKotlinTypeChecker.isSubtypeOf(type, other)} + uniqueTypes.any { other -> type != other && NewKotlinTypeChecker.isSubtypeOf(type, other) } } // seems like all types are equal if (filteredType.isEmpty()) return uniqueTypes.first() @@ -125,11 +125,16 @@ object NewCommonSuperTypeCalculator { } private fun superTypeWithGivenConstructor( - types: List, - constructor: TypeConstructor, - depth: Int + types: List, + constructor: TypeConstructor, + depth: Int ): SimpleType { - if (constructor.parameters.isEmpty()) return KotlinTypeFactory.simpleType(Annotations.EMPTY, constructor, emptyList(), nullable = false) + if (constructor.parameters.isEmpty()) return KotlinTypeFactory.simpleType( + Annotations.EMPTY, + constructor, + emptyList(), + nullable = false + ) val typeCheckerContext = TypeCheckerContext(false) @@ -158,12 +163,11 @@ object NewCommonSuperTypeCalculator { } val argument = - if (thereIsStar || typeProjections.isEmpty()) { - StarProjectionImpl(parameter) - } - else { - calculateArgument(parameter, typeProjections, depth) - } + if (thereIsStar || typeProjections.isEmpty()) { + StarProjectionImpl(parameter) + } else { + calculateArgument(parameter, typeProjections, depth) + } arguments.add(argument) } @@ -185,20 +189,17 @@ object NewCommonSuperTypeCalculator { val asOut: Boolean if (parameter.variance != Variance.INVARIANT) { asOut = parameter.variance == Variance.OUT_VARIANCE - } - else { + } else { val thereIsOut = arguments.any { it.projectionKind == Variance.OUT_VARIANCE } val thereIsIn = arguments.any { it.projectionKind == Variance.IN_VARIANCE } if (thereIsOut) { if (thereIsIn) { // CS(Inv, Inv) = Inv<*> return StarProjectionImpl(parameter) - } - else { + } else { asOut = true } - } - else { + } else { asOut = !thereIsIn } } @@ -207,11 +208,16 @@ object NewCommonSuperTypeCalculator { // CS(In, In) = In if (asOut) { val type = commonSuperType(arguments.map { it.type.unwrap() }, depth + 1) - return if (parameter.variance != Variance.INVARIANT) return type.asTypeProjection() else TypeProjectionImpl(Variance.OUT_VARIANCE, type) - } - else { + return if (parameter.variance != Variance.INVARIANT) return type.asTypeProjection() else TypeProjectionImpl( + Variance.OUT_VARIANCE, + type + ) + } else { val type = intersectTypes(arguments.map { it.type.unwrap() }) - return if (parameter.variance != Variance.INVARIANT) return type.asTypeProjection() else TypeProjectionImpl(Variance.IN_VARIANCE, type) + return if (parameter.variance != Variance.INVARIANT) return type.asTypeProjection() else TypeProjectionImpl( + Variance.IN_VARIANCE, + type + ) } } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/AdditionalDiagnosticReporter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/AdditionalDiagnosticReporter.kt index b07ceaf93f5..99bd2a05188 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/AdditionalDiagnosticReporter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/AdditionalDiagnosticReporter.kt @@ -29,18 +29,18 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker class AdditionalDiagnosticReporter(private val languageVersionSettings: LanguageVersionSettings) { fun reportAdditionalDiagnostics( - candidate: ResolvedCallAtom, - resultingDescriptor: CallableDescriptor, - kotlinDiagnosticsHolder: KotlinDiagnosticsHolder, - diagnostics: Collection + candidate: ResolvedCallAtom, + resultingDescriptor: CallableDescriptor, + kotlinDiagnosticsHolder: KotlinDiagnosticsHolder, + diagnostics: Collection ) { reportSmartCasts(candidate, resultingDescriptor, kotlinDiagnosticsHolder, diagnostics) } private fun createSmartCastDiagnostic( - candidate: ResolvedCallAtom, - argument: KotlinCallArgument, - expectedResultType: UnwrappedType + candidate: ResolvedCallAtom, + argument: KotlinCallArgument, + expectedResultType: UnwrappedType ): SmartCastDiagnostic? { if (argument !is ExpressionKotlinCallArgument) return null if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(argument.receiver.receiverValue.type, expectedResultType)) { @@ -50,10 +50,10 @@ class AdditionalDiagnosticReporter(private val languageVersionSettings: Language } private fun reportSmartCastOnReceiver( - candidate: ResolvedCallAtom, - receiver: SimpleKotlinCallArgument?, - parameter: ReceiverParameterDescriptor?, - diagnostics: Collection + candidate: ResolvedCallAtom, + receiver: SimpleKotlinCallArgument?, + parameter: ReceiverParameterDescriptor?, + diagnostics: Collection ): SmartCastDiagnostic? { if (receiver == null || parameter == null) return null val expectedType = parameter.type.unwrap().let { if (receiver.isSafeCall) it.makeNullableAsSpecified(true) else it } @@ -65,24 +65,34 @@ class AdditionalDiagnosticReporter(private val languageVersionSettings: Language diagnostics.filterIsInstance().none { it.receiver == receiver } - && - diagnostics.filterIsInstance().none { - it.argument == receiver - } + && + diagnostics.filterIsInstance().none { + it.argument == receiver + } } } private fun reportSmartCasts( - candidate: ResolvedCallAtom, - resultingDescriptor: CallableDescriptor, - kotlinDiagnosticsHolder: KotlinDiagnosticsHolder, - diagnostics: Collection + candidate: ResolvedCallAtom, + resultingDescriptor: CallableDescriptor, + kotlinDiagnosticsHolder: KotlinDiagnosticsHolder, + diagnostics: Collection ) { kotlinDiagnosticsHolder.addDiagnosticIfNotNull( - reportSmartCastOnReceiver(candidate, candidate.extensionReceiverArgument, resultingDescriptor.extensionReceiverParameter, diagnostics) + reportSmartCastOnReceiver( + candidate, + candidate.extensionReceiverArgument, + resultingDescriptor.extensionReceiverParameter, + diagnostics + ) ) kotlinDiagnosticsHolder.addDiagnosticIfNotNull( - reportSmartCastOnReceiver(candidate, candidate.dispatchReceiverArgument, resultingDescriptor.dispatchReceiverParameter, diagnostics) + reportSmartCastOnReceiver( + candidate, + candidate.dispatchReceiverArgument, + resultingDescriptor.dispatchReceiverParameter, + diagnostics + ) ) for (parameter in resultingDescriptor.valueParameters) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt index ee0f0b2a314..fc779c082a8 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsToParametersMapper.kt @@ -27,29 +27,28 @@ import java.util.* class ArgumentsToParametersMapper { data class ArgumentMapping( - // This map should be ordered by arguments as written, e.g.: - // fun foo(a: Int, b: Int) {} - // foo(b = bar(), a = qux()) - // parameterToCallArgumentMap.values() should be [ 'bar()', 'foo()' ] - val parameterToCallArgumentMap: Map, - val diagnostics: List + // This map should be ordered by arguments as written, e.g.: + // fun foo(a: Int, b: Int) {} + // foo(b = bar(), a = qux()) + // parameterToCallArgumentMap.values() should be [ 'bar()', 'foo()' ] + val parameterToCallArgumentMap: Map, + val diagnostics: List ) val EmptyArgumentMapping = ArgumentMapping(emptyMap(), emptyList()) fun mapArguments(call: KotlinCall, descriptor: CallableDescriptor): ArgumentMapping = - mapArguments(call.argumentsInParenthesis, call.externalArgument, descriptor) + mapArguments(call.argumentsInParenthesis, call.externalArgument, descriptor) fun mapArguments( - argumentsInParenthesis: List, - externalArgument: KotlinCallArgument?, - descriptor: CallableDescriptor + argumentsInParenthesis: List, + externalArgument: KotlinCallArgument?, + descriptor: CallableDescriptor ): ArgumentMapping { // optimization for case of variable if (argumentsInParenthesis.isEmpty() && externalArgument == null && descriptor.valueParameters.isEmpty()) { return EmptyArgumentMapping - } - else { + } else { val processor = CallArgumentProcessor(descriptor) processor.processArgumentsInParenthesis(argumentsInParenthesis) @@ -171,8 +170,7 @@ class ArgumentsToParametersMapper { return valueParameter } } - } - else { + } else { parameter.getOverriddenParameterWithOtherName()?.let { addDiagnostic(NameForAmbiguousParameter(argument, parameter, it)) } @@ -209,7 +207,7 @@ class ArgumentsToParametersMapper { completeVarargPositionArguments() } } - + fun processExternalArgument(externalArgument: KotlinCallArgument) { val lastParameter = parameters.lastOrNull() if (lastParameter == null) { @@ -237,8 +235,7 @@ class ArgumentsToParametersMapper { if (!parameter.isVararg) { if (resolvedArgument !is ResolvedCallArgument.SimpleArgument) { error("Incorrect resolved argument for parameter $parameter :$resolvedArgument") - } - else { + } else { if (resolvedArgument.callArgument.isSpread) { addDiagnostic(NonVarargSpread(resolvedArgument.callArgument)) } @@ -250,11 +247,9 @@ class ArgumentsToParametersMapper { if (!result.containsKey(parameter.original)) { if (parameter.hasDefaultValue()) { result[parameter.original] = ResolvedCallArgument.DefaultArgument - } - else if (parameter.isVararg) { + } else if (parameter.isVararg) { result[parameter.original] = ResolvedCallArgument.VarargArgument(emptyList()) - } - else { + } else { addDiagnostic(NoValueForParameter(parameter, descriptor)) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt index 05fcce0bf3e..47b27234bfa 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ArgumentsUtils.kt @@ -32,7 +32,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs internal fun unexpectedArgument(argument: KotlinCallArgument): Nothing = - error("Unexpected argument type: $argument, ${argument.javaClass.canonicalName}.") + error("Unexpected argument type: $argument, ${argument.javaClass.canonicalName}.") // if expression is not stable and has smart casts, then we create this type internal val ReceiverValueWithSmartCastInfo.unstableType: UnwrappedType? @@ -49,19 +49,18 @@ internal val ReceiverValueWithSmartCastInfo.stableType: UnwrappedType } internal fun KotlinCallArgument.getExpectedType(parameter: ParameterDescriptor, languageVersionSettings: LanguageVersionSettings) = - if (this.isSpread || this.isArrayAssignedAsNamedArgumentInAnnotation(parameter, languageVersionSettings)) { - parameter.type.unwrap() - } - else { - parameter.safeAs()?.varargElementType?.unwrap() ?: parameter.type.unwrap() - } + if (this.isSpread || this.isArrayAssignedAsNamedArgumentInAnnotation(parameter, languageVersionSettings)) { + parameter.type.unwrap() + } else { + parameter.safeAs()?.varargElementType?.unwrap() ?: parameter.type.unwrap() + } val ValueParameterDescriptor.isVararg: Boolean get() = varargElementType != null val ParameterDescriptor.isVararg: Boolean get() = this.safeAs()?.isVararg ?: false private fun KotlinCallArgument.isArrayAssignedAsNamedArgumentInAnnotation( - parameter: ParameterDescriptor, - languageVersionSettings: LanguageVersionSettings + parameter: ParameterDescriptor, + languageVersionSettings: LanguageVersionSettings ): Boolean { if (!languageVersionSettings.supportsFeature(LanguageFeature.AssigningArraysToVarargsInNamedFormInAnnotations)) return false diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt index d8b756a9a9c..c4319713864 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolution.kt @@ -46,7 +46,8 @@ sealed class CallableReceiver(val receiver: ReceiverValueWithSmartCastInfo) { class UnboundReference(val qualifier: QualifierReceiver, receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver) class BoundValueReference(val qualifier: QualifierReceiver, receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver) class ScopeReceiver(receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver) - class ExplicitValueReceiver(val lhsArgument: SimpleKotlinCallArgument, receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver) + class ExplicitValueReceiver(val lhsArgument: SimpleKotlinCallArgument, receiver: ReceiverValueWithSmartCastInfo) : + CallableReceiver(receiver) } // todo investigate similar code in CheckVisibility @@ -62,13 +63,13 @@ private val CallableReceiver.asReceiverValueForVisibilityChecks: ReceiverValue * For class B with companion object B::companionM dispatchReceiver = BoundValueReference */ class CallableReferenceCandidate( - val candidate: CallableDescriptor, - val dispatchReceiver: CallableReceiver?, - val extensionReceiver: CallableReceiver?, - val explicitReceiverKind: ExplicitReceiverKind, - val reflectionCandidateType: UnwrappedType, - val numDefaults: Int, - val diagnostics: List + val candidate: CallableDescriptor, + val dispatchReceiver: CallableReceiver?, + val extensionReceiver: CallableReceiver?, + val explicitReceiverKind: ExplicitReceiverKind, + val reflectionCandidateType: UnwrappedType, + val numDefaults: Int, + val diagnostics: List ) : Candidate { override val resultingApplicability = getResultApplicability(diagnostics) override val isSuccessful get() = resultingApplicability.isSuccess @@ -113,13 +114,13 @@ fun createCallableReferenceProcessor(factory: CallableReferencesCandidateFactory } fun ConstraintSystemOperation.checkCallableReference( - argument: CallableReferenceKotlinCallArgument, - dispatchReceiver: CallableReceiver?, - extensionReceiver: CallableReceiver?, - candidateDescriptor: CallableDescriptor, - reflectionCandidateType: UnwrappedType, - expectedType: UnwrappedType?, - ownerDescriptor: DeclarationDescriptor + argument: CallableReferenceKotlinCallArgument, + dispatchReceiver: CallableReceiver?, + extensionReceiver: CallableReceiver?, + candidateDescriptor: CallableDescriptor, + reflectionCandidateType: UnwrappedType, + expectedType: UnwrappedType?, + ownerDescriptor: DeclarationDescriptor ): Pair { val position = ArgumentConstraintPosition(argument) @@ -132,17 +133,19 @@ fun ConstraintSystemOperation.checkCallableReference( addReceiverConstraint(toFreshSubstitutor, dispatchReceiver, candidateDescriptor.dispatchReceiverParameter, position) addReceiverConstraint(toFreshSubstitutor, extensionReceiver, candidateDescriptor.extensionReceiverParameter, position) - val invisibleMember = Visibilities.findInvisibleMember(dispatchReceiver?.asReceiverValueForVisibilityChecks, - candidateDescriptor, ownerDescriptor) + val invisibleMember = Visibilities.findInvisibleMember( + dispatchReceiver?.asReceiverValueForVisibilityChecks, + candidateDescriptor, ownerDescriptor + ) return toFreshSubstitutor to invisibleMember?.let(::VisibilityError) } private fun ConstraintSystemOperation.addReceiverConstraint( - toFreshSubstitutor: FreshVariableNewTypeSubstitutor, - receiverArgument: CallableReceiver?, - receiverParameter: ReceiverParameterDescriptor?, - position: ArgumentConstraintPosition + toFreshSubstitutor: FreshVariableNewTypeSubstitutor, + receiverArgument: CallableReceiver?, + receiverParameter: ReceiverParameterDescriptor?, + position: ArgumentConstraintPosition ) { if (receiverArgument == null || receiverParameter == null) { assert(receiverArgument == null) { "Receiver argument should be null if parameter is: $receiverArgument" } @@ -156,41 +159,45 @@ private fun ConstraintSystemOperation.addReceiverConstraint( } class CallableReferencesCandidateFactory( - val argument: CallableReferenceKotlinCallArgument, - val callComponents: KotlinCallComponents, - val scopeTower: ImplicitScopeTower, - val compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit, - val expectedType: UnwrappedType? + val argument: CallableReferenceKotlinCallArgument, + val callComponents: KotlinCallComponents, + val scopeTower: ImplicitScopeTower, + val compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit, + val expectedType: UnwrappedType? ) : CandidateFactory { fun createCallableProcessor(explicitReceiver: DetailedReceiver?) = - createCallableReferenceProcessor(scopeTower, argument.rhsName, this, explicitReceiver) + createCallableReferenceProcessor(scopeTower, argument.rhsName, this, explicitReceiver) override fun createCandidate( - towerCandidate: CandidateWithBoundDispatchReceiver, - explicitReceiverKind: ExplicitReceiverKind, - extensionReceiver: ReceiverValueWithSmartCastInfo? + towerCandidate: CandidateWithBoundDispatchReceiver, + explicitReceiverKind: ExplicitReceiverKind, + extensionReceiver: ReceiverValueWithSmartCastInfo? ): CallableReferenceCandidate { - val dispatchCallableReceiver = towerCandidate.dispatchReceiver?.let { toCallableReceiver(it, explicitReceiverKind == DISPATCH_RECEIVER) } + val dispatchCallableReceiver = + towerCandidate.dispatchReceiver?.let { toCallableReceiver(it, explicitReceiverKind == DISPATCH_RECEIVER) } val extensionCallableReceiver = extensionReceiver?.let { toCallableReceiver(it, explicitReceiverKind == EXTENSION_RECEIVER) } val candidateDescriptor = towerCandidate.descriptor val diagnostics = SmartList() val (reflectionCandidateType, defaults) = buildReflectionType( - candidateDescriptor, - dispatchCallableReceiver, - extensionCallableReceiver, - expectedType) + candidateDescriptor, + dispatchCallableReceiver, + extensionCallableReceiver, + expectedType + ) if (defaults != 0) { diagnostics.add(CallableReferencesDefaultArgumentUsed(argument, candidateDescriptor, defaults)) } if (candidateDescriptor !is CallableMemberDescriptor) { - return CallableReferenceCandidate(candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver, - explicitReceiverKind, reflectionCandidateType, defaults, - listOf(NotCallableMemberReference(argument, candidateDescriptor))) + return CallableReferenceCandidate( + candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver, + explicitReceiverKind, reflectionCandidateType, defaults, + listOf(NotCallableMemberReference(argument, candidateDescriptor)) + ) } diagnostics.addAll(towerCandidate.diagnostics) @@ -200,22 +207,32 @@ class CallableReferencesCandidateFactory( if (it.hasContradiction) return@compatibilityChecker val (_, visibilityError) = it.checkCallableReference( - argument, dispatchCallableReceiver, extensionCallableReceiver, candidateDescriptor, - reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor) + argument, dispatchCallableReceiver, extensionCallableReceiver, candidateDescriptor, + reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor + ) diagnostics.addIfNotNull(visibilityError) - if (it.hasContradiction) diagnostics.add(CallableReferenceNotCompatible(argument, candidateDescriptor, expectedType, reflectionCandidateType)) + if (it.hasContradiction) diagnostics.add( + CallableReferenceNotCompatible( + argument, + candidateDescriptor, + expectedType, + reflectionCandidateType + ) + ) } - return CallableReferenceCandidate(candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver, - explicitReceiverKind, reflectionCandidateType, defaults, diagnostics) + return CallableReferenceCandidate( + candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver, + explicitReceiverKind, reflectionCandidateType, defaults, diagnostics + ) } private fun getArgumentAndReturnTypeUseMappingByExpectedType( - descriptor: FunctionDescriptor, - expectedType: UnwrappedType?, - unboundReceiverCount: Int + descriptor: FunctionDescriptor, + expectedType: UnwrappedType?, + unboundReceiverCount: Int ): Triple, CoercionStrategy, Int>? { val functionType = getFunctionTypeFromCallableReferenceExpectedType(expectedType) ?: return null @@ -223,7 +240,8 @@ class CallableReferencesCandidateFactory( if (expectedArgumentCount < 0) return null val fakeArguments = (0..(expectedArgumentCount - 1)).map { FakeKotlinCallArgumentForCallableReference(it) } - val argumentMapping = callComponents.argumentsToParametersMapper.mapArguments(fakeArguments, externalArgument = null, descriptor = descriptor) + val argumentMapping = + callComponents.argumentsToParametersMapper.mapArguments(fakeArguments, externalArgument = null, descriptor = descriptor) if (argumentMapping.diagnostics.any { !it.candidateApplicability.isSuccess }) return null /** @@ -253,10 +271,10 @@ class CallableReferencesCandidateFactory( } private fun buildReflectionType( - descriptor: CallableDescriptor, - dispatchReceiver: CallableReceiver?, - extensionReceiver: CallableReceiver?, - expectedType: UnwrappedType? + descriptor: CallableDescriptor, + dispatchReceiver: CallableReceiver?, + extensionReceiver: CallableReceiver?, + expectedType: UnwrappedType? ): Pair { val argumentsAndReceivers = ArrayList(descriptor.valueParameters.size + 2) @@ -268,30 +286,38 @@ class CallableReferencesCandidateFactory( } val descriptorReturnType = descriptor.returnType - ?: ErrorUtils.createErrorType("Error return type for descriptor: $descriptor") + ?: ErrorUtils.createErrorType("Error return type for descriptor: $descriptor") when (descriptor) { is PropertyDescriptor -> { val mutable = descriptor.isVar && run { val setter = descriptor.setter - setter == null || Visibilities.isVisible(dispatchReceiver?.asReceiverValueForVisibilityChecks, setter, - scopeTower.lexicalScope.ownerDescriptor) + setter == null || Visibilities.isVisible( + dispatchReceiver?.asReceiverValueForVisibilityChecks, setter, + scopeTower.lexicalScope.ownerDescriptor + ) } - return callComponents.reflectionTypes.getKPropertyType(Annotations.EMPTY, argumentsAndReceivers, descriptorReturnType, mutable) to 0 + return callComponents.reflectionTypes.getKPropertyType( + Annotations.EMPTY, + argumentsAndReceivers, + descriptorReturnType, + mutable + ) to 0 } is FunctionDescriptor -> { val returnType: KotlinType val defaults: Int - val argumentsAndExpectedTypeCoercion = getArgumentAndReturnTypeUseMappingByExpectedType(descriptor, expectedType, - unboundReceiverCount = argumentsAndReceivers.size) + val argumentsAndExpectedTypeCoercion = getArgumentAndReturnTypeUseMappingByExpectedType( + descriptor, expectedType, + unboundReceiverCount = argumentsAndReceivers.size + ) if (argumentsAndExpectedTypeCoercion == null) { descriptor.valueParameters.mapTo(argumentsAndReceivers) { it.type } returnType = descriptorReturnType defaults = 0 - } - else { + } else { val (arguments, coercion) = argumentsAndExpectedTypeCoercion defaults = argumentsAndExpectedTypeCoercion.third argumentsAndReceivers.addAll(arguments) @@ -299,8 +325,10 @@ class CallableReferencesCandidateFactory( returnType = if (coercion == CoercionStrategy.COERCION_TO_UNIT) descriptor.builtIns.unitType else descriptorReturnType } - return callComponents.reflectionTypes.getKFunctionType(Annotations.EMPTY, null, argumentsAndReceivers, null, - returnType, descriptor.builtIns) to defaults + return callComponents.reflectionTypes.getKFunctionType( + Annotations.EMPTY, null, argumentsAndReceivers, null, + returnType, descriptor.builtIns + ) to defaults } else -> error("Unsupported descriptor type: $descriptor") } @@ -315,8 +343,7 @@ class CallableReferencesCandidateFactory( is LHSResult.Type -> { if (lhsResult.qualifier.classValueReceiver?.type == receiver.receiverValue.type) { CallableReceiver.BoundValueReference(lhsResult.qualifier, receiver) - } - else { + } else { CallableReceiver.UnboundReference(lhsResult.qualifier, receiver) } } @@ -331,11 +358,9 @@ fun getFunctionTypeFromCallableReferenceExpectedType(expectedType: UnwrappedType return if (expectedType.isFunctionType) { expectedType - } - else if (ReflectionTypes.isNumberedKFunction(expectedType)) { + } else if (ReflectionTypes.isNumberedKFunction(expectedType)) { expectedType.immediateSupertypes().first { it.isFunctionType }.unwrap() - } - else { + } else { null } } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt index 1cbabcbd2ca..7e0d4955053 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt @@ -32,36 +32,36 @@ import org.jetbrains.kotlin.types.UnwrappedType class CallableReferenceOverloadConflictResolver( - builtIns: KotlinBuiltIns, - specificityComparator: TypeSpecificityComparator, - statelessCallbacks: KotlinResolutionStatelessCallbacks, - constraintInjector: ConstraintInjector + builtIns: KotlinBuiltIns, + specificityComparator: TypeSpecificityComparator, + statelessCallbacks: KotlinResolutionStatelessCallbacks, + constraintInjector: ConstraintInjector ) : OverloadingConflictResolver( - builtIns, - specificityComparator, - { it.candidate }, - { SimpleConstraintSystemImpl(constraintInjector, builtIns) }, - Companion::createFlatSignature, - { null }, - { statelessCallbacks.isDescriptorFromSource(it) } - ) { + builtIns, + specificityComparator, + { it.candidate }, + { SimpleConstraintSystemImpl(constraintInjector, builtIns) }, + Companion::createFlatSignature, + { null }, + { statelessCallbacks.isDescriptorFromSource(it) } +) { companion object { private fun createFlatSignature(candidate: CallableReferenceCandidate) = - FlatSignature.createFromReflectionType(candidate, candidate.candidate, candidate.numDefaults, candidate.reflectionCandidateType) + FlatSignature.createFromReflectionType(candidate, candidate.candidate, candidate.numDefaults, candidate.reflectionCandidateType) } } class CallableReferenceResolver( - private val towerResolver: TowerResolver, - private val callableReferenceOverloadConflictResolver: CallableReferenceOverloadConflictResolver, - private val callComponents: KotlinCallComponents + private val towerResolver: TowerResolver, + private val callableReferenceOverloadConflictResolver: CallableReferenceOverloadConflictResolver, + private val callComponents: KotlinCallComponents ) { fun processCallableReferenceArgument( - csBuilder: ConstraintSystemBuilder, - resolvedAtom: ResolvedCallableReferenceAtom, - diagnosticsHolder: KotlinDiagnosticsHolder + csBuilder: ConstraintSystemBuilder, + resolvedAtom: ResolvedCallableReferenceAtom, + diagnosticsHolder: KotlinDiagnosticsHolder ) { val argument = resolvedAtom.atom val expectedType = resolvedAtom.expectedType?.let { csBuilder.buildCurrentSubstitutor().safeSubstitute(it) } @@ -73,17 +73,17 @@ class CallableReferenceResolver( val chosenCandidate = candidates.singleOrNull() if (chosenCandidate != null) { val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) { - csBuilder.checkCallableReference(argument, dispatchReceiver, extensionReceiver, candidate, - reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor) + csBuilder.checkCallableReference( + argument, dispatchReceiver, extensionReceiver, candidate, + reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor + ) } diagnosticsHolder.addDiagnosticIfNotNull(diagnostic) chosenCandidate.freshSubstitutor = toFreshSubstitutor - } - else { + } else { if (candidates.isEmpty()) { diagnosticsHolder.addDiagnostic(NoneCallableReferenceCandidates(argument)) - } - else { + } else { diagnosticsHolder.addDiagnostic(CallableReferenceCandidatesAmbiguity(argument, candidates)) } } @@ -97,7 +97,7 @@ class CallableReferenceResolver( private fun buildResolvedKtArgument(lhsResult: LHSResult): ResolvedAtom? { if (lhsResult !is LHSResult.Expression) return null val lshCallArgument = lhsResult.lshCallArgument - return when(lshCallArgument) { + return when (lshCallArgument) { is SubKotlinCallArgument -> lshCallArgument.callResult is ExpressionKotlinCallArgument -> ResolvedExpressionAtom(lshCallArgument) else -> unexpectedArgument(lshCallArgument) @@ -105,19 +105,20 @@ class CallableReferenceResolver( } private fun runRHSResolution( - scopeTower: ImplicitScopeTower, - callableReference: CallableReferenceKotlinCallArgument, - expectedType: UnwrappedType?, // this type can have not fixed type variable inside - compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit // you can run anything throw this operation and all this operation will be rolled back + scopeTower: ImplicitScopeTower, + callableReference: CallableReferenceKotlinCallArgument, + expectedType: UnwrappedType?, // this type can have not fixed type variable inside + compatibilityChecker: ((ConstraintSystemOperation) -> Unit) -> Unit // you can run anything throw this operation and all this operation will be rolled back ): Set { val factory = CallableReferencesCandidateFactory(callableReference, callComponents, scopeTower, compatibilityChecker, expectedType) val processor = createCallableReferenceProcessor(factory) val candidates = towerResolver.runResolve(scopeTower, processor, useOrder = true, name = callableReference.rhsName) return callableReferenceOverloadConflictResolver.chooseMaximallySpecificCandidates( - candidates, - CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, - discriminateGenerics = false, // we can't specify generics explicitly for callable references - isDebuggerContext = scopeTower.isDebuggerContext) + candidates, + CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, + discriminateGenerics = false, // we can't specify generics explicitly for callable references + isDebuggerContext = scopeTower.isDebuggerContext + ) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt index 625927f355e..2162c72632b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt @@ -38,11 +38,11 @@ interface KotlinResolutionStatelessCallbacks { // This components hold state (trace). Work with this carefully. interface KotlinResolutionCallbacks { fun analyzeAndGetLambdaReturnArguments( - lambdaArgument: LambdaKotlinCallArgument, - isSuspend: Boolean, - receiverType: UnwrappedType?, - parameters: List, - expectedReturnType: UnwrappedType? // null means, that return type is not proper i.e. it depends on some type variables + lambdaArgument: LambdaKotlinCallArgument, + isSuspend: Boolean, + receiverType: UnwrappedType?, + parameters: List, + expectedReturnType: UnwrappedType? // null means, that return type is not proper i.e. it depends on some type variables ): List fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt index cb3bcc8c9f3..7bd6fe4f2d1 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt @@ -27,15 +27,15 @@ import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.UnwrappedType class KotlinCallCompleter( - private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, - private val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter + private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, + private val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter ) { fun runCompletion( - factory: SimpleCandidateFactory, - candidates: Collection, - expectedType: UnwrappedType?, - resolutionCallbacks: KotlinResolutionCallbacks + factory: SimpleCandidateFactory, + candidates: Collection, + expectedType: UnwrappedType?, + resolutionCallbacks: KotlinResolutionCallbacks ): CallResolutionResult { val diagnosticHolder = KotlinDiagnosticsHolder.SimpleHolder() if (candidates.isEmpty()) { @@ -54,14 +54,20 @@ class KotlinCallCompleter( if (candidate == null || candidate.csBuilder.hasContradiction) { val candidateForCompletion = candidate ?: factory.createErrorCandidate().forceResolution() candidateForCompletion.prepareForCompletion(expectedType, resolutionCallbacks) - runCompletion(candidateForCompletion.resolvedCall, ConstraintSystemCompletionMode.FULL, diagnosticHolder, candidateForCompletion.getSystem(), resolutionCallbacks) + runCompletion( + candidateForCompletion.resolvedCall, + ConstraintSystemCompletionMode.FULL, + diagnosticHolder, + candidateForCompletion.getSystem(), + resolutionCallbacks + ) val systemStorage = candidate?.getSystem()?.asReadOnlyStorage() ?: ConstraintStorage.Empty return CallResolutionResult( - CallResolutionResult.Type.ERROR, - candidate?.resolvedCall, - diagnosticHolder.getDiagnostics() + diagnosticsFromResolutionParts, - systemStorage + CallResolutionResult.Type.ERROR, + candidate?.resolvedCall, + diagnosticHolder.getDiagnostics() + diagnosticsFromResolutionParts, + systemStorage ) } @@ -71,57 +77,62 @@ class KotlinCallCompleter( return if (completionType == ConstraintSystemCompletionMode.FULL) { CallResolutionResult( - CallResolutionResult.Type.COMPLETED, - candidate.resolvedCall, - diagnosticHolder.getDiagnostics() + diagnosticsFromResolutionParts, - constraintSystem.asReadOnlyStorage() + CallResolutionResult.Type.COMPLETED, + candidate.resolvedCall, + diagnosticHolder.getDiagnostics() + diagnosticsFromResolutionParts, + constraintSystem.asReadOnlyStorage() ) - } - else { + } else { CallResolutionResult( - CallResolutionResult.Type.PARTIAL, - candidate.resolvedCall, - diagnosticHolder.getDiagnostics() + diagnosticsFromResolutionParts, - constraintSystem.asReadOnlyStorage() + CallResolutionResult.Type.PARTIAL, + candidate.resolvedCall, + diagnosticHolder.getDiagnostics() + diagnosticsFromResolutionParts, + constraintSystem.asReadOnlyStorage() ) } } fun createAllCandidatesResult( - candidates: Collection, - expectedType: UnwrappedType?, - resolutionCallbacks: KotlinResolutionCallbacks + candidates: Collection, + expectedType: UnwrappedType?, + resolutionCallbacks: KotlinResolutionCallbacks ): CallResolutionResult { val diagnosticsHolder = KotlinDiagnosticsHolder.SimpleHolder() for (candidate in candidates) { candidate.prepareForCompletion(expectedType, resolutionCallbacks) runCompletion( - candidate.resolvedCall, - ConstraintSystemCompletionMode.FULL, - diagnosticsHolder, - candidate.getSystem(), - resolutionCallbacks, - skipPostponedArguments = true) + candidate.resolvedCall, + ConstraintSystemCompletionMode.FULL, + diagnosticsHolder, + candidate.getSystem(), + resolutionCallbacks, + skipPostponedArguments = true + ) } return CallResolutionResult(CallResolutionResult.Type.ALL_CANDIDATES, null, emptyList(), ConstraintStorage.Empty, candidates) } - private fun runCompletion( - resolvedCallAtom: ResolvedCallAtom, - completionMode: ConstraintSystemCompletionMode, - diagnosticsHolder: KotlinDiagnosticsHolder, - constraintSystem: NewConstraintSystem, - resolutionCallbacks: KotlinResolutionCallbacks, - skipPostponedArguments: Boolean = false + private fun runCompletion( + resolvedCallAtom: ResolvedCallAtom, + completionMode: ConstraintSystemCompletionMode, + diagnosticsHolder: KotlinDiagnosticsHolder, + constraintSystem: NewConstraintSystem, + resolutionCallbacks: KotlinResolutionCallbacks, + skipPostponedArguments: Boolean = false ) { val returnType = resolvedCallAtom.freshReturnType ?: constraintSystem.builtIns.unitType - kotlinConstraintSystemCompleter.runCompletion(constraintSystem.asConstraintSystemCompleterContext(), completionMode, resolvedCallAtom, returnType) { + kotlinConstraintSystemCompleter.runCompletion( + constraintSystem.asConstraintSystemCompleterContext(), + completionMode, + resolvedCallAtom, + returnType + ) { if (!skipPostponedArguments) { postponedArgumentsAnalyzer.analyze( - constraintSystem.asPostponedArgumentsAnalyzerContext(), - resolutionCallbacks, - it, - diagnosticsHolder + constraintSystem.asPostponedArgumentsAnalyzerContext(), + resolutionCallbacks, + it, + diagnosticsHolder ) } } @@ -132,8 +143,8 @@ class KotlinCallCompleter( // true if we should complete this call private fun KotlinResolutionCandidate.prepareForCompletion( - expectedType: UnwrappedType?, - resolutionCallbacks: KotlinResolutionCallbacks + expectedType: UnwrappedType?, + resolutionCallbacks: KotlinResolutionCallbacks ): ConstraintSystemCompletionMode { val unsubstitutedReturnType = resolvedCall.candidateDescriptor.returnType?.unwrap() ?: return ConstraintSystemCompletionMode.PARTIAL val withSmartCastInfo = resolutionCallbacks.createReceiverWithSmartCastInfo(resolvedCall) @@ -141,14 +152,16 @@ class KotlinCallCompleter( val actualType = withSmartCastInfo?.stableType ?: unsubstitutedReturnType val returnType = resolvedCall.substitutor.substituteKeepAnnotations(actualType) - if (expectedType != null && !TypeUtils.noExpectedType(expectedType) && !resolutionCallbacks.isCompileTimeConstant(resolvedCall, expectedType)) { + if (expectedType != null && !TypeUtils.noExpectedType(expectedType) && !resolutionCallbacks.isCompileTimeConstant( + resolvedCall, + expectedType + )) { csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPosition(resolvedCall.atom)) } return if (expectedType != null || csBuilder.isProperType(returnType)) { ConstraintSystemCompletionMode.FULL - } - else { + } else { ConstraintSystemCompletionMode.PARTIAL } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt index 67d57d5522c..f17eb26e034 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt @@ -28,21 +28,21 @@ import org.jetbrains.kotlin.types.KotlinType import java.util.* class NewOverloadingConflictResolver( - builtIns: KotlinBuiltIns, - specificityComparator: TypeSpecificityComparator, - statelessCallbacks: KotlinResolutionStatelessCallbacks, - constraintInjector: ConstraintInjector + builtIns: KotlinBuiltIns, + specificityComparator: TypeSpecificityComparator, + statelessCallbacks: KotlinResolutionStatelessCallbacks, + constraintInjector: ConstraintInjector ) : OverloadingConflictResolver( - builtIns, - specificityComparator, - { - // todo investigate - it.resolvedCall.candidateDescriptor - }, - { SimpleConstraintSystemImpl(constraintInjector, builtIns) }, - Companion::createFlatSignature, - { it.variableCandidateIfInvoke }, - { statelessCallbacks.isDescriptorFromSource(it) } + builtIns, + specificityComparator, + { + // todo investigate + it.resolvedCall.candidateDescriptor + }, + { SimpleConstraintSystemImpl(constraintInjector, builtIns) }, + Companion::createFlatSignature, + { it.variableCandidateIfInvoke }, + { statelessCallbacks.isDescriptorFromSource(it) } ) { companion object { @@ -57,8 +57,7 @@ class NewOverloadingConflictResolver( for ((valueParameter, resolvedValueArgument) in resolvedCall.argumentMappingByOriginal) { if (resolvedValueArgument is ResolvedCallArgument.DefaultArgument) { numDefaults++ - } - else { + } else { val originalValueParameter = originalValueParameters[valueParameter.index] val parameterType = originalValueParameter.argumentValueType for (valueArgument in resolvedValueArgument.arguments) { @@ -71,7 +70,7 @@ class NewOverloadingConflictResolver( originalDescriptor, numDefaults, resolvedCall.atom.argumentsInParenthesis.map { valueArgumentToParameterType[it] } + - listOfNotNull(resolvedCall.atom.externalArgument?.let { valueArgumentToParameterType[it] }) + listOfNotNull(resolvedCall.atom.externalArgument?.let { valueArgumentToParameterType[it] }) ) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt index 58c78bafe33..0991673e648 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt @@ -27,11 +27,11 @@ import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.utils.addToStdlib.safeAs fun resolveKtPrimitive( - csBuilder: ConstraintSystemBuilder, - argument: KotlinCallArgument, - expectedType: UnwrappedType?, - diagnosticsHolder: KotlinDiagnosticsHolder, - isReceiver: Boolean + csBuilder: ConstraintSystemBuilder, + argument: KotlinCallArgument, + expectedType: UnwrappedType?, + diagnosticsHolder: KotlinDiagnosticsHolder, + isReceiver: Boolean ): ResolvedAtom = when (argument) { is SimpleKotlinCallArgument -> checkSimpleArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver) is LambdaKotlinCallArgument -> preprocessLambdaArgument(csBuilder, argument, expectedType) @@ -43,10 +43,10 @@ fun resolveKtPrimitive( // if expected type isn't function type, then may be it is Function, Any or just `T` private fun preprocessLambdaArgument( - csBuilder: ConstraintSystemBuilder, - argument: LambdaKotlinCallArgument, - expectedType: UnwrappedType?, - forceResolution: Boolean = false + csBuilder: ConstraintSystemBuilder, + argument: LambdaKotlinCallArgument, + expectedType: UnwrappedType?, + forceResolution: Boolean = false ): ResolvedAtom { if (expectedType != null && !forceResolution && csBuilder.isTypeVariable(expectedType)) { return LambdaWithTypeVariableAsExpectedTypeAtom(argument, expectedType) @@ -55,8 +55,10 @@ private fun preprocessLambdaArgument( val resolvedArgument = extractLambdaInfoFromFunctionalType(expectedType, argument) ?: extraLambdaInfo(expectedType, argument, csBuilder) if (expectedType != null) { - val lambdaType = createFunctionType(csBuilder.builtIns, Annotations.EMPTY, resolvedArgument.receiver, - resolvedArgument.parameters, null, resolvedArgument.returnType, resolvedArgument.isSuspend) + val lambdaType = createFunctionType( + csBuilder.builtIns, Annotations.EMPTY, resolvedArgument.receiver, + resolvedArgument.parameters, null, resolvedArgument.returnType, resolvedArgument.isSuspend + ) csBuilder.addSubtypeConstraint(lambdaType, expectedType, ArgumentConstraintPosition(argument)) } @@ -64,9 +66,9 @@ private fun preprocessLambdaArgument( } private fun extraLambdaInfo( - expectedType: UnwrappedType?, - argument: LambdaKotlinCallArgument, - csBuilder: ConstraintSystemBuilder + expectedType: UnwrappedType?, + argument: LambdaKotlinCallArgument, + csBuilder: ConstraintSystemBuilder ): ResolvedLambdaAtom { val builtIns = csBuilder.builtIns val isSuspend = expectedType?.isSuspendFunctionType ?: false @@ -77,9 +79,9 @@ private fun extraLambdaInfo( val typeVariable = TypeVariableForLambdaReturnType(argument, builtIns, "_L") val receiverType = argumentAsFunctionExpression?.receiverType - val returnType = argumentAsFunctionExpression?.returnType ?: - expectedType?.arguments?.singleOrNull()?.type?.unwrap()?.takeIf { isFunctionSupertype } ?: - typeVariable.defaultType + val returnType = + argumentAsFunctionExpression?.returnType ?: expectedType?.arguments?.singleOrNull()?.type?.unwrap()?.takeIf { isFunctionSupertype } + ?: typeVariable.defaultType val parameters = argument.parametersTypes?.map { it ?: builtIns.nothingType } ?: emptyList() @@ -97,7 +99,14 @@ private fun extractLambdaInfoFromFunctionalType(expectedType: UnwrappedType?, ar val receiverType = argumentAsFunctionExpression?.receiverType ?: expectedType.getReceiverTypeFromFunctionType()?.unwrap() val returnType = argumentAsFunctionExpression?.returnType ?: expectedType.getReturnTypeFromFunctionType().unwrap() - return ResolvedLambdaAtom(argument, expectedType.isSuspendFunctionType, receiverType, parameters, returnType, typeVariableForLambdaReturnType = null) + return ResolvedLambdaAtom( + argument, + expectedType.isSuspendFunctionType, + receiverType, + parameters, + returnType, + typeVariableForLambdaReturnType = null + ) } private fun extractLambdaParameters(expectedType: UnwrappedType, argument: LambdaKotlinCallArgument): List { @@ -122,15 +131,16 @@ fun LambdaWithTypeVariableAsExpectedTypeAtom.transformToResolvedLambda(csBuilder } private fun preprocessCallableReference( - csBuilder: ConstraintSystemBuilder, - argument: CallableReferenceKotlinCallArgument, - expectedType: UnwrappedType?, - diagnosticsHolder: KotlinDiagnosticsHolder + csBuilder: ConstraintSystemBuilder, + argument: CallableReferenceKotlinCallArgument, + expectedType: UnwrappedType?, + diagnosticsHolder: KotlinDiagnosticsHolder ): ResolvedAtom { val result = ResolvedCallableReferenceAtom(argument, expectedType) if (expectedType == null) return result - val notCallableTypeConstructor = csBuilder.getProperSuperTypeConstructors(expectedType).firstOrNull { !ReflectionTypes.isPossibleExpectedCallableType(it) } + val notCallableTypeConstructor = + csBuilder.getProperSuperTypeConstructors(expectedType).firstOrNull { !ReflectionTypes.isPossibleExpectedCallableType(it) } if (notCallableTypeConstructor != null) { diagnosticsHolder.addDiagnostic(NotCallableExpectedType(argument, expectedType, notCallableTypeConstructor)) } @@ -138,8 +148,8 @@ private fun preprocessCallableReference( } private fun preprocessCollectionLiteralArgument( - collectionLiteralArgument: CollectionLiteralKotlinCallArgument, - expectedType: UnwrappedType? + collectionLiteralArgument: CollectionLiteralKotlinCallArgument, + expectedType: UnwrappedType? ): ResolvedAtom { // todo add some checks about expected type return ResolvedCollectionLiteralAtom(collectionLiteralArgument, expectedType) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt index b759271c377..d8659bf4276 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.typeUtil.builtIns class PostponedArgumentsAnalyzer( - private val callableReferenceResolver: CallableReferenceResolver + private val callableReferenceResolver: CallableReferenceResolver ) { interface Context { fun buildCurrentSubstitutor(): NewTypeSubstitutor @@ -36,10 +36,16 @@ class PostponedArgumentsAnalyzer( // mutable operations fun addOtherSystem(otherSystem: ConstraintStorage) + fun getBuilder(): ConstraintSystemBuilder } - fun analyze(c: Context, resolutionCallbacks: KotlinResolutionCallbacks, argument: ResolvedAtom, diagnosticsHolder: KotlinDiagnosticsHolder) { + fun analyze( + c: Context, + resolutionCallbacks: KotlinResolutionCallbacks, + argument: ResolvedAtom, + diagnosticsHolder: KotlinDiagnosticsHolder + ) { when (argument) { is ResolvedLambdaAtom -> analyzeLambda(c, resolutionCallbacks, argument, diagnosticsHolder) @@ -56,7 +62,12 @@ class PostponedArgumentsAnalyzer( } } - private fun analyzeLambda(c: Context, resolutionCallbacks: KotlinResolutionCallbacks, lambda: ResolvedLambdaAtom, diagnosticHolder: KotlinDiagnosticsHolder) { + private fun analyzeLambda( + c: Context, + resolutionCallbacks: KotlinResolutionCallbacks, + lambda: ResolvedLambdaAtom, + diagnosticHolder: KotlinDiagnosticsHolder + ) { val currentSubstitutor = c.buildCurrentSubstitutor() fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(type) @@ -64,7 +75,8 @@ class PostponedArgumentsAnalyzer( val parameters = lambda.parameters.map(::substitute) val expectedType = lambda.returnType.takeIf { c.canBeProper(it) }?.let(::substitute) - val returnArguments = resolutionCallbacks.analyzeAndGetLambdaReturnArguments(lambda.atom, lambda.isSuspend, receiver, parameters, expectedType) + val returnArguments = + resolutionCallbacks.analyzeAndGetLambdaReturnArguments(lambda.atom, lambda.isSuspend, receiver, parameters, expectedType) returnArguments.forEach { c.addSubsystemFromArgument(it) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index e11d197ad87..491475f66c5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -55,12 +55,19 @@ internal object CheckVisibility : ResolutionPart() { if (scopeTower.isDebuggerContext) return val receiverValue = dispatchReceiverArgument?.receiver?.receiverValue ?: Visibilities.ALWAYS_SUITABLE_RECEIVER - val invisibleMember = Visibilities.findInvisibleMember(receiverValue, resolvedCall.candidateDescriptor, containingDescriptor) ?: return + val invisibleMember = + Visibilities.findInvisibleMember(receiverValue, resolvedCall.candidateDescriptor, containingDescriptor) ?: return if (dispatchReceiverArgument is ExpressionKotlinCallArgument) { val smartCastReceiver = getReceiverValueWithSmartCast(receiverValue, dispatchReceiverArgument.receiver.stableType) if (Visibilities.findInvisibleMember(smartCastReceiver, candidateDescriptor, containingDescriptor) == null) { - addDiagnostic(SmartCastDiagnostic(dispatchReceiverArgument, dispatchReceiverArgument.receiver.stableType, resolvedCall.atom)) + addDiagnostic( + SmartCastDiagnostic( + dispatchReceiverArgument, + dispatchReceiverArgument.receiver.stableType, + resolvedCall.atom + ) + ) return } } @@ -147,16 +154,23 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() { val knownTypeArgument = knownTypeParametersResultingSubstitutor?.substitute(typeParameter.defaultType) if (knownTypeArgument != null) { - csBuilder.addEqualityConstraint(freshVariable.defaultType, knownTypeArgument.unwrap(), KnownTypeParameterConstraintPosition(knownTypeArgument)) + csBuilder.addEqualityConstraint( + freshVariable.defaultType, + knownTypeArgument.unwrap(), + KnownTypeParameterConstraintPosition(knownTypeArgument) + ) continue } val typeArgument = resolvedCall.typeArgumentMappingByOriginal.getTypeArgument(typeParameter) if (typeArgument is SimpleTypeArgument) { - csBuilder.addEqualityConstraint(freshVariable.defaultType, typeArgument.type, ExplicitTypeParameterConstraintPosition(typeArgument)) - } - else { + csBuilder.addEqualityConstraint( + freshVariable.defaultType, + typeArgument.type, + ExplicitTypeParameterConstraintPosition(typeArgument) + ) + } else { assert(typeArgument == TypeArgumentPlaceholder) { "Unexpected typeArgument: $typeArgument, ${typeArgument.javaClass.canonicalName}" } @@ -165,8 +179,8 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() { } fun createToFreshVariableSubstitutorAndAddInitialConstraints( - candidateDescriptor: CallableDescriptor, - csBuilder: ConstraintSystemOperation + candidateDescriptor: CallableDescriptor, + csBuilder: ConstraintSystemOperation ): FreshVariableNewTypeSubstitutor { val typeParameters = candidateDescriptor.typeParameters @@ -193,9 +207,11 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() { internal object CheckExplicitReceiverKindConsistency : ResolutionPart() { private fun KotlinResolutionCandidate.hasError(): Nothing = - error("Inconsistent call: $kotlinCall. \n" + - "Candidate: $candidateDescriptor, explicitReceiverKind: ${resolvedCall.explicitReceiverKind}.\n" + - "Explicit receiver: ${kotlinCall.explicitReceiver}, dispatchReceiverForInvokeExtension: ${kotlinCall.dispatchReceiverForInvokeExtension}") + error( + "Inconsistent call: $kotlinCall. \n" + + "Candidate: $candidateDescriptor, explicitReceiverKind: ${resolvedCall.explicitReceiverKind}.\n" + + "Explicit receiver: ${kotlinCall.explicitReceiver}, dispatchReceiverForInvokeExtension: ${kotlinCall.dispatchReceiverForInvokeExtension}" + ) override fun KotlinResolutionCandidate.process(workIndex: Int) { when (resolvedCall.explicitReceiverKind) { @@ -207,20 +223,25 @@ internal object CheckExplicitReceiverKindConsistency : ResolutionPart() { } private fun KotlinResolutionCandidate.resolveKotlinArgument( - argument: KotlinCallArgument, - candidateParameter: ParameterDescriptor?, - isReceiver: Boolean + argument: KotlinCallArgument, + candidateParameter: ParameterDescriptor?, + isReceiver: Boolean ) { val expectedType = candidateParameter?.let { - resolvedCall.substitutor.substituteKeepAnnotations(argument.getExpectedType(candidateParameter, callComponents.languageVersionSettings)) + resolvedCall.substitutor.substituteKeepAnnotations( + argument.getExpectedType( + candidateParameter, + callComponents.languageVersionSettings + ) + ) } addResolvedKtPrimitive(resolveKtPrimitive(csBuilder, argument, expectedType, this, isReceiver)) } internal object CheckReceivers : ResolutionPart() { private fun KotlinResolutionCandidate.checkReceiver( - receiverArgument: SimpleKotlinCallArgument?, - receiverParameter: ReceiverParameterDescriptor? + receiverArgument: SimpleKotlinCallArgument?, + receiverParameter: ReceiverParameterDescriptor? ) { if ((receiverArgument == null) != (receiverParameter == null)) { error("Inconsistency receiver state for call $kotlinCall and candidate descriptor: $candidateDescriptor") diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt index ed11eca0a42..ca40dbef3d5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt @@ -33,11 +33,11 @@ import org.jetbrains.kotlin.types.upperIfFlexible fun checkSimpleArgument( - csBuilder: ConstraintSystemBuilder, - argument: SimpleKotlinCallArgument, - expectedType: UnwrappedType?, - diagnosticsHolder: KotlinDiagnosticsHolder, - isReceiver: Boolean + csBuilder: ConstraintSystemBuilder, + argument: SimpleKotlinCallArgument, + expectedType: UnwrappedType?, + diagnosticsHolder: KotlinDiagnosticsHolder, + isReceiver: Boolean ): ResolvedAtom = when (argument) { is ExpressionKotlinCallArgument -> checkExpressionArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver) is SubKotlinCallArgument -> checkSubCallArgument(csBuilder, argument, expectedType, diagnosticsHolder, isReceiver) @@ -45,11 +45,11 @@ fun checkSimpleArgument( } private fun checkExpressionArgument( - csBuilder: ConstraintSystemBuilder, - expressionArgument: ExpressionKotlinCallArgument, - expectedType: UnwrappedType?, - diagnosticsHolder: KotlinDiagnosticsHolder, - isReceiver: Boolean + csBuilder: ConstraintSystemBuilder, + expressionArgument: ExpressionKotlinCallArgument, + expectedType: UnwrappedType?, + diagnosticsHolder: KotlinDiagnosticsHolder, + isReceiver: Boolean ): ResolvedAtom { val resolvedKtExpression = ResolvedExpressionAtom(expressionArgument) if (expectedType == null) return resolvedKtExpression @@ -58,7 +58,7 @@ private fun checkExpressionArgument( val argumentType = captureFromTypeParameterUpperBoundIfNeeded(expressionArgument.receiver.stableType, expectedType) fun unstableSmartCastOrSubtypeError( - unstableType: UnwrappedType?, actualExpectedType: UnwrappedType, position: ConstraintPosition + unstableType: UnwrappedType?, actualExpectedType: UnwrappedType, position: ConstraintPosition ): KotlinCallDiagnostic? { if (unstableType != null) { if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, actualExpectedType, position)) { @@ -74,25 +74,30 @@ private fun checkExpressionArgument( if (expressionArgument.isSafeCall) { if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) { diagnosticsHolder.addDiagnosticIfNotNull( - unstableSmartCastOrSubtypeError(expressionArgument.receiver.unstableType, expectedNullableType, position)) + unstableSmartCastOrSubtypeError(expressionArgument.receiver.unstableType, expectedNullableType, position) + ) } return resolvedKtExpression } if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedType, position)) { if (!isReceiver) { - diagnosticsHolder.addDiagnosticIfNotNull(unstableSmartCastOrSubtypeError(expressionArgument.receiver.unstableType, expectedType, position)) + diagnosticsHolder.addDiagnosticIfNotNull( + unstableSmartCastOrSubtypeError( + expressionArgument.receiver.unstableType, + expectedType, + position + ) + ) return resolvedKtExpression } val unstableType = expressionArgument.receiver.unstableType if (unstableType != null && csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) { diagnosticsHolder.addDiagnostic(UnstableSmartCast(expressionArgument, unstableType)) - } - else if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) { + } else if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) { diagnosticsHolder.addDiagnostic(UnsafeCallError(expressionArgument)) - } - else { + } else { csBuilder.addSubtypeConstraint(argumentType, expectedType, position) } } @@ -122,7 +127,7 @@ private fun captureFromTypeParameterUpperBoundIfNeeded(argumentType: UnwrappedTy if (argumentType.lowerIfFlexible().constructor.declarationDescriptor is TypeParameterDescriptor) { val chosenSupertype = argumentType.lowerIfFlexible().supertypes().singleOrNull { it.constructor.declarationDescriptor is ClassifierDescriptorWithTypeParameters && - it.unwrap().hasSupertypeWithGivenTypeConstructor(expectedTypeConstructor) + it.unwrap().hasSupertypeWithGivenTypeConstructor(expectedTypeConstructor) } if (chosenSupertype != null) { return captureFromExpression(chosenSupertype.unwrap()) ?: argumentType @@ -133,11 +138,11 @@ private fun captureFromTypeParameterUpperBoundIfNeeded(argumentType: UnwrappedTy } private fun checkSubCallArgument( - csBuilder: ConstraintSystemBuilder, - subCallArgument: SubKotlinCallArgument, - expectedType: UnwrappedType?, - diagnosticsHolder: KotlinDiagnosticsHolder, - isReceiver: Boolean + csBuilder: ConstraintSystemBuilder, + subCallArgument: SubKotlinCallArgument, + expectedType: UnwrappedType?, + diagnosticsHolder: KotlinDiagnosticsHolder, + isReceiver: Boolean ): ResolvedAtom { val subCallResult = subCallArgument.callResult @@ -156,7 +161,7 @@ private fun checkSubCallArgument( if (isReceiver && !csBuilder.addSubtypeConstraintIfCompatible(currentReturnType, expectedType, position) && csBuilder.addSubtypeConstraintIfCompatible(currentReturnType, expectedNullableType, position) - ) { + ) { diagnosticsHolder.addDiagnostic(UnsafeCallError(subCallArgument)) return subCallResult } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/TypeArgumentsToParametersMapper.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/TypeArgumentsToParametersMapper.kt index e4edfdc5aa6..fe08725d25e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/TypeArgumentsToParametersMapper.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/TypeArgumentsToParametersMapper.kt @@ -29,15 +29,15 @@ class TypeArgumentsToParametersMapper { object NoExplicitArguments : TypeArgumentsMapping(emptyList()) { override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument = - TypeArgumentPlaceholder + TypeArgumentPlaceholder } class TypeArgumentsMappingImpl( - diagnostics: List, - private val typeParameterToArgumentMap: Map - ): TypeArgumentsMapping(diagnostics) { + diagnostics: List, + private val typeParameterToArgumentMap: Map + ) : TypeArgumentsMapping(diagnostics) { override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument = - typeParameterToArgumentMap[typeParameterDescriptor] ?: TypeArgumentPlaceholder + typeParameterToArgumentMap[typeParameterDescriptor] ?: TypeArgumentPlaceholder } } @@ -48,9 +48,9 @@ class TypeArgumentsToParametersMapper { if (call.typeArguments.size != descriptor.typeParameters.size) { return TypeArgumentsMapping.TypeArgumentsMappingImpl( - listOf(WrongCountOfTypeArguments(descriptor, call.typeArguments.size)), emptyMap()) - } - else { + listOf(WrongCountOfTypeArguments(descriptor, call.typeArguments.size)), emptyMap() + ) + } else { val typeParameterToArgumentMap = descriptor.typeParameters.zip(call.typeArguments).associate { it } return TypeArgumentsMapping.TypeArgumentsMappingImpl(listOf(), typeParameterToArgumentMap) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt index 2a1c9e60ae8..b61d966fb08 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt @@ -47,11 +47,15 @@ interface ConstraintSystemBuilder : ConstraintSystemOperation { fun buildCurrentSubstitutor(): NewTypeSubstitutor } -fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible(lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition) = - runTransaction { - if (!hasContradiction) addSubtypeConstraint(lowerType, upperType, position) - !hasContradiction - } +fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible( + lowerType: UnwrappedType, + upperType: UnwrappedType, + position: ConstraintPosition +) = + runTransaction { + if (!hasContradiction) addSubtypeConstraint(lowerType, upperType, position) + !hasContradiction + } fun PostponedArgumentsAnalyzer.Context.addSubsystemFromArgument(argument: KotlinCallArgument?) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt index 229cbd048b9..878e50c9e5d 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt @@ -33,7 +33,10 @@ fun ConstraintStorage.buildResultingSubstitutor(): NewTypeSubstitutor { it.key to it.value } val uninferredSubstitutorMap = notFixedTypeVariables.entries.associate { (freshTypeConstructor, typeVariable) -> - freshTypeConstructor to ErrorUtils.createErrorTypeWithCustomConstructor("Uninferred type", typeVariable.typeVariable.freshTypeConstructor) + freshTypeConstructor to ErrorUtils.createErrorTypeWithCustomConstructor( + "Uninferred type", + typeVariable.typeVariable.freshTypeConstructor + ) } return NewTypeSubstitutorByConstructorMap(currentSubstitutorMap + uninferredSubstitutorMap) @@ -61,10 +64,10 @@ fun CallableDescriptor.substituteAndApproximateCapturedTypes(substitutor: NewTyp override fun get(key: KotlinType): TypeProjection? = null override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = - substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType -> - TypeApproximator().approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedTypesApproximation) ?: - substitutedType - } + substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType -> + TypeApproximator().approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedTypesApproximation) + ?: substitutedType + } } return substitute(TypeSubstitutor.create(wrappedSubstitution)) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/NewConstraintSystem.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/NewConstraintSystem.kt index 7d6f4ccd2e5..20ca62c7066 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/NewConstraintSystem.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/NewConstraintSystem.kt @@ -32,6 +32,7 @@ interface NewConstraintSystem { // after this method we shouldn't mutate system via ConstraintSystemBuilder fun asReadOnlyStorage(): ConstraintStorage + fun asConstraintSystemCompleterContext(): KotlinConstraintSystemCompleter.Context fun asPostponedArgumentsAnalyzerContext(): PostponedArgumentsAnalyzer.Context } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt index fde647fe881..acc88f32af5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt @@ -102,30 +102,38 @@ class ConstraintIncorporator(val typeApproximator: TypeApproximator) { } private fun generateNewConstraint( - c: Context, - targetVariable: NewTypeVariable, - baseConstraint: Constraint, - otherVariable: NewTypeVariable, - otherConstraint: Constraint + c: Context, + targetVariable: NewTypeVariable, + baseConstraint: Constraint, + otherVariable: NewTypeVariable, + otherConstraint: Constraint ) { val typeForApproximation = when (otherConstraint.kind) { ConstraintKind.EQUALITY -> { baseConstraint.type.substitute(otherVariable, otherConstraint.type) } ConstraintKind.UPPER -> { - val newCapturedTypeConstructor = NewCapturedTypeConstructor(TypeProjectionImpl(Variance.OUT_VARIANCE, otherConstraint.type), - listOf(otherConstraint.type)) - val temporaryCapturedType = NewCapturedType(CaptureStatus.FOR_INCORPORATION, - newCapturedTypeConstructor, - lowerType = null) + val newCapturedTypeConstructor = NewCapturedTypeConstructor( + TypeProjectionImpl(Variance.OUT_VARIANCE, otherConstraint.type), + listOf(otherConstraint.type) + ) + val temporaryCapturedType = NewCapturedType( + CaptureStatus.FOR_INCORPORATION, + newCapturedTypeConstructor, + lowerType = null + ) baseConstraint.type.substitute(otherVariable, temporaryCapturedType) } ConstraintKind.LOWER -> { - val newCapturedTypeConstructor = NewCapturedTypeConstructor(TypeProjectionImpl(Variance.IN_VARIANCE, otherConstraint.type), - emptyList()) - val temporaryCapturedType = NewCapturedType(CaptureStatus.FOR_INCORPORATION, - newCapturedTypeConstructor, - lowerType = otherConstraint.type) + val newCapturedTypeConstructor = NewCapturedTypeConstructor( + TypeProjectionImpl(Variance.IN_VARIANCE, otherConstraint.type), + emptyList() + ) + val temporaryCapturedType = NewCapturedType( + CaptureStatus.FOR_INCORPORATION, + newCapturedTypeConstructor, + lowerType = otherConstraint.type + ) baseConstraint.type.substitute(otherVariable, temporaryCapturedType) } } @@ -145,8 +153,8 @@ class ConstraintIncorporator(val typeApproximator: TypeApproximator) { } private fun approximateCapturedTypes(type: UnwrappedType, toSuper: Boolean): UnwrappedType = - if (toSuper) typeApproximator.approximateToSuperType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type - else typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type + if (toSuper) typeApproximator.approximateToSuperType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type + else typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt index fe96adf62e1..2022afec3de 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt @@ -63,7 +63,12 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val } - private fun addSubTypeConstraintAndIncorporateIt(c: Context, lowerType: UnwrappedType, upperType: UnwrappedType, incorporatePosition: IncorporationConstraintPosition) { + private fun addSubTypeConstraintAndIncorporateIt( + c: Context, + lowerType: UnwrappedType, + upperType: UnwrappedType, + incorporatePosition: IncorporationConstraintPosition + ) { val possibleNewConstraints = Stack>() val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType, possibleNewConstraints) typeCheckerContext.runIsSubtypeOf(lowerType, upperType) @@ -72,7 +77,8 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val val (typeVariable, constraint) = possibleNewConstraints.pop() if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue - val constraints = c.notFixedTypeVariables[typeVariable.freshTypeConstructor] ?: typeCheckerContext.fixedTypeVariable(typeVariable) + val constraints = + c.notFixedTypeVariables[typeVariable.freshTypeConstructor] ?: typeCheckerContext.fixedTypeVariable(typeVariable) // it is important, that we add constraint here(not inside TypeCheckerContext), because inside incorporation we read constraints constraints.addConstraint(constraint)?.let { @@ -105,14 +111,15 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val return false } - private fun Context.isAllowedType(type: UnwrappedType) = type.typeDepth() <= maxTypeDepthFromInitialConstraints + ALLOWED_DEPTH_DELTA_FOR_INCORPORATION + private fun Context.isAllowedType(type: UnwrappedType) = + type.typeDepth() <= maxTypeDepthFromInitialConstraints + ALLOWED_DEPTH_DELTA_FOR_INCORPORATION private inner class TypeCheckerContext( - val c: Context, - val position: IncorporationConstraintPosition, - val baseLowerType: UnwrappedType, - val baseUpperType: UnwrappedType, - val possibleNewConstraints: MutableList> + val c: Context, + val position: IncorporationConstraintPosition, + val baseLowerType: UnwrappedType, + val baseUpperType: UnwrappedType, + val possibleNewConstraints: MutableList> ) : TypeCheckerContextForConstraintSystem(), ConstraintIncorporator.Context { fun runIsSubtypeOf(lowerType: UnwrappedType, upperType: UnwrappedType) { @@ -126,36 +133,39 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val // from TypeCheckerContextForConstraintSystem override fun isMyTypeVariable(type: SimpleType): Boolean = c.allTypeVariables.containsKey(type.constructor) + override fun addUpperConstraint(typeVariable: TypeConstructor, superType: UnwrappedType) = - addConstraint(typeVariable, superType, UPPER) + addConstraint(typeVariable, superType, UPPER) override fun addLowerConstraint(typeVariable: TypeConstructor, subType: UnwrappedType) = - addConstraint(typeVariable, subType, LOWER) + addConstraint(typeVariable, subType, LOWER) private fun isCapturedTypeFromSubtyping(type: UnwrappedType) = - when ((type as? NewCapturedType)?.captureStatus) { - null, CaptureStatus.FROM_EXPRESSION -> false - CaptureStatus.FOR_SUBTYPING -> true - CaptureStatus.FOR_INCORPORATION -> - error("Captured type for incorporation shouldn't escape from incorporation: $type\n" + renderBaseConstraint()) - } + when ((type as? NewCapturedType)?.captureStatus) { + null, CaptureStatus.FROM_EXPRESSION -> false + CaptureStatus.FOR_SUBTYPING -> true + CaptureStatus.FOR_INCORPORATION -> + error("Captured type for incorporation shouldn't escape from incorporation: $type\n" + renderBaseConstraint()) + } private fun addConstraint(typeVariableConstructor: TypeConstructor, type: UnwrappedType, kind: ConstraintKind) { val typeVariable = c.allTypeVariables[typeVariableConstructor] - ?: error("Should by type variableConstructor: $typeVariableConstructor. ${c.allTypeVariables.values}") + ?: error("Should by type variableConstructor: $typeVariableConstructor. ${c.allTypeVariables.values}") var targetType = type if (type.contains(this::isCapturedTypeFromSubtyping)) { // TypeVariable <: type -> if TypeVariable <: subType => TypeVariable <: type if (kind == UPPER) { - val subType = typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation) + val subType = + typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation) if (subType != null && !KotlinBuiltIns.isNothingOrNullableNothing(subType)) { targetType = subType } } if (kind == LOWER) { - val superType = typeApproximator.approximateToSuperType(type, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation) + val superType = + typeApproximator.approximateToSuperType(type, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation) if (superType != null && !KotlinBuiltIns.isAnyOrNullableAny(superType)) { // todo rethink error reporting for Any cases targetType = superType } @@ -189,12 +199,14 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val } override fun getConstraintsForVariable(typeVariable: NewTypeVariable) = - c.notFixedTypeVariables[typeVariable.freshTypeConstructor]?.constraints - ?: fixedTypeVariable(typeVariable) + c.notFixedTypeVariables[typeVariable.freshTypeConstructor]?.constraints + ?: fixedTypeVariable(typeVariable) fun fixedTypeVariable(variable: NewTypeVariable): Nothing { - error("Type variable $variable should not be fixed!\n" + - renderBaseConstraint()) + error( + "Type variable $variable should not be fixed!\n" + + renderBaseConstraint() + ) } private fun renderBaseConstraint() = "Base constraint: $baseLowerType <: $baseUpperType from position: $position" diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt index f2a0d95a11a..e72b5c2c406 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt @@ -27,8 +27,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs class KotlinConstraintSystemCompleter( - private val resultTypeResolver: ResultTypeResolver, - private val variableFixationFinder: VariableFixationFinder + private val resultTypeResolver: ResultTypeResolver, + private val variableFixationFinder: VariableFixationFinder ) { enum class ConstraintSystemCompletionMode { FULL, @@ -43,15 +43,16 @@ class KotlinConstraintSystemCompleter( // mutable operations fun addError(error: KotlinCallDiagnostic) + fun fixVariable(variable: NewTypeVariable, resultType: UnwrappedType) } fun runCompletion( - c: Context, - completionMode: ConstraintSystemCompletionMode, - topLevelPrimitive: ResolvedAtom, - topLevelType: UnwrappedType, - analyze: (PostponedResolvedAtom) -> Unit + c: Context, + completionMode: ConstraintSystemCompletionMode, + topLevelPrimitive: ResolvedAtom, + topLevelType: UnwrappedType, + analyze: (PostponedResolvedAtom) -> Unit ) { while (true) { if (analyzePostponeArgumentIfPossible(c, topLevelPrimitive, analyze)) continue @@ -59,7 +60,8 @@ class KotlinConstraintSystemCompleter( val allTypeVariables = getOrderedAllTypeVariables(c, topLevelPrimitive) val postponedKtPrimitives = getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive) val variableForFixation = variableFixationFinder.findFirstVariableForFixation( - c, allTypeVariables, postponedKtPrimitives, completionMode, topLevelType) + c, allTypeVariables, postponedKtPrimitives, completionMode, topLevelType + ) if (shouldForceCallableReferenceOrLambdaResolution(completionMode, variableForFixation)) { if (forcePostponedAtomResolution(topLevelPrimitive, analyze)) continue @@ -88,8 +90,8 @@ class KotlinConstraintSystemCompleter( } private fun shouldForceCallableReferenceOrLambdaResolution( - completionMode: ConstraintSystemCompletionMode, - variableForFixation: VariableFixationFinder.VariableForFixation? + completionMode: ConstraintSystemCompletionMode, + variableForFixation: VariableFixationFinder.VariableForFixation? ): Boolean { if (completionMode == ConstraintSystemCompletionMode.PARTIAL) return false if (variableForFixation != null && variableForFixation.hasProperConstraint) return false @@ -98,7 +100,11 @@ class KotlinConstraintSystemCompleter( } // true if we do analyze - private fun analyzePostponeArgumentIfPossible(c: Context, topLevelPrimitive: ResolvedAtom, analyze: (PostponedResolvedAtom) -> Unit): Boolean { + private fun analyzePostponeArgumentIfPossible( + c: Context, + topLevelPrimitive: ResolvedAtom, + analyze: (PostponedResolvedAtom) -> Unit + ): Boolean { for (argument in getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive)) { if (canWeAnalyzeIt(c, argument)) { analyze(argument) @@ -110,8 +116,8 @@ class KotlinConstraintSystemCompleter( // true if we find some callable reference and run resolution for it. Note that such resolution can be unsuccessful private inline fun forcePostponedAtomResolution( - topLevelPrimitive: ResolvedAtom, - analyze: (PostponedResolvedAtom) -> Unit + topLevelPrimitive: ResolvedAtom, + analyze: (PostponedResolvedAtom) -> Unit ): Boolean { val postponedArgument = getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive).firstIsInstanceOrNull() ?: return false analyze(postponedArgument) @@ -129,7 +135,7 @@ class KotlinConstraintSystemCompleter( return arrayListOf().apply { topLevelPrimitive.process(this) } } - private fun getOrderedAllTypeVariables(c: Context, topLevelPrimitive: ResolvedAtom) : List { + private fun getOrderedAllTypeVariables(c: Context, topLevelPrimitive: ResolvedAtom): List { fun ResolvedAtom.process(to: MutableList) { val typeVariables = when (this) { is ResolvedCallAtom -> substitutor.freshVariables @@ -146,6 +152,7 @@ class KotlinConstraintSystemCompleter( subResolvedAtoms.forEach { it.process(to) } } } + val result = arrayListOf().apply { topLevelPrimitive.process(this) } assert(result.size == c.notFixedTypeVariables.size) { @@ -164,10 +171,10 @@ class KotlinConstraintSystemCompleter( } private fun fixVariable( - c: Context, - topLevelType: UnwrappedType, - variableWithConstraints: VariableWithConstraints, - postponedResolveKtPrimitives: List + c: Context, + topLevelType: UnwrappedType, + variableWithConstraints: VariableWithConstraints, + postponedResolveKtPrimitives: List ) { val direction = TypeVariableDirectionCalculator(c, postponedResolveKtPrimitives, topLevelType).getDirection(variableWithConstraints) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt index be5f583d103..8b451ca68a7 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt @@ -29,26 +29,27 @@ interface NewTypeSubstitutor { fun safeSubstitute(type: UnwrappedType): UnwrappedType = substitute(type, runCapturedChecks = true, keepAnnotation = false) ?: type fun substituteKeepAnnotations(type: UnwrappedType): UnwrappedType = - substitute(type, runCapturedChecks = true, keepAnnotation = true) ?: type + substitute(type, runCapturedChecks = true, keepAnnotation = true) ?: type private fun substitute(type: UnwrappedType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? = - when (type) { - is SimpleType -> substitute(type, keepAnnotation, runCapturedChecks) - is FlexibleType -> if (type is DynamicType || type is RawType) { + when (type) { + is SimpleType -> substitute(type, keepAnnotation, runCapturedChecks) + is FlexibleType -> if (type is DynamicType || type is RawType) { + null + } else { + val lowerBound = substitute(type.lowerBound, keepAnnotation, runCapturedChecks) + val upperBound = substitute(type.upperBound, keepAnnotation, runCapturedChecks) + if (lowerBound == null && upperBound == null) { null - } - else { - val lowerBound = substitute(type.lowerBound, keepAnnotation, runCapturedChecks) - val upperBound = substitute(type.upperBound, keepAnnotation, runCapturedChecks) - if (lowerBound == null && upperBound == null) { - null - } - else { - // todo discuss lowerIfFlexible and upperIfFlexible - KotlinTypeFactory.flexibleType(lowerBound?.lowerIfFlexible() ?: type.lowerBound, upperBound?.upperIfFlexible() ?: type.upperBound) - } + } else { + // todo discuss lowerIfFlexible and upperIfFlexible + KotlinTypeFactory.flexibleType( + lowerBound?.lowerIfFlexible() ?: type.lowerBound, + upperBound?.upperIfFlexible() ?: type.upperBound + ) } } + } private fun substitute(type: SimpleType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? { if (type.isError) return null @@ -57,10 +58,11 @@ interface NewTypeSubstitutor { val substitutedExpandedType = substitute(type.expandedType, keepAnnotation, runCapturedChecks) val substitutedAbbreviation = substitute(type.abbreviation, keepAnnotation, runCapturedChecks) if (substitutedExpandedType is SimpleType? && substitutedAbbreviation is SimpleType?) { - return AbbreviatedType(substitutedExpandedType ?: type.expandedType, - substitutedAbbreviation ?: type.abbreviation) - } - else { + return AbbreviatedType( + substitutedExpandedType ?: type.expandedType, + substitutedAbbreviation ?: type.abbreviation + ) + } else { return substitutedExpandedType } } @@ -74,21 +76,26 @@ interface NewTypeSubstitutor { if (typeConstructor is NewCapturedTypeConstructor) { if (!runCapturedChecks) return null - assert(type is NewCapturedType || (type is DefinitelyNotNullType && type.original is NewCapturedType)) { // KT-16147 + assert(type is NewCapturedType || (type is DefinitelyNotNullType && type.original is NewCapturedType)) { + // KT-16147 "Type is inconsistent -- somewhere we create type with typeConstructor = $typeConstructor " + - "and class: ${type::class.java.canonicalName}. type.toString() = $type" + "and class: ${type::class.java.canonicalName}. type.toString() = $type" } val capturedType = if (type is DefinitelyNotNullType) type.original as NewCapturedType else type as NewCapturedType val lower = capturedType.lowerType?.let { substitute(it, keepAnnotation, runCapturedChecks = false) } - if (lower != null) throw IllegalStateException("Illegal type substitutor: $this, " + - "because for captured type '$type' lower type approximation should be null, but it is: '$lower'," + - "original lower type: '${capturedType.lowerType}") + if (lower != null) throw IllegalStateException( + "Illegal type substitutor: $this, " + + "because for captured type '$type' lower type approximation should be null, but it is: '$lower'," + + "original lower type: '${capturedType.lowerType}" + ) typeConstructor.supertypes.forEach { supertype -> substitute(supertype, keepAnnotation, runCapturedChecks = false)?.let { - throw IllegalStateException("Illegal type substitutor: $this, " + - "because for captured type '$type' supertype approximation should be null, but it is: '$supertype'," + - "original supertype: '$supertype'") + throw IllegalStateException( + "Illegal type substitutor: $this, " + + "because for captured type '$type' supertype approximation should be null, but it is: '$supertype'," + + "original supertype: '$supertype'" + ) } } @@ -120,9 +127,9 @@ interface NewTypeSubstitutor { } private fun substituteParametrizedType( - type: SimpleType, - keepAnnotation: Boolean, - runCapturedChecks: Boolean + type: SimpleType, + keepAnnotation: Boolean, + runCapturedChecks: Boolean ): UnwrappedType? { val parameters = type.constructor.parameters val arguments = type.arguments diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt index 5ca8e698daa..ef9bda7d3b9 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.types.checker.intersectTypes import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType class ResultTypeResolver( - val typeApproximator: TypeApproximator + val typeApproximator: TypeApproximator ) { interface Context { fun isProperType(type: UnwrappedType): Boolean @@ -49,8 +49,7 @@ class ResultTypeResolver( val superType = findSuperType(c, variableWithConstraints) val result = if (direction == ResolveDirection.TO_SUBTYPE || direction == ResolveDirection.UNKNOWN) { c.resultType(subType, superType, variableWithConstraints) - } - else { + } else { c.resultType(superType, subType, variableWithConstraints) } @@ -58,9 +57,9 @@ class ResultTypeResolver( } private fun Context.resultType( - firstCandidate: UnwrappedType?, - secondCandidate: UnwrappedType?, - variableWithConstraints: VariableWithConstraints + firstCandidate: UnwrappedType?, + secondCandidate: UnwrappedType?, + variableWithConstraints: VariableWithConstraints ): UnwrappedType? { if (firstCandidate == null || secondCandidate == null) return firstCandidate ?: secondCandidate @@ -68,8 +67,7 @@ class ResultTypeResolver( if (isSuitableType(secondCandidate, variableWithConstraints)) { return secondCandidate - } - else { + } else { return firstCandidate } } @@ -105,8 +103,11 @@ class ResultTypeResolver( * */ - return typeApproximator.approximateToSuperType(adjustedCommonSuperType, TypeApproximatorConfiguration.CapturedTypesApproximation) - ?: adjustedCommonSuperType + return typeApproximator.approximateToSuperType( + adjustedCommonSuperType, + TypeApproximatorConfiguration.CapturedTypesApproximation + ) + ?: adjustedCommonSuperType } return null @@ -150,9 +151,9 @@ class ResultTypeResolver( } fun findResultIfThereIsEqualsConstraint( - c: Context, - variableWithConstraints: VariableWithConstraints, - allowedFixToNotProperType: Boolean = false + c: Context, + variableWithConstraints: VariableWithConstraints, + allowedFixToNotProperType: Boolean = false ): UnwrappedType? { val properEqualsConstraint = variableWithConstraints.constraints.filter { it.kind == ConstraintKind.EQUALITY && c.isProperType(it.type) @@ -160,7 +161,7 @@ class ResultTypeResolver( if (properEqualsConstraint.isNotEmpty()) { return properEqualsConstraint.map { it.type }.singleBestRepresentative()?.unwrap() - ?: properEqualsConstraint.first().type // seems like constraint system has contradiction + ?: properEqualsConstraint.first().type // seems like constraint system has contradiction } if (!allowedFixToNotProperType) return null diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt index 7fae9e1f315..92fc20794b1 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerContextForConstraintSystem.kt @@ -31,6 +31,7 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT // super and sub type isSingleClassifierType abstract fun addUpperConstraint(typeVariable: TypeConstructor, superType: UnwrappedType) + abstract fun addLowerConstraint(typeVariable: TypeConstructor, subType: UnwrappedType) override fun getLowerCapturedTypePolicy(subType: SimpleType, superType: NewCapturedType) = when { @@ -65,10 +66,10 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT } private fun UnwrappedType.isTypeVariableWithExact() = - anyBound(this@TypeCheckerContextForConstraintSystem::isMyTypeVariable) && hasExactAnnotation() + anyBound(this@TypeCheckerContextForConstraintSystem::isMyTypeVariable) && hasExactAnnotation() private fun UnwrappedType.isTypeVariableWithNoInfer() = - anyBound(this@TypeCheckerContextForConstraintSystem::isMyTypeVariable) && hasNoInferAnnotation() + anyBound(this@TypeCheckerContextForConstraintSystem::isMyTypeVariable) && hasNoInferAnnotation() private fun internalAddSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType): Boolean? { assertInputTypes(subType, superType) @@ -81,8 +82,7 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT if (subType.anyBound(this::isMyTypeVariable)) { return simplifyUpperConstraint(subType, superType) && (answer ?: true) - } - else { + } else { return simplifyConstraintForPossibleIntersectionSubType(subType, superType) ?: answer } } @@ -174,7 +174,7 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT if (typeVariable.isMarkedNullable) { // here is important that superType is singleClassifierType return superType.anyBound(this::isMyTypeVariable) || - isSubtypeOfByTypeChecker(typeVariable.builtIns.nullableNothingType, superType) + isSubtypeOfByTypeChecker(typeVariable.builtIns.nullableNothingType, superType) } return true @@ -222,11 +222,14 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT } private fun isSubtypeOfByTypeChecker(subType: UnwrappedType, superType: UnwrappedType) = - with(NewKotlinTypeChecker) { this@TypeCheckerContextForConstraintSystem.isSubtypeOf(subType, superType) } + with(NewKotlinTypeChecker) { this@TypeCheckerContextForConstraintSystem.isSubtypeOf(subType, superType) } private fun assertInputTypes(subType: UnwrappedType, superType: UnwrappedType) { - fun correctSubType(subType: SimpleType) = subType.isSingleClassifierType || subType.isIntersectionType || isMyTypeVariable(subType) || subType.isError - fun correctSuperType(superType: SimpleType) = superType.isSingleClassifierType || superType.isIntersectionType || isMyTypeVariable(superType) || superType.isError + fun correctSubType(subType: SimpleType) = + subType.isSingleClassifierType || subType.isIntersectionType || isMyTypeVariable(subType) || subType.isError + + fun correctSuperType(superType: SimpleType) = + superType.isSingleClassifierType || superType.isIntersectionType || isMyTypeVariable(superType) || superType.isError assert(subType.bothBounds(::correctSubType)) { "Not singleClassifierType and not intersection subType: $subType" diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeVariableDependencyInformationProvider.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeVariableDependencyInformationProvider.kt index d0c8fe24bb3..394365476c9 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeVariableDependencyInformationProvider.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeVariableDependencyInformationProvider.kt @@ -24,9 +24,9 @@ import org.jetbrains.kotlin.types.typeUtil.contains import org.jetbrains.kotlin.utils.SmartSet class TypeVariableDependencyInformationProvider( - private val notFixedTypeVariables: Map, - private val postponedKtPrimitives: List, - private val topLevelType: UnwrappedType? + private val notFixedTypeVariables: Map, + private val postponedKtPrimitives: List, + private val topLevelType: UnwrappedType? ) { // not oriented edges private val constrainEdges: MutableMap> = hashMapOf() diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeVariableDirectionCalculator.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeVariableDirectionCalculator.kt index 20fe372fbcc..71500f0e239 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeVariableDirectionCalculator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeVariableDirectionCalculator.kt @@ -32,9 +32,9 @@ import org.jetbrains.kotlin.utils.SmartList private typealias Variable = VariableWithConstraints class TypeVariableDirectionCalculator( - private val c: VariableFixationFinder.Context, - private val postponedKtPrimitives: List, - topLevelType: UnwrappedType + private val c: VariableFixationFinder.Context, + private val postponedKtPrimitives: List, + topLevelType: UnwrappedType ) { enum class ResolveDirection { TO_SUBTYPE, @@ -45,7 +45,7 @@ class TypeVariableDirectionCalculator( data class NodeWithDirection(val variableWithConstraints: VariableWithConstraints, val direction: ResolveDirection) { override fun toString() = "$variableWithConstraints to $direction" } - + private val directions = HashMap() init { @@ -53,7 +53,7 @@ class TypeVariableDirectionCalculator( } fun getDirection(typeVariable: Variable): ResolveDirection = - directions.getOrDefault(typeVariable, ResolveDirection.UNKNOWN) + directions.getOrDefault(typeVariable, ResolveDirection.UNKNOWN) private fun setupDirections(topReturnType: UnwrappedType) { topReturnType.visitType(ResolveDirection.TO_SUBTYPE) { variableWithConstraints, direction -> @@ -87,32 +87,35 @@ class TypeVariableDirectionCalculator( } private fun getConstraintDependencies( - variable: Variable, - direction: ResolveDirection + variable: Variable, + direction: ResolveDirection ): List = - SmartList().also { result -> - for (constraint in variable.constraints) { - if (!isInterestingConstraint(direction, constraint)) continue + SmartList().also { result -> + for (constraint in variable.constraints) { + if (!isInterestingConstraint(direction, constraint)) continue - constraint.type.visitType(direction) { nodeVariable, nodeDirection -> - result.add(NodeWithDirection(nodeVariable, nodeDirection)) - } + constraint.type.visitType(direction) { nodeVariable, nodeDirection -> + result.add(NodeWithDirection(nodeVariable, nodeDirection)) } } + } private fun isInterestingConstraint(direction: ResolveDirection, constraint: Constraint): Boolean = - !(direction == ResolveDirection.TO_SUBTYPE && constraint.kind == ConstraintKind.UPPER) && - !(direction == ResolveDirection.TO_SUPERTYPE && constraint.kind == ConstraintKind.LOWER) + !(direction == ResolveDirection.TO_SUBTYPE && constraint.kind == ConstraintKind.UPPER) && + !(direction == ResolveDirection.TO_SUPERTYPE && constraint.kind == ConstraintKind.LOWER) - private fun UnwrappedType.visitType(startDirection: ResolveDirection, action: (variable: Variable, direction: ResolveDirection) -> Unit) = - when (this) { - is SimpleType -> visitType(startDirection, action) - is FlexibleType -> { - lowerBound.visitType(startDirection, action) - upperBound.visitType(startDirection, action) - } + private fun UnwrappedType.visitType( + startDirection: ResolveDirection, + action: (variable: Variable, direction: ResolveDirection) -> Unit + ) = + when (this) { + is SimpleType -> visitType(startDirection, action) + is FlexibleType -> { + lowerBound.visitType(startDirection, action) + upperBound.visitType(startDirection, action) } + } private fun SimpleType.visitType(startDirection: ResolveDirection, action: (variable: Variable, direction: ResolveDirection) -> Unit) { if (isIntersectionType) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt index 97f4fe0356b..c4e774ec262 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt @@ -34,11 +34,11 @@ class VariableFixationFinder { data class VariableForFixation(val variable: TypeConstructor, val hasProperConstraint: Boolean) fun findFirstVariableForFixation( - c: Context, - allTypeVariables: List, - postponedKtPrimitives: List, - completionMode: ConstraintSystemCompletionMode, - topLevelType: UnwrappedType + c: Context, + allTypeVariables: List, + postponedKtPrimitives: List, + completionMode: ConstraintSystemCompletionMode, + topLevelType: UnwrappedType ): VariableForFixation? = c.findTypeVariableForFixation(allTypeVariables, postponedKtPrimitives, completionMode, topLevelType) private enum class TypeVariableFixationReadiness { @@ -50,11 +50,11 @@ class VariableFixationFinder { } private fun Context.getTypeVariableReadiness( - variable: TypeConstructor, - dependencyProvider: TypeVariableDependencyInformationProvider + variable: TypeConstructor, + dependencyProvider: TypeVariableDependencyInformationProvider ): TypeVariableFixationReadiness = when { !notFixedTypeVariables.contains(variable) || - dependencyProvider.isVariableRelatedToTopLevelType(variable) -> TypeVariableFixationReadiness.FORBIDDEN + dependencyProvider.isVariableRelatedToTopLevelType(variable) -> TypeVariableFixationReadiness.FORBIDDEN !variableHasProperArgumentConstraints(variable) -> TypeVariableFixationReadiness.WITHOUT_PROPER_ARGUMENT_CONSTRAINT hasDependencyToOtherTypeVariables(variable) -> TypeVariableFixationReadiness.WITH_COMPLEX_DEPENDENCY dependencyProvider.isVariableRelatedToAnyOutputType(variable) -> TypeVariableFixationReadiness.RELATED_TO_ANY_OUTPUT_TYPE @@ -62,10 +62,10 @@ class VariableFixationFinder { } private fun Context.findTypeVariableForFixation( - allTypeVariables: List, - postponedKtPrimitives: List, - completionMode: ConstraintSystemCompletionMode, - topLevelType: UnwrappedType + allTypeVariables: List, + postponedKtPrimitives: List, + completionMode: ConstraintSystemCompletionMode, + topLevelType: UnwrappedType ): VariableForFixation? { val dependencyProvider = TypeVariableDependencyInformationProvider(notFixedTypeVariables, postponedKtPrimitives, topLevelType.takeIf { completionMode == PARTIAL }) @@ -89,12 +89,12 @@ class VariableFixationFinder { } private fun Context.variableHasProperArgumentConstraints(variable: TypeConstructor): Boolean = - notFixedTypeVariables[variable]?.constraints?.any { isProperArgumentConstraint(it) } ?: false + notFixedTypeVariables[variable]?.constraints?.any { isProperArgumentConstraint(it) } ?: false private fun Context.isProperArgumentConstraint(c: Constraint) = - isProperType(c.type) && c.position.initialConstraint.position !is DeclaredUpperBoundConstraintPosition + isProperType(c.type) && c.position.initialConstraint.position !is DeclaredUpperBoundConstraintPosition private fun Context.isProperType(type: UnwrappedType): Boolean = - !type.contains { notFixedTypeVariables.containsKey(it.constructor) } + !type.contains { notFixedTypeVariables.containsKey(it.constructor) } } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt index b8447ab638b..585cf05d904 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt @@ -30,12 +30,15 @@ sealed class ConstraintPosition class ExplicitTypeParameterConstraintPosition(val typeArgument: SimpleTypeArgument) : ConstraintPosition() { override fun toString() = "TypeParameter $typeArgument" } + class ExpectedTypeConstraintPosition(val topLevelCall: KotlinCall) : ConstraintPosition() { override fun toString() = "ExpectedType for call $topLevelCall" } + class DeclaredUpperBoundConstraintPosition(val typeParameterDescriptor: TypeParameterDescriptor) : ConstraintPosition() { override fun toString() = "DeclaredUpperBound ${typeParameterDescriptor.name} from ${typeParameterDescriptor.containingDeclaration}" } + class ArgumentConstraintPosition(val argument: KotlinCallArgument) : ConstraintPosition() { override fun toString() = "Argument $argument" } @@ -47,9 +50,11 @@ class ReceiverConstraintPosition(val argument: KotlinCallArgument) : ConstraintP class FixVariableConstraintPosition(val variable: NewTypeVariable) : ConstraintPosition() { override fun toString() = "Fix variable $variable" } + class KnownTypeParameterConstraintPosition(val typeArgument: KotlinType) : ConstraintPosition() { override fun toString() = "TypeArgument $typeArgument" } + class LambdaArgumentConstraintPosition(val lambda: ResolvedLambdaAtom) : ConstraintPosition() { override fun toString(): String { return "LambdaArgument $lambda" @@ -68,15 +73,15 @@ abstract class ConstraintSystemCallDiagnostic(applicability: ResolutionCandidate } class NewConstraintError( - val lowerType: UnwrappedType, - val upperType: UnwrappedType, - val position: IncorporationConstraintPosition + val lowerType: UnwrappedType, + val upperType: UnwrappedType, + val position: IncorporationConstraintPosition ) : ConstraintSystemCallDiagnostic(if (position.from is ReceiverConstraintPosition) INAPPLICABLE_WRONG_RECEIVER else INAPPLICABLE) class CapturedTypeFromSubtyping( - val typeVariable: NewTypeVariable, - val constraintType: UnwrappedType, - val position: ConstraintPosition + val typeVariable: NewTypeVariable, + val constraintType: UnwrappedType, + val position: ConstraintPosition ) : ConstraintSystemCallDiagnostic(INAPPLICABLE) class NotEnoughInformationForTypeParameter(val typeVariable: NewTypeVariable) : ConstraintSystemCallDiagnostic(INAPPLICABLE) \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt index e80787733b6..0b5642a7659 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt @@ -70,10 +70,10 @@ enum class ConstraintKind { } class Constraint( - val kind: ConstraintKind, - val type: UnwrappedType, // flexible types here is allowed - val position: IncorporationConstraintPosition, - val typeHashCode: Int = type.hashCode() + val kind: ConstraintKind, + val type: UnwrappedType, // flexible types here is allowed + val position: IncorporationConstraintPosition, + val typeHashCode: Int = type.hashCode() ) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -100,18 +100,18 @@ interface VariableWithConstraints { } class InitialConstraint( - val a: UnwrappedType, - val b: UnwrappedType, - val constraintKind: ConstraintKind, // see [checkConstraint] - val position: ConstraintPosition + val a: UnwrappedType, + val b: UnwrappedType, + val constraintKind: ConstraintKind, // see [checkConstraint] + val position: ConstraintPosition ) { override fun toString(): String { val sign = - when (constraintKind) { - ConstraintKind.EQUALITY -> "==" - ConstraintKind.LOWER -> ":>" - ConstraintKind.UPPER -> "<:" - } + when (constraintKind) { + ConstraintKind.EQUALITY -> "==" + ConstraintKind.LOWER -> ":>" + ConstraintKind.UPPER -> "<:" + } return "$a $sign $b from $position" } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt index 3f84245ccbf..9e6a04b8ee6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt @@ -25,15 +25,16 @@ import kotlin.collections.ArrayList class MutableVariableWithConstraints( - override val typeVariable: NewTypeVariable, - constraints: Collection = emptyList() + override val typeVariable: NewTypeVariable, + constraints: Collection = emptyList() ) : VariableWithConstraints { - override val constraints: List get() { - if (simplifiedConstraints == null) { - simplifiedConstraints = simplifyConstraints() + override val constraints: List + get() { + if (simplifiedConstraints == null) { + simplifiedConstraints = simplifyConstraints() + } + return simplifiedConstraints!! } - return simplifiedConstraints!! - } private val mutableConstraints = ArrayList(constraints) private var simplifiedConstraints: List? = null @@ -49,8 +50,7 @@ class MutableVariableWithConstraints( val actualConstraint = if (previousConstraintWithSameType.isNotEmpty()) { // i.e. previous is LOWER and new is UPPER or opposite situation Constraint(ConstraintKind.EQUALITY, constraint.type, constraint.position, constraint.typeHashCode) - } - else { + } else { constraint } mutableConstraints.add(actualConstraint) @@ -72,16 +72,16 @@ class MutableVariableWithConstraints( } private fun newConstraintIsUseless(oldKind: ConstraintKind, newKind: ConstraintKind) = - when (oldKind) { - ConstraintKind.EQUALITY -> true - ConstraintKind.LOWER -> newKind == ConstraintKind.LOWER - ConstraintKind.UPPER -> newKind == ConstraintKind.UPPER - } + when (oldKind) { + ConstraintKind.EQUALITY -> true + ConstraintKind.LOWER -> newKind == ConstraintKind.LOWER + ConstraintKind.UPPER -> newKind == ConstraintKind.UPPER + } private fun simplifyConstraints(): List { val equalityConstraints = mutableConstraints - .filter { it.kind == ConstraintKind.EQUALITY } - .groupBy { it.typeHashCode } + .filter { it.kind == ConstraintKind.EQUALITY } + .groupBy { it.typeHashCode } return mutableConstraints.filter { isUsefulConstraint(it, equalityConstraints) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index d2640385392..2924214eba9 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -31,16 +31,15 @@ import org.jetbrains.kotlin.types.typeUtil.contains import org.jetbrains.kotlin.utils.SmartList class NewConstraintSystemImpl( - private val constraintInjector: ConstraintInjector, - override val builtIns: KotlinBuiltIns -): - NewConstraintSystem, - ConstraintSystemBuilder, - ConstraintInjector.Context, - ResultTypeResolver.Context, - KotlinConstraintSystemCompleter.Context, - PostponedArgumentsAnalyzer.Context -{ + private val constraintInjector: ConstraintInjector, + override val builtIns: KotlinBuiltIns +) : + NewConstraintSystem, + ConstraintSystemBuilder, + ConstraintInjector.Context, + ResultTypeResolver.Context, + KotlinConstraintSystemCompleter.Context, + PostponedArgumentsAnalyzer.Context { private val storage = MutableConstraintStorage() private var state = State.BUILDING private val typeVariablesTransaction: MutableList = SmartList() @@ -83,10 +82,20 @@ class NewConstraintSystemImpl( } override fun addSubtypeConstraint(lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition) = - constraintInjector.addInitialSubtypeConstraint(apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) }, lowerType, upperType, position) + constraintInjector.addInitialSubtypeConstraint( + apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) }, + lowerType, + upperType, + position + ) override fun addEqualityConstraint(a: UnwrappedType, b: UnwrappedType, position: ConstraintPosition) = - constraintInjector.addInitialEqualityConstraint(apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) }, a, b, position) + constraintInjector.addInitialEqualityConstraint( + apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) }, + a, + b, + position + ) override fun getProperSuperTypeConstructors(type: UnwrappedType): List { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) @@ -146,7 +155,14 @@ class NewConstraintSystemImpl( // ConstraintSystemBuilder, KotlinConstraintSystemCompleter.Context override val hasContradiction: Boolean - get() = diagnostics.any { !it.candidateApplicability.isSuccess }.apply { checkState(State.FREEZED, State.BUILDING, State.COMPLETION, State.TRANSACTION) } + get() = diagnostics.any { !it.candidateApplicability.isSuccess }.apply { + checkState( + State.FREEZED, + State.BUILDING, + State.COMPLETION, + State.TRANSACTION + ) + } override fun addOtherSystem(otherSystem: ConstraintStorage) { storage.allTypeVariables.putAll(otherSystem.allTypeVariables) @@ -154,7 +170,8 @@ class NewConstraintSystemImpl( notFixedTypeVariables[variable] = MutableVariableWithConstraints(constraints.typeVariable, constraints.constraints) } storage.initialConstraints.addAll(otherSystem.initialConstraints) - storage.maxTypeDepthFromInitialConstraints = Math.max(storage.maxTypeDepthFromInitialConstraints, otherSystem.maxTypeDepthFromInitialConstraints) + storage.maxTypeDepthFromInitialConstraints = + Math.max(storage.maxTypeDepthFromInitialConstraints, otherSystem.maxTypeDepthFromInitialConstraints) storage.errors.addAll(otherSystem.errors) storage.fixedTypeVariables.putAll(otherSystem.fixedTypeVariables) } @@ -173,10 +190,11 @@ class NewConstraintSystemImpl( } // ConstraintInjector.Context - override val allTypeVariables: Map get() { - checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) - return storage.allTypeVariables - } + override val allTypeVariables: Map + get() { + checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) + return storage.allTypeVariables + } override var maxTypeDepthFromInitialConstraints: Int get() = storage.maxTypeDepthFromInitialConstraints @@ -191,10 +209,11 @@ class NewConstraintSystemImpl( } // ConstraintInjector.Context, FixationOrderCalculator.Context - override val notFixedTypeVariables: MutableMap get() { - checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) - return storage.notFixedTypeVariables - } + override val notFixedTypeVariables: MutableMap + get() { + checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) + return storage.notFixedTypeVariables + } // ConstraintInjector.Context, KotlinConstraintSystemCompleter.Context override fun addError(error: KotlinCallDiagnostic) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/TypeVariable.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/TypeVariable.kt index ff5b68b04b3..0bbec1d3613 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/TypeVariable.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/TypeVariable.kt @@ -29,7 +29,8 @@ import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor -class TypeVariableTypeConstructor(private val builtIns: KotlinBuiltIns, val debugName: String): TypeConstructor, NewTypeVariableConstructor { +class TypeVariableTypeConstructor(private val builtIns: KotlinBuiltIns, val debugName: String) : TypeConstructor, + NewTypeVariableConstructor { override fun getParameters(): List = emptyList() override fun getSupertypes(): Collection = emptyList() override fun isFinal(): Boolean = false @@ -47,18 +48,19 @@ sealed class NewTypeVariable(builtIns: KotlinBuiltIns, name: String) { // member scope is used if we have receiver with type TypeVariable(T) // todo add to member scope methods from supertypes for type variable val defaultType: SimpleType = KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope( - Annotations.EMPTY, freshTypeConstructor, arguments = emptyList(), - nullable = false, memberScope = builtIns.any.unsubstitutedMemberScope) + Annotations.EMPTY, freshTypeConstructor, arguments = emptyList(), + nullable = false, memberScope = builtIns.any.unsubstitutedMemberScope + ) override fun toString() = freshTypeConstructor.toString() } class TypeVariableFromCallableDescriptor( - val originalTypeParameter: TypeParameterDescriptor + val originalTypeParameter: TypeParameterDescriptor ) : NewTypeVariable(originalTypeParameter.builtIns, originalTypeParameter.name.identifier) class TypeVariableForLambdaReturnType( - val lambdaArgument: LambdaKotlinCallArgument, - builtIns: KotlinBuiltIns, - name: String + val lambdaArgument: LambdaKotlinCallArgument, + builtIns: KotlinBuiltIns, + name: String ) : NewTypeVariable(builtIns, name) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ArgumentsImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ArgumentsImpl.kt index ab3cb1d5b40..856439d0a68 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ArgumentsImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ArgumentsImpl.kt @@ -24,27 +24,27 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.prepareReceiverRegardingCap class FakeKotlinCallArgumentForCallableReference( - val index: Int + val index: Int ) : KotlinCallArgument { override val isSpread: Boolean get() = false override val argumentName: Name? get() = null } class ReceiverExpressionKotlinCallArgument private constructor( - override val receiver: ReceiverValueWithSmartCastInfo, - override val isSafeCall: Boolean = false, - val isVariableReceiverForInvoke: Boolean = false + override val receiver: ReceiverValueWithSmartCastInfo, + override val isSafeCall: Boolean = false, + val isVariableReceiverForInvoke: Boolean = false ) : ExpressionKotlinCallArgument { override val isSpread: Boolean get() = false override val argumentName: Name? get() = null - override fun toString() = "$receiver" + if(isSafeCall) "?" else "" + override fun toString() = "$receiver" + if (isSafeCall) "?" else "" companion object { // we create ReceiverArgument and fix capture types operator fun invoke( - receiver: ReceiverValueWithSmartCastInfo, - isSafeCall: Boolean = false, - isVariableReceiverForInvoke: Boolean = false + receiver: ReceiverValueWithSmartCastInfo, + isSafeCall: Boolean = false, + isVariableReceiverForInvoke: Boolean = false ) = ReceiverExpressionKotlinCallArgument(receiver.prepareReceiverRegardingCaptureTypes(), isSafeCall, isVariableReceiverForInvoke) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCall.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCall.kt index 0fa8f0b91fb..6ae426dadd2 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCall.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCall.kt @@ -78,8 +78,7 @@ fun KotlinCall.checkCallInvariants() { assert(dispatchReceiverForInvokeExtension == null) { "Dispatch receiver for invoke should be null for not function call: $dispatchReceiverForInvokeExtension" } - } - else { + } else { assert(externalArgument == null || !externalArgument!!.isSpread) { "External argument cannot nave spread element: $externalArgument" } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallArguments.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallArguments.kt index 16029a38435..f148647668c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallArguments.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallArguments.kt @@ -88,7 +88,7 @@ interface FunctionExpression : LambdaKotlinCallArgument { * D.E::foo <-> Expression */ sealed class LHSResult { - class Type(val qualifier: QualifierReceiver, resolvedType: UnwrappedType): LHSResult() { + class Type(val qualifier: QualifierReceiver, resolvedType: UnwrappedType) : LHSResult() { val unboundDetailedReceiver: ReceiverValueWithSmartCastInfo init { @@ -101,7 +101,7 @@ sealed class LHSResult { } } - class Object(val qualifier: QualifierReceiver): LHSResult() { + class Object(val qualifier: QualifierReceiver) : LHSResult() { val objectValueReceiver: ReceiverValueWithSmartCastInfo init { @@ -111,12 +111,13 @@ sealed class LHSResult { objectValueReceiver = qualifier.classValueReceiverWithSmartCastInfo ?: error("class value should be not null for $qualifier") } } - class Expression(val lshCallArgument: SimpleKotlinCallArgument): LHSResult() + + class Expression(val lshCallArgument: SimpleKotlinCallArgument) : LHSResult() // todo this case is forbid for now - object Empty: LHSResult() + object Empty : LHSResult() - object Error: LHSResult() + object Error : LHSResult() } interface CallableReferenceKotlinCallArgument : PostponableKotlinCallArgument { @@ -135,6 +136,6 @@ interface TypeArgument // todo allow '_' in frontend object TypeArgumentPlaceholder : TypeArgument -interface SimpleTypeArgument: TypeArgument { +interface SimpleTypeArgument : TypeArgument { val type: UnwrappedType } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt index ef7bbb2fdab..933fa0386f1 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinCallDiagnostics.kt @@ -31,7 +31,8 @@ abstract class InapplicableArgumentDiagnostic : KotlinCallDiagnostic(INAPPLICABL } // ArgumentsToParameterMapper -class TooManyArguments(val argument: KotlinCallArgument, val descriptor: CallableDescriptor) : KotlinCallDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR) { +class TooManyArguments(val argument: KotlinCallArgument, val descriptor: CallableDescriptor) : + KotlinCallDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR) { override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this) } @@ -50,54 +51,54 @@ class NameNotFound(val argument: KotlinCallArgument, val descriptor: CallableDes } class NoValueForParameter( - val parameterDescriptor: ValueParameterDescriptor, - val descriptor: CallableDescriptor + val parameterDescriptor: ValueParameterDescriptor, + val descriptor: CallableDescriptor ) : KotlinCallDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR) { override fun report(reporter: DiagnosticReporter) = reporter.onCall(this) } class ArgumentPassedTwice( - val argument: KotlinCallArgument, - val parameterDescriptor: ValueParameterDescriptor, - val firstOccurrence: ResolvedCallArgument + val argument: KotlinCallArgument, + val parameterDescriptor: ValueParameterDescriptor, + val firstOccurrence: ResolvedCallArgument ) : KotlinCallDiagnostic(INAPPLICABLE) { override fun report(reporter: DiagnosticReporter) = reporter.onCallArgumentName(argument, this) } class VarargArgumentOutsideParentheses( - override val argument: KotlinCallArgument, - val parameterDescriptor: ValueParameterDescriptor + override val argument: KotlinCallArgument, + val parameterDescriptor: ValueParameterDescriptor ) : InapplicableArgumentDiagnostic() class NameForAmbiguousParameter( - val argument: KotlinCallArgument, - val parameterDescriptor: ValueParameterDescriptor, - val overriddenParameterWithOtherName: ValueParameterDescriptor + val argument: KotlinCallArgument, + val parameterDescriptor: ValueParameterDescriptor, + val overriddenParameterWithOtherName: ValueParameterDescriptor ) : KotlinCallDiagnostic(CONVENTION_ERROR) { override fun report(reporter: DiagnosticReporter) = reporter.onCallArgumentName(argument, this) } class NamedArgumentReference( - val argument: KotlinCallArgument, - val parameterDescriptor: ValueParameterDescriptor + val argument: KotlinCallArgument, + val parameterDescriptor: ValueParameterDescriptor ) : KotlinCallDiagnostic(RESOLVED) { override fun report(reporter: DiagnosticReporter) = reporter.onCallArgumentName(argument, this) } // TypeArgumentsToParameterMapper class WrongCountOfTypeArguments( - val descriptor: CallableDescriptor, - val currentCount: Int + val descriptor: CallableDescriptor, + val currentCount: Int ) : KotlinCallDiagnostic(INAPPLICABLE) { override fun report(reporter: DiagnosticReporter) = reporter.onTypeArguments(this) } // Callable reference resolution class CallableReferenceNotCompatible( - override val argument: CallableReferenceKotlinCallArgument, - val candidate: CallableMemberDescriptor, - val expectedType: UnwrappedType?, - val callableReverenceType: UnwrappedType + override val argument: CallableReferenceKotlinCallArgument, + val candidate: CallableMemberDescriptor, + val expectedType: UnwrappedType?, + val callableReverenceType: UnwrappedType ) : InapplicableArgumentDiagnostic() // supported by FE but not supported by BE now @@ -110,35 +111,35 @@ class CallableReferencesDefaultArgumentUsed( } class NotCallableMemberReference( - override val argument: CallableReferenceKotlinCallArgument, - val candidate: CallableDescriptor + override val argument: CallableReferenceKotlinCallArgument, + val candidate: CallableDescriptor ) : InapplicableArgumentDiagnostic() class NoneCallableReferenceCandidates(override val argument: CallableReferenceKotlinCallArgument) : InapplicableArgumentDiagnostic() class CallableReferenceCandidatesAmbiguity( - override val argument: CallableReferenceKotlinCallArgument, - val candidates: Collection + override val argument: CallableReferenceKotlinCallArgument, + val candidates: Collection ) : InapplicableArgumentDiagnostic() class NotCallableExpectedType( - override val argument: CallableReferenceKotlinCallArgument, - val expectedType: UnwrappedType, - val notCallableTypeConstructor: TypeConstructor + override val argument: CallableReferenceKotlinCallArgument, + val expectedType: UnwrappedType, + val notCallableTypeConstructor: TypeConstructor ) : InapplicableArgumentDiagnostic() // SmartCasts class SmartCastDiagnostic( - val argument: ExpressionKotlinCallArgument, - val smartCastType: UnwrappedType, - val kotlinCall: KotlinCall? -): KotlinCallDiagnostic(RESOLVED) { + val argument: ExpressionKotlinCallArgument, + val smartCastType: UnwrappedType, + val kotlinCall: KotlinCall? +) : KotlinCallDiagnostic(RESOLVED) { override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this) } class UnstableSmartCast( - val argument: ExpressionKotlinCallArgument, - val targetType: UnwrappedType + val argument: ExpressionKotlinCallArgument, + val targetType: UnwrappedType ) : KotlinCallDiagnostic(MAY_THROW_RUNTIME_ERROR) { override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this) } @@ -172,8 +173,8 @@ class NoneCandidatesCallDiagnostic(val kotlinCall: KotlinCall) : KotlinCallDiagn } class ManyCandidatesCallDiagnostic( - val kotlinCall: KotlinCall, - val candidates: Collection + val kotlinCall: KotlinCall, + val candidates: Collection ) : KotlinCallDiagnostic(INAPPLICABLE) { override fun report(reporter: DiagnosticReporter) { reporter.onCall(this) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt index 3c3478dd12a..b979bc449b9 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/KotlinResolverContext.kt @@ -36,20 +36,20 @@ import org.jetbrains.kotlin.types.isDynamic class KotlinCallComponents( - val statelessCallbacks: KotlinResolutionStatelessCallbacks, - val argumentsToParametersMapper: ArgumentsToParametersMapper, - val typeArgumentsToParametersMapper: TypeArgumentsToParametersMapper, - val constraintInjector: ConstraintInjector, - val reflectionTypes: ReflectionTypes, - val builtIns: KotlinBuiltIns, - val languageVersionSettings: LanguageVersionSettings + val statelessCallbacks: KotlinResolutionStatelessCallbacks, + val argumentsToParametersMapper: ArgumentsToParametersMapper, + val typeArgumentsToParametersMapper: TypeArgumentsToParametersMapper, + val constraintInjector: ConstraintInjector, + val reflectionTypes: ReflectionTypes, + val builtIns: KotlinBuiltIns, + val languageVersionSettings: LanguageVersionSettings ) class SimpleCandidateFactory( - val callComponents: KotlinCallComponents, - val scopeTower: ImplicitScopeTower, - val kotlinCall: KotlinCall -): CandidateFactory { + val callComponents: KotlinCallComponents, + val scopeTower: ImplicitScopeTower, + val kotlinCall: KotlinCall +) : CandidateFactory { val baseSystem: ConstraintStorage init { @@ -66,11 +66,11 @@ class SimpleCandidateFactory( // todo: try something else, because current method is ugly and unstable private fun createReceiverArgument( - explicitReceiver: ReceiverKotlinCallArgument?, - fromResolution: ReceiverValueWithSmartCastInfo? + explicitReceiver: ReceiverKotlinCallArgument?, + fromResolution: ReceiverValueWithSmartCastInfo? ): SimpleKotlinCallArgument? = - explicitReceiver as? SimpleKotlinCallArgument ?: // qualifier receiver cannot be safe - fromResolution?.let { ReceiverExpressionKotlinCallArgument(it, isSafeCall = false) } // todo smartcast implicit this + explicitReceiver as? SimpleKotlinCallArgument ?: // qualifier receiver cannot be safe + fromResolution?.let { ReceiverExpressionKotlinCallArgument(it, isSafeCall = false) } // todo smartcast implicit this private fun KotlinCall.getExplicitDispatchReceiver(explicitReceiverKind: ExplicitReceiverKind) = when (explicitReceiverKind) { ExplicitReceiverKind.DISPATCH_RECEIVER -> explicitReceiver @@ -86,38 +86,55 @@ class SimpleCandidateFactory( fun createCandidate(givenCandidate: GivenCandidate): KotlinResolutionCandidate { val isSafeCall = (kotlinCall.explicitReceiver as? SimpleKotlinCallArgument)?.isSafeCall ?: false - val explicitReceiverKind = if (givenCandidate.dispatchReceiver == null) ExplicitReceiverKind.NO_EXPLICIT_RECEIVER else ExplicitReceiverKind.DISPATCH_RECEIVER + val explicitReceiverKind = + if (givenCandidate.dispatchReceiver == null) ExplicitReceiverKind.NO_EXPLICIT_RECEIVER else ExplicitReceiverKind.DISPATCH_RECEIVER val dispatchArgumentReceiver = givenCandidate.dispatchReceiver?.let { ReceiverExpressionKotlinCallArgument(it, isSafeCall) } - return createCandidate(givenCandidate.descriptor, explicitReceiverKind, dispatchArgumentReceiver, null, - listOf(), givenCandidate.knownTypeParametersResultingSubstitutor) + return createCandidate( + givenCandidate.descriptor, explicitReceiverKind, dispatchArgumentReceiver, null, + listOf(), givenCandidate.knownTypeParametersResultingSubstitutor + ) } override fun createCandidate( - towerCandidate: CandidateWithBoundDispatchReceiver, - explicitReceiverKind: ExplicitReceiverKind, - extensionReceiver: ReceiverValueWithSmartCastInfo? + towerCandidate: CandidateWithBoundDispatchReceiver, + explicitReceiverKind: ExplicitReceiverKind, + extensionReceiver: ReceiverValueWithSmartCastInfo? ): KotlinResolutionCandidate { - val dispatchArgumentReceiver = createReceiverArgument(kotlinCall.getExplicitDispatchReceiver(explicitReceiverKind), - towerCandidate.dispatchReceiver) - val extensionArgumentReceiver = createReceiverArgument(kotlinCall.getExplicitExtensionReceiver(explicitReceiverKind), extensionReceiver) + val dispatchArgumentReceiver = createReceiverArgument( + kotlinCall.getExplicitDispatchReceiver(explicitReceiverKind), + towerCandidate.dispatchReceiver + ) + val extensionArgumentReceiver = + createReceiverArgument(kotlinCall.getExplicitExtensionReceiver(explicitReceiverKind), extensionReceiver) - return createCandidate(towerCandidate.descriptor, explicitReceiverKind, dispatchArgumentReceiver, - extensionArgumentReceiver, towerCandidate.diagnostics, knownSubstitutor = null) + return createCandidate( + towerCandidate.descriptor, explicitReceiverKind, dispatchArgumentReceiver, + extensionArgumentReceiver, towerCandidate.diagnostics, knownSubstitutor = null + ) } private fun createCandidate( - descriptor: CallableDescriptor, - explicitReceiverKind: ExplicitReceiverKind, - dispatchArgumentReceiver: SimpleKotlinCallArgument?, - extensionArgumentReceiver: SimpleKotlinCallArgument?, - initialDiagnostics: Collection, - knownSubstitutor: TypeSubstitutor? + descriptor: CallableDescriptor, + explicitReceiverKind: ExplicitReceiverKind, + dispatchArgumentReceiver: SimpleKotlinCallArgument?, + extensionArgumentReceiver: SimpleKotlinCallArgument?, + initialDiagnostics: Collection, + knownSubstitutor: TypeSubstitutor? ): KotlinResolutionCandidate { - val resolvedKtCall = MutableResolvedCallAtom(kotlinCall, descriptor, explicitReceiverKind, - dispatchArgumentReceiver, extensionArgumentReceiver) + val resolvedKtCall = MutableResolvedCallAtom( + kotlinCall, descriptor, explicitReceiverKind, + dispatchArgumentReceiver, extensionArgumentReceiver + ) if (ErrorUtils.isError(descriptor)) { - return KotlinResolutionCandidate(callComponents, scopeTower, baseSystem, resolvedKtCall, knownSubstitutor, listOf(ErrorDescriptorResolutionPart)) + return KotlinResolutionCandidate( + callComponents, + scopeTower, + baseSystem, + resolvedKtCall, + knownSubstitutor, + listOf(ErrorDescriptorResolutionPart) + ) } val candidate = KotlinResolutionCandidate(callComponents, scopeTower, baseSystem, resolvedKtCall, knownSubstitutor) @@ -145,45 +162,47 @@ class SimpleCandidateFactory( val errorScope = ErrorUtils.createErrorScope("Error resolution candidate for call $kotlinCall") val errorDescriptor = if (kotlinCall.callKind == KotlinCallKind.VARIABLE) { errorScope.getContributedVariables(kotlinCall.name, scopeTower.location) - } - else { + } else { errorScope.getContributedFunctions(kotlinCall.name, scopeTower.location) }.first() val dispatchReceiver = createReceiverArgument(kotlinCall.explicitReceiver, fromResolution = null) - val explicitReceiverKind = if (dispatchReceiver == null) ExplicitReceiverKind.NO_EXPLICIT_RECEIVER else ExplicitReceiverKind.DISPATCH_RECEIVER + val explicitReceiverKind = + if (dispatchReceiver == null) ExplicitReceiverKind.NO_EXPLICIT_RECEIVER else ExplicitReceiverKind.DISPATCH_RECEIVER - return createCandidate(errorDescriptor, explicitReceiverKind, dispatchReceiver, extensionArgumentReceiver = null, - initialDiagnostics = listOf(), knownSubstitutor = null) + return createCandidate( + errorDescriptor, explicitReceiverKind, dispatchReceiver, extensionArgumentReceiver = null, + initialDiagnostics = listOf(), knownSubstitutor = null + ) } } enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) { VARIABLE( - CheckVisibility, - CheckInfixResolutionPart, - CheckOperatorResolutionPart, - CheckSuperExpressionCallPart, - NoTypeArguments, - NoArguments, - CreateFreshVariablesSubstitutor, - CheckExplicitReceiverKindConsistency, - CheckReceivers + CheckVisibility, + CheckInfixResolutionPart, + CheckOperatorResolutionPart, + CheckSuperExpressionCallPart, + NoTypeArguments, + NoArguments, + CreateFreshVariablesSubstitutor, + CheckExplicitReceiverKindConsistency, + CheckReceivers ), FUNCTION( - CheckInstantiationOfAbstractClass, - CheckVisibility, - CheckInfixResolutionPart, - CheckSuperExpressionCallPart, - MapTypeArguments, - MapArguments, - ArgumentsToCandidateParameterDescriptor, - CreateFreshVariablesSubstitutor, - CheckExplicitReceiverKindConsistency, - CheckReceivers, - CheckArguments, - CheckExternalArgument + CheckInstantiationOfAbstractClass, + CheckVisibility, + CheckInfixResolutionPart, + CheckSuperExpressionCallPart, + MapTypeArguments, + MapArguments, + ArgumentsToCandidateParameterDescriptor, + CreateFreshVariablesSubstitutor, + CheckExplicitReceiverKindConsistency, + CheckReceivers, + CheckArguments, + CheckExternalArgument ), UNSUPPORTED(); @@ -191,8 +210,8 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) { } class GivenCandidate( - val descriptor: FunctionDescriptor, - val dispatchReceiver: ReceiverValueWithSmartCastInfo?, - val knownTypeParametersResultingSubstitutor: TypeSubstitutor? + val descriptor: FunctionDescriptor, + val dispatchReceiver: ReceiverValueWithSmartCastInfo?, + val knownTypeParametersResultingSubstitutor: TypeSubstitutor? ) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt index 7107d98777a..23483840fd8 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionAtoms.kt @@ -74,14 +74,15 @@ class ResolvedExpressionAtom(override val atom: ExpressionKotlinCallArgument) : setAnalyzedResults(listOf()) } } + sealed class PostponedResolvedAtom : ResolvedAtom() { abstract val inputTypes: Collection abstract val outputType: UnwrappedType? } class LambdaWithTypeVariableAsExpectedTypeAtom( - override val atom: LambdaKotlinCallArgument, - val expectedType: UnwrappedType + override val atom: LambdaKotlinCallArgument, + val expectedType: UnwrappedType ) : PostponedResolvedAtom() { override val inputTypes: Collection get() = listOf(expectedType) override val outputType: UnwrappedType? get() = null @@ -92,19 +93,19 @@ class LambdaWithTypeVariableAsExpectedTypeAtom( } class ResolvedLambdaAtom( - override val atom: LambdaKotlinCallArgument, - val isSuspend: Boolean, - val receiver: UnwrappedType?, - val parameters: List, - val returnType: UnwrappedType, - val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType? + override val atom: LambdaKotlinCallArgument, + val isSuspend: Boolean, + val receiver: UnwrappedType?, + val parameters: List, + val returnType: UnwrappedType, + val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType? ) : PostponedResolvedAtom() { lateinit var resultArguments: List private set fun setAnalyzedResults( - resultArguments: List, - subResolvedAtoms: List + resultArguments: List, + subResolvedAtoms: List ) { this.resultArguments = resultArguments setAnalyzedResults(subResolvedAtoms) @@ -115,15 +116,15 @@ class ResolvedLambdaAtom( } class ResolvedCallableReferenceAtom( - override val atom: CallableReferenceKotlinCallArgument, - val expectedType: UnwrappedType? + override val atom: CallableReferenceKotlinCallArgument, + val expectedType: UnwrappedType? ) : PostponedResolvedAtom() { var candidate: CallableReferenceCandidate? = null private set fun setAnalyzedResults( - candidate: CallableReferenceCandidate?, - subResolvedAtoms: List + candidate: CallableReferenceCandidate?, + subResolvedAtoms: List ) { this.candidate = candidate setAnalyzedResults(subResolvedAtoms) @@ -145,8 +146,8 @@ class ResolvedCallableReferenceAtom( } class ResolvedCollectionLiteralAtom( - override val atom: CollectionLiteralKotlinCallArgument, - val expectedType: UnwrappedType? + override val atom: CollectionLiteralKotlinCallArgument, + val expectedType: UnwrappedType? ) : ResolvedAtom() { init { setAnalyzedResults(listOf()) @@ -154,11 +155,11 @@ class ResolvedCollectionLiteralAtom( } class CallResolutionResult( - val type: Type, - val resultCallAtom: ResolvedCallAtom?, - val diagnostics: List, - val constraintSystem: ConstraintStorage, - val allCandidates: Collection? = null + val type: Type, + val resultCallAtom: ResolvedCallAtom?, + val diagnostics: List, + val constraintSystem: ConstraintStorage, + val allCandidates: Collection? = null ) : ResolvedAtom() { override val atom: ResolutionAtom? get() = null @@ -176,7 +177,8 @@ class CallResolutionResult( override fun toString() = "$type, resultCallAtom = $resultCallAtom, (${diagnostics.joinToString()})" } -val ResolvedCallAtom.freshReturnType: UnwrappedType? get() { - val returnType = candidateDescriptor.returnType ?: return null - return substitutor.safeSubstitute(returnType.unwrap()) -} \ No newline at end of file +val ResolvedCallAtom.freshReturnType: UnwrappedType? + get() { + val returnType = candidateDescriptor.returnType ?: return null + return substitutor.safeSubstitute(returnType.unwrap()) + } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt index e86ae9ad79a..54e52ac24e7 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt @@ -56,17 +56,18 @@ interface KotlinDiagnosticsHolder { fun KotlinDiagnosticsHolder.addDiagnosticIfNotNull(diagnostic: KotlinCallDiagnostic?) { diagnostic?.let { addDiagnostic(it) } } + /** * baseSystem contains all information from arguments, i.e. it is union of all system of arguments * Also by convention we suppose that baseSystem has no contradiction */ class KotlinResolutionCandidate( - val callComponents: KotlinCallComponents, - val scopeTower: ImplicitScopeTower, - private val baseSystem: ConstraintStorage, - val resolvedCall: MutableResolvedCallAtom, - val knownTypeParametersResultingSubstitutor: TypeSubstitutor? = null, - private val resolutionSequence: List = resolvedCall.atom.callKind.resolutionSequence + val callComponents: KotlinCallComponents, + val scopeTower: ImplicitScopeTower, + private val baseSystem: ConstraintStorage, + val resolvedCall: MutableResolvedCallAtom, + val knownTypeParametersResultingSubstitutor: TypeSubstitutor? = null, + private val resolutionSequence: List = resolvedCall.atom.callKind.resolutionSequence ) : Candidate, KotlinDiagnosticsHolder { val diagnosticsFromResolutionParts = arrayListOf() // TODO: this is mutable list, take diagnostics only once! private var newSystem: NewConstraintSystemImpl? = null @@ -106,8 +107,7 @@ class KotlinResolutionCandidate( if (workStep >= workCount) { partIndex++ workStep -= workCount - } - else { + } else { break } } @@ -165,11 +165,11 @@ class KotlinResolutionCandidate( } class MutableResolvedCallAtom( - override val atom: KotlinCall, - override val candidateDescriptor: CallableDescriptor, // original candidate descriptor - override val explicitReceiverKind: ExplicitReceiverKind, - override val dispatchReceiverArgument: SimpleKotlinCallArgument?, - override val extensionReceiverArgument: SimpleKotlinCallArgument? + override val atom: KotlinCall, + override val candidateDescriptor: CallableDescriptor, // original candidate descriptor + override val explicitReceiverKind: ExplicitReceiverKind, + override val dispatchReceiverArgument: SimpleKotlinCallArgument?, + override val extensionReceiverArgument: SimpleKotlinCallArgument? ) : ResolvedCallAtom() { override lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping override lateinit var argumentMappingByOriginal: Map diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt index 99080fa93a0..cf741ba9710 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt @@ -26,11 +26,11 @@ sealed class ResolvedCallArgument { } - class SimpleArgument(val callArgument: KotlinCallArgument): ResolvedCallArgument() { + class SimpleArgument(val callArgument: KotlinCallArgument) : ResolvedCallArgument() { override val arguments: List get() = listOf(callArgument) } - class VarargArgument(override val arguments: List): ResolvedCallArgument() + class VarargArgument(override val arguments: List) : ResolvedCallArgument() } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt index 72703438bc6..4df725f9ee2 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt @@ -33,76 +33,79 @@ interface SpecificityComparisonCallbacks { interface TypeSpecificityComparator { fun isDefinitelyLessSpecific(specific: KotlinType, general: KotlinType): Boolean - object NONE: TypeSpecificityComparator { + object NONE : TypeSpecificityComparator { override fun isDefinitelyLessSpecific(specific: KotlinType, general: KotlinType) = false } } class FlatSignature private constructor( - val origin: T, - val typeParameters: Collection, - val valueParameterTypes: List, - val hasExtensionReceiver: Boolean, - val hasVarargs: Boolean, - val numDefaults: Int, - val isExpect: Boolean, - val isSyntheticMember: Boolean + val origin: T, + val typeParameters: Collection, + val valueParameterTypes: List, + val hasExtensionReceiver: Boolean, + val hasVarargs: Boolean, + val numDefaults: Int, + val isExpect: Boolean, + val isSyntheticMember: Boolean ) { val isGeneric = typeParameters.isNotEmpty() companion object { fun createFromReflectionType( - origin: T, - descriptor: CallableDescriptor, - numDefaults: Int, - reflectionType: UnwrappedType + origin: T, + descriptor: CallableDescriptor, + numDefaults: Int, + reflectionType: UnwrappedType ): FlatSignature { - return FlatSignature(origin, - descriptor.typeParameters, - reflectionType.arguments.map { it.type }, // should we drop return type? - hasExtensionReceiver = false, - hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, - numDefaults = numDefaults, - isExpect = descriptor is MemberDescriptor && descriptor.isExpect, - isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> - ) + return FlatSignature( + origin, + descriptor.typeParameters, + reflectionType.arguments.map { it.type }, // should we drop return type? + hasExtensionReceiver = false, + hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, + numDefaults = numDefaults, + isExpect = descriptor is MemberDescriptor && descriptor.isExpect, + isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> + ) } fun create( - origin: T, - descriptor: CallableDescriptor, - numDefaults: Int, - parameterTypes: List + origin: T, + descriptor: CallableDescriptor, + numDefaults: Int, + parameterTypes: List ): FlatSignature { val extensionReceiverType = descriptor.extensionReceiverParameter?.type - return FlatSignature(origin, - descriptor.typeParameters, - valueParameterTypes = - listOfNotNull(extensionReceiverType) + parameterTypes, - hasExtensionReceiver = extensionReceiverType != null, - hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, - numDefaults = numDefaults, - isExpect = descriptor is MemberDescriptor && descriptor.isExpect, - isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> + return FlatSignature( + origin, + descriptor.typeParameters, + valueParameterTypes = + listOfNotNull(extensionReceiverType) + parameterTypes, + hasExtensionReceiver = extensionReceiverType != null, + hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, + numDefaults = numDefaults, + isExpect = descriptor is MemberDescriptor && descriptor.isExpect, + isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> ) } fun createFromCallableDescriptor( - descriptor: D + descriptor: D ): FlatSignature = - create(descriptor, descriptor, numDefaults = 0, parameterTypes = descriptor.valueParameters.map { it.argumentValueType }) + create(descriptor, descriptor, numDefaults = 0, parameterTypes = descriptor.valueParameters.map { it.argumentValueType }) fun createForPossiblyShadowedExtension(descriptor: D): FlatSignature = - FlatSignature(descriptor, - descriptor.typeParameters, - valueParameterTypes = descriptor.valueParameters.map { it.argumentValueType }, - hasExtensionReceiver = false, - hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, - numDefaults = descriptor.valueParameters.count { it.hasDefaultValue() }, - isExpect = descriptor is MemberDescriptor && descriptor.isExpect, - isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> - ) + FlatSignature( + descriptor, + descriptor.typeParameters, + valueParameterTypes = descriptor.valueParameters.map { it.argumentValueType }, + hasExtensionReceiver = false, + hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, + numDefaults = descriptor.valueParameters.count { it.hasDefaultValue() }, + isExpect = descriptor is MemberDescriptor && descriptor.isExpect, + isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> + ) val ValueParameterDescriptor.argumentValueType get() = varargElementType ?: type } @@ -119,10 +122,10 @@ interface SimpleConstraintSystem { } fun SimpleConstraintSystem.isSignatureNotLessSpecific( - specific: FlatSignature, - general: FlatSignature, - callbacks: SpecificityComparisonCallbacks, - specificityComparator: TypeSpecificityComparator + specific: FlatSignature, + general: FlatSignature, + callbacks: SpecificityComparisonCallbacks, + specificityComparator: TypeSpecificityComparator ): Boolean { if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return false if (specific.valueParameterTypes.size != general.valueParameterTypes.size) return false @@ -143,8 +146,7 @@ fun SimpleConstraintSystem.isSignatureNotLessSpecific( return false } } - } - else { + } else { val substitutedGeneralType = typeSubstitutor.safeSubstitute(generalType, Variance.INVARIANT) /** diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt index a46d3c53e63..de7fef42e45 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/OverloadingConflictResolver.kt @@ -33,41 +33,40 @@ import org.jetbrains.kotlin.types.TypeUtils import java.util.* open class OverloadingConflictResolver( - private val builtIns: KotlinBuiltIns, - private val specificityComparator: TypeSpecificityComparator, - private val getResultingDescriptor: (C) -> CallableDescriptor, - private val createEmptyConstraintSystem: () -> SimpleConstraintSystem, - private val createFlatSignature: (C) -> FlatSignature, - private val getVariableCandidates: (C) -> C?, // for variable WithInvoke - private val isFromSources: (CallableDescriptor) -> Boolean + private val builtIns: KotlinBuiltIns, + private val specificityComparator: TypeSpecificityComparator, + private val getResultingDescriptor: (C) -> CallableDescriptor, + private val createEmptyConstraintSystem: () -> SimpleConstraintSystem, + private val createFlatSignature: (C) -> FlatSignature, + private val getVariableCandidates: (C) -> C?, // for variable WithInvoke + private val isFromSources: (CallableDescriptor) -> Boolean ) { private val resolvedCallHashingStrategy = object : TObjectHashingStrategy { override fun equals(call1: C?, call2: C?): Boolean = - if (call1 != null && call2 != null) - call1.resultingDescriptor == call2.resultingDescriptor - else - call1 == call2 + if (call1 != null && call2 != null) + call1.resultingDescriptor == call2.resultingDescriptor + else + call1 == call2 override fun computeHashCode(call: C?): Int = - call?.resultingDescriptor?.hashCode() ?: 0 + call?.resultingDescriptor?.hashCode() ?: 0 } private val C.resultingDescriptor: CallableDescriptor get() = getResultingDescriptor(this) // if result contains only one element -- it is maximally specific; otherwise we have ambiguity fun chooseMaximallySpecificCandidates( - candidates: Collection, - checkArgumentsMode: CheckArgumentTypesMode, - discriminateGenerics: Boolean, - isDebuggerContext: Boolean + candidates: Collection, + checkArgumentsMode: CheckArgumentTypesMode, + discriminateGenerics: Boolean, + isDebuggerContext: Boolean ): Set { candidates.setIfOneOrEmpty()?.let { return it } val fixedCandidates = if (getVariableCandidates(candidates.first()) != null) { findMaximallySpecificVariableAsFunctionCalls(candidates, isDebuggerContext) ?: return LinkedHashSet(candidates) - } - else { + } else { candidates } @@ -131,35 +130,35 @@ open class OverloadingConflictResolver( return result } - private fun Collection.setIfOneOrEmpty() = when(size) { + private fun Collection.setIfOneOrEmpty() = when (size) { 0 -> emptySet() 1 -> setOf(single()) else -> null } private fun findMaximallySpecific( - candidates: Set, - checkArgumentsMode: CheckArgumentTypesMode, - discriminateGenerics: Boolean, - isDebuggerContext: Boolean + candidates: Set, + checkArgumentsMode: CheckArgumentTypesMode, + discriminateGenerics: Boolean, + isDebuggerContext: Boolean ): C? = - if (candidates.size <= 1) - candidates.firstOrNull() - else when (checkArgumentsMode) { - CheckArgumentTypesMode.CHECK_CALLABLE_TYPE -> - uniquifyCandidatesSet(candidates).singleOrNull { - isDefinitelyMostSpecific(it, candidates) { call1, call2 -> - isNotLessSpecificCallableReference(call1.resultingDescriptor, call2.resultingDescriptor) - } + if (candidates.size <= 1) + candidates.firstOrNull() + else when (checkArgumentsMode) { + CheckArgumentTypesMode.CHECK_CALLABLE_TYPE -> + uniquifyCandidatesSet(candidates).singleOrNull { + isDefinitelyMostSpecific(it, candidates) { call1, call2 -> + isNotLessSpecificCallableReference(call1.resultingDescriptor, call2.resultingDescriptor) } + } - CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS -> - findMaximallySpecificCall(candidates, discriminateGenerics, isDebuggerContext) - ?: findMaximallySpecificCall( + CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS -> + findMaximallySpecificCall(candidates, discriminateGenerics, isDebuggerContext) + ?: findMaximallySpecificCall( candidates.filterNotTo(mutableSetOf()) { createFlatSignature(it).isSyntheticMember }, discriminateGenerics, isDebuggerContext - ) - } + ) + } // null means ambiguity between variables private fun findMaximallySpecificVariableAsFunctionCalls(candidates: Collection, isDebuggerContext: Boolean): Set? { @@ -167,8 +166,10 @@ open class OverloadingConflictResolver( getVariableCandidates(it) ?: throw AssertionError("Regular call among variable-as-function calls: $it") } - val maxSpecificVariableCalls = chooseMaximallySpecificCandidates(variableCalls, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, - isDebuggerContext = isDebuggerContext, discriminateGenerics = false) + val maxSpecificVariableCalls = chooseMaximallySpecificCandidates( + variableCalls, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, + isDebuggerContext = isDebuggerContext, discriminateGenerics = false + ) val maxSpecificVariableCall = maxSpecificVariableCalls.singleOrNull() ?: return null return candidates.filterTo(newResolvedCallSet(2)) { @@ -177,29 +178,25 @@ open class OverloadingConflictResolver( } private fun findMaximallySpecificCall( - candidates: Set, - discriminateGenerics: Boolean, - isDebuggerContext: Boolean + candidates: Set, + discriminateGenerics: Boolean, + isDebuggerContext: Boolean ): C? { val filteredCandidates = uniquifyCandidatesSet(candidates) if (filteredCandidates.size <= 1) return filteredCandidates.singleOrNull() - val conflictingCandidates = filteredCandidates.map { - candidateCall -> + val conflictingCandidates = filteredCandidates.map { candidateCall -> createFlatSignature(candidateCall) } - val bestCandidatesByParameterTypes = conflictingCandidates.filter { - candidate -> - isMostSpecific(candidate, conflictingCandidates) { - call1, call2 -> + val bestCandidatesByParameterTypes = conflictingCandidates.filter { candidate -> + isMostSpecific(candidate, conflictingCandidates) { call1, call2 -> isNotLessSpecificCallWithArgumentMapping(call1, call2, discriminateGenerics) } } - return bestCandidatesByParameterTypes.exactMaxWith { - call1, call2 -> + return bestCandidatesByParameterTypes.exactMaxWith { call1, call2 -> isOfNotLessSpecificShape(call1, call2) && isOfNotLessSpecificVisibilityForDebugger(call1, call2, isDebuggerContext) }?.origin } @@ -219,29 +216,34 @@ open class OverloadingConflictResolver( } private inline fun isMostSpecific(candidate: C, candidates: Collection, isNotLessSpecific: (C, C) -> Boolean): Boolean = - candidates.all { - other -> - candidate === other || - isNotLessSpecific(candidate, other) - } + candidates.all { other -> + candidate === other || + isNotLessSpecific(candidate, other) + } - private inline fun isDefinitelyMostSpecific(candidate: C, candidates: Collection, isNotLessSpecific: (C, C) -> Boolean): Boolean = - candidates.all { - other -> - candidate === other || - isNotLessSpecific(candidate, other) && !isNotLessSpecific(other, candidate) - } + private inline fun isDefinitelyMostSpecific( + candidate: C, + candidates: Collection, + isNotLessSpecific: (C, C) -> Boolean + ): Boolean = + candidates.all { other -> + candidate === other || + isNotLessSpecific(candidate, other) && !isNotLessSpecific(other, candidate) + } /** * `call1` is not less specific than `call2` */ private fun isNotLessSpecificCallWithArgumentMapping( - call1: FlatSignature, - call2: FlatSignature, - discriminateGenerics: Boolean + call1: FlatSignature, + call2: FlatSignature, + discriminateGenerics: Boolean ): Boolean { - return tryCompareDescriptorsFromScripts(call1.candidateDescriptor(), call2.candidateDescriptor()) ?: - compareCallsByUsedArguments(call1, call2, discriminateGenerics) + return tryCompareDescriptorsFromScripts(call1.candidateDescriptor(), call2.candidateDescriptor()) ?: compareCallsByUsedArguments( + call1, + call2, + discriminateGenerics + ) } /** @@ -249,9 +251,9 @@ open class OverloadingConflictResolver( * `false` otherwise. */ private fun compareCallsByUsedArguments( - call1: FlatSignature, - call2: FlatSignature, - discriminateGenerics: Boolean + call1: FlatSignature, + call2: FlatSignature, + discriminateGenerics: Boolean ): Boolean { if (discriminateGenerics) { val isGeneric1 = call1.isGeneric @@ -266,7 +268,12 @@ open class OverloadingConflictResolver( if (!call1.isExpect && call2.isExpect) return true if (call1.isExpect && !call2.isExpect) return false - return createEmptyConstraintSystem().isSignatureNotLessSpecific(call1, call2, SpecificityComparisonWithNumerics, specificityComparator) + return createEmptyConstraintSystem().isSignatureNotLessSpecific( + call1, + call2, + SpecificityComparisonWithNumerics, + specificityComparator + ) } private val SpecificityComparisonWithNumerics = object : SpecificityComparisonCallbacks { @@ -295,8 +302,8 @@ open class OverloadingConflictResolver( } private fun isOfNotLessSpecificShape( - call1: FlatSignature, - call2: FlatSignature + call1: FlatSignature, + call2: FlatSignature ): Boolean { val hasVarargs1 = call1.hasVarargs val hasVarargs2 = call2.hasVarargs @@ -311,9 +318,9 @@ open class OverloadingConflictResolver( } private fun isOfNotLessSpecificVisibilityForDebugger( - call1: FlatSignature, - call2: FlatSignature, - isDebuggerContext: Boolean + call1: FlatSignature, + call2: FlatSignature, + isDebuggerContext: Boolean ): Boolean { if (isDebuggerContext) { val isMoreVisible1 = Visibilities.compare(call1.descriptorVisibility(), call2.descriptorVisibility()) @@ -352,7 +359,12 @@ open class OverloadingConflictResolver( val fSignature = FlatSignature.createFromCallableDescriptor(f) val gSignature = FlatSignature.createFromCallableDescriptor(g) - if (!createEmptyConstraintSystem().isSignatureNotLessSpecific(fSignature, gSignature, SpecificityComparisonWithNumerics, specificityComparator)) { + if (!createEmptyConstraintSystem().isSignatureNotLessSpecific( + fSignature, + gSignature, + SpecificityComparisonWithNumerics, + specificityComparator + )) { return false } @@ -365,20 +377,19 @@ open class OverloadingConflictResolver( } private fun isNotLessSpecificCallableReference(f: CallableDescriptor, g: CallableDescriptor): Boolean = - // TODO should we "discriminate generic descriptors" for callable references? - tryCompareDescriptorsFromScripts(f, g) ?: - isNotLessSpecificCallableReferenceDescriptor(f, g) + // TODO should we "discriminate generic descriptors" for callable references? + tryCompareDescriptorsFromScripts(f, g) ?: isNotLessSpecificCallableReferenceDescriptor(f, g) // Different smart casts may lead to the same candidate descriptor wrapped into different ResolvedCallImpl objects private fun uniquifyCandidatesSet(candidates: Collection): Set = - THashSet(candidates.size, resolvedCallHashingStrategy).apply { addAll(candidates) } + THashSet(candidates.size, resolvedCallHashingStrategy).apply { addAll(candidates) } private fun newResolvedCallSet(expectedSize: Int): MutableSet = - THashSet(expectedSize, resolvedCallHashingStrategy) + THashSet(expectedSize, resolvedCallHashingStrategy) private fun FlatSignature.candidateDescriptor() = - origin.resultingDescriptor.original + origin.resultingDescriptor.original private fun FlatSignature.descriptorVisibility() = - candidateDescriptor().visibility + candidateDescriptor().visibility } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/smartcasts/smartCastUtil.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/smartcasts/smartCastUtil.kt index d242581d66e..06cebce48f3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/smartcasts/smartCastUtil.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/smartcasts/smartCastUtil.kt @@ -20,8 +20,8 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.KotlinType fun getReceiverValueWithSmartCast( - receiverArgument: ReceiverValue?, - smartCastType: KotlinType? + receiverArgument: ReceiverValue?, + smartCastType: KotlinType? ) = smartCastType?.let(::SmartCastReceiverValue) ?: receiverArgument private class SmartCastReceiverValue(private val type: KotlinType) : ReceiverValue { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tasks/synthesizedInvokes.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tasks/synthesizedInvokes.kt index 671ca36fcba..b4936d115e2 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tasks/synthesizedInvokes.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tasks/synthesizedInvokes.kt @@ -43,17 +43,16 @@ fun createSynthesizedInvokes(functions: Collection): Collect val containerClassId = (invoke.containingDeclaration as ClassDescriptor).classId val synthesized = if (containerClassId != null && isBuiltinFunctionClass(containerClassId)) { createSynthesizedFunctionWithFirstParameterAsReceiver(invoke) - } - else { + } else { val invokeDeclaration = invoke.overriddenDescriptors.singleOrNull() - ?: error("No single overridden invoke for $invoke: ${invoke.overriddenDescriptors}") + ?: error("No single overridden invoke for $invoke: ${invoke.overriddenDescriptors}") val synthesizedSuperFun = createSynthesizedFunctionWithFirstParameterAsReceiver(invokeDeclaration) val fakeOverride = synthesizedSuperFun.copy( - invoke.containingDeclaration, - synthesizedSuperFun.modality, - synthesizedSuperFun.visibility, - CallableMemberDescriptor.Kind.FAKE_OVERRIDE, - /* copyOverrides = */ false + invoke.containingDeclaration, + synthesizedSuperFun.modality, + synthesizedSuperFun.visibility, + CallableMemberDescriptor.Kind.FAKE_OVERRIDE, + /* copyOverrides = */ false ) fakeOverride.setSingleOverridden(synthesizedSuperFun) fakeOverride @@ -69,9 +68,9 @@ private fun createSynthesizedFunctionWithFirstParameterAsReceiver(descriptor: Fu descriptor.original.newCopyBuilder().apply { setExtensionReceiverType(descriptor.original.valueParameters.first().type) setValueParameters( - descriptor.original.valueParameters - .drop(1) - .map { p -> p.copy(descriptor.original, Name.identifier("p${p.index + 1}"), p.index - 1) } + descriptor.original.valueParameters + .drop(1) + .map { p -> p.copy(descriptor.original, Name.identifier("p${p.index + 1}"), p.index - 1) } ) }.build()!! @@ -85,5 +84,5 @@ fun isSynthesizedInvoke(descriptor: DeclarationDescriptor): Boolean { } return real.kind == CallableMemberDescriptor.Kind.SYNTHESIZED && - real.containingDeclaration.getFunctionalClassKind() != null + real.containingDeclaration.getFunctionalClassKind() != null } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ErrorCandidateFactory.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ErrorCandidateFactory.kt index d8a219be215..0f6e87b2808 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ErrorCandidateFactory.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ErrorCandidateFactory.kt @@ -36,19 +36,19 @@ enum class WrongResolutionToClassifier(val message: (Name) -> String) { OBJECT_AS_FUNCTION({ "Function 'invoke()' is not found in object $it" }) } -sealed class ErrorCandidate(val descriptor: D) { +sealed class ErrorCandidate(val descriptor: D) { class Classifier( - classifierDescriptor: ClassifierDescriptor, - val kind: WrongResolutionToClassifier + classifierDescriptor: ClassifierDescriptor, + val kind: WrongResolutionToClassifier ) : ErrorCandidate(classifierDescriptor) { val errorMessage = kind.message(descriptor.name) } } fun collectErrorCandidatesForFunction( - scopeTower: ImplicitScopeTower, - name: Name, - explicitReceiver: DetailedReceiver? + scopeTower: ImplicitScopeTower, + name: Name, + explicitReceiver: DetailedReceiver? ): Collection> { val context = ErrorCandidateContext(scopeTower, name, explicitReceiver) context.asClassifierCall(asFunction = true) @@ -56,9 +56,9 @@ fun collectErrorCandidatesForFunction( } fun collectErrorCandidatesForVariable( - scopeTower: ImplicitScopeTower, - name: Name, - explicitReceiver: DetailedReceiver? + scopeTower: ImplicitScopeTower, + name: Name, + explicitReceiver: DetailedReceiver? ): Collection> { val context = ErrorCandidateContext(scopeTower, name, explicitReceiver) context.asClassifierCall(asFunction = false) @@ -66,54 +66,59 @@ fun collectErrorCandidatesForVariable( } private class ErrorCandidateContext( - val scopeTower: ImplicitScopeTower, - val name: Name, - val explicitReceiver: DetailedReceiver? + val scopeTower: ImplicitScopeTower, + val name: Name, + val explicitReceiver: DetailedReceiver? ) { val result = SmartList>() - fun add(errorCandidate: ErrorCandidate<*>) { result.add(errorCandidate) } + fun add(errorCandidate: ErrorCandidate<*>) { + result.add(errorCandidate) + } } private fun ErrorCandidateContext.asClassifierCall(asFunction: Boolean) { val classifier = - when (explicitReceiver) { - is ReceiverValueWithSmartCastInfo -> { - explicitReceiver.receiverValue.type.memberScope.getContributedClassifier(name, scopeTower.location) - } - is QualifierReceiver -> { - explicitReceiver.staticScope.getContributedClassifier(name, scopeTower.location) - } - else -> scopeTower.lexicalScope.findClassifier(name, scopeTower.location) - } ?: return + when (explicitReceiver) { + is ReceiverValueWithSmartCastInfo -> { + explicitReceiver.receiverValue.type.memberScope.getContributedClassifier(name, scopeTower.location) + } + is QualifierReceiver -> { + explicitReceiver.staticScope.getContributedClassifier(name, scopeTower.location) + } + else -> scopeTower.lexicalScope.findClassifier(name, scopeTower.location) + } ?: return val kind = getWrongResolutionToClassifier(classifier, asFunction) ?: return add(ErrorCandidate.Classifier(classifier, kind)) } -private fun ErrorCandidateContext.getWrongResolutionToClassifier(classifier: ClassifierDescriptor, asFunction: Boolean): WrongResolutionToClassifier? = - when (classifier) { - is TypeAliasDescriptor -> classifier.classDescriptor?.let { getWrongResolutionToClassifier(it, asFunction) } +private fun ErrorCandidateContext.getWrongResolutionToClassifier( + classifier: ClassifierDescriptor, + asFunction: Boolean +): WrongResolutionToClassifier? = + when (classifier) { + is TypeAliasDescriptor -> classifier.classDescriptor?.let { getWrongResolutionToClassifier(it, asFunction) } - is TypeParameterDescriptor -> if (asFunction) TYPE_PARAMETER_AS_FUNCTION else TYPE_PARAMETER_AS_VALUE + is TypeParameterDescriptor -> if (asFunction) TYPE_PARAMETER_AS_FUNCTION else TYPE_PARAMETER_AS_VALUE - is ClassDescriptor -> { - when (classifier.kind) { - ClassKind.INTERFACE -> if (asFunction) INTERFACE_AS_FUNCTION else INTERFACE_AS_VALUE + is ClassDescriptor -> { + when (classifier.kind) { + ClassKind.INTERFACE -> if (asFunction) INTERFACE_AS_FUNCTION else INTERFACE_AS_VALUE - ClassKind.OBJECT -> if (asFunction) OBJECT_AS_FUNCTION else null - - ClassKind.CLASS -> when { - asFunction && explicitReceiver is QualifierReceiver? && classifier.isInner -> INNER_CLASS_CONSTRUCTOR_NO_RECEIVER - asFunction && classifier.isExpect -> EXPECT_CLASS_AS_FUNCTION - !asFunction -> CLASS_AS_VALUE - else -> null - } + ClassKind.OBJECT -> if (asFunction) OBJECT_AS_FUNCTION else null + ClassKind.CLASS -> when { + asFunction && explicitReceiver is QualifierReceiver? && classifier.isInner -> INNER_CLASS_CONSTRUCTOR_NO_RECEIVER + asFunction && classifier.isExpect -> EXPECT_CLASS_AS_FUNCTION + !asFunction -> CLASS_AS_VALUE else -> null } - } - else -> null + else -> null + } } + + else -> null + } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt index ed15100ebc6..73f91f870cf 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ImplicitScopeTower.kt @@ -64,8 +64,9 @@ interface CandidateWithBoundDispatchReceiver { val dispatchReceiver: ReceiverValueWithSmartCastInfo? } -fun getResultApplicability(diagnostics: Collection) = diagnostics.maxBy { it.candidateApplicability }?.candidateApplicability - ?: RESOLVED +fun getResultApplicability(diagnostics: Collection) = + diagnostics.maxBy { it.candidateApplicability }?.candidateApplicability + ?: RESOLVED enum class ResolutionCandidateApplicability { RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate @@ -80,30 +81,31 @@ enum class ResolutionCandidateApplicability { HIDDEN, // removed from resolve } -abstract class ResolutionDiagnostic(candidateApplicability: ResolutionCandidateApplicability): KotlinCallDiagnostic(candidateApplicability) { +abstract class ResolutionDiagnostic(candidateApplicability: ResolutionCandidateApplicability) : + KotlinCallDiagnostic(candidateApplicability) { override fun report(reporter: DiagnosticReporter) { // do nothing } } // todo error for this access from nested class -class VisibilityError(val invisibleMember: DeclarationDescriptorWithVisibility): ResolutionDiagnostic(RUNTIME_ERROR) { +class VisibilityError(val invisibleMember: DeclarationDescriptorWithVisibility) : ResolutionDiagnostic(RUNTIME_ERROR) { override fun report(reporter: DiagnosticReporter) { reporter.onCall(this) } } -class NestedClassViaInstanceReference(val classDescriptor: ClassDescriptor): ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE) -class InnerClassViaStaticReference(val classDescriptor: ClassDescriptor): ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE) -class UnsupportedInnerClassCall(val message: String): ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE) -class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType): ResolutionDiagnostic(RESOLVED) +class NestedClassViaInstanceReference(val classDescriptor: ClassDescriptor) : ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE) +class InnerClassViaStaticReference(val classDescriptor: ClassDescriptor) : ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE) +class UnsupportedInnerClassCall(val message: String) : ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE) +class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType) : ResolutionDiagnostic(RESOLVED) object ErrorDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED) // todo discuss and change to INAPPLICABLE object LowPriorityDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY) -object DynamicDescriptorDiagnostic: ResolutionDiagnostic(RESOLVED_LOW_PRIORITY) -object UnstableSmartCastDiagnostic: ResolutionDiagnostic(MAY_THROW_RUNTIME_ERROR) -object HiddenExtensionRelatedToDynamicTypes: ResolutionDiagnostic(HIDDEN) -object HiddenDescriptor: ResolutionDiagnostic(HIDDEN) +object DynamicDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY) +object UnstableSmartCastDiagnostic : ResolutionDiagnostic(MAY_THROW_RUNTIME_ERROR) +object HiddenExtensionRelatedToDynamicTypes : ResolutionDiagnostic(HIDDEN) +object HiddenDescriptor : ResolutionDiagnostic(HIDDEN) object InvokeConventionCallNoOperatorModifier : ResolutionDiagnostic(CONVENTION_ERROR) object InfixCallNoInfixModifier : ResolutionDiagnostic(CONVENTION_ERROR) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt index 15211751e74..86e311ca9f2 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/InvokeProcessors.kt @@ -26,8 +26,8 @@ import org.jetbrains.kotlin.util.OperatorNameConventions import java.util.* abstract class AbstractInvokeTowerProcessor( - protected val factoryProviderForInvoke: CandidateFactoryProviderForInvoke, - protected val variableProcessor: ScopeTowerProcessor + protected val factoryProviderForInvoke: CandidateFactoryProviderForInvoke, + protected val variableProcessor: ScopeTowerProcessor ) : ScopeTowerProcessor { // todo optimize it private val previousData = ArrayList() @@ -36,14 +36,13 @@ abstract class AbstractInvokeTowerProcessor( protected fun hasInvokeProcessors() = invokeProcessors.isNotEmpty() private inner class VariableInvokeProcessor( - var variableCandidate: C, - val invokeProcessor: ScopeTowerProcessor - ): ScopeTowerProcessor { + var variableCandidate: C, + val invokeProcessor: ScopeTowerProcessor + ) : ScopeTowerProcessor { - override fun process(data: TowerData) - = invokeProcessor.process(data).map { candidateGroup -> - candidateGroup.map { factoryProviderForInvoke.transformCandidate(variableCandidate, it) } - } + override fun process(data: TowerData) = invokeProcessor.process(data).map { candidateGroup -> + candidateGroup.map { factoryProviderForInvoke.transformCandidate(variableCandidate, it) } + } override fun recordLookups(skippedData: Collection, name: Name) { invokeProcessor.recordLookups(skippedData, name) @@ -51,7 +50,7 @@ abstract class AbstractInvokeTowerProcessor( } private fun createVariableInvokeProcessor(variableCandidate: C): VariableInvokeProcessor? = - createInvokeProcessor(variableCandidate)?.let { VariableInvokeProcessor(variableCandidate, it) } + createInvokeProcessor(variableCandidate)?.let { VariableInvokeProcessor(variableCandidate, it) } protected abstract fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor? @@ -98,24 +97,33 @@ abstract class AbstractInvokeTowerProcessor( // todo KT-9522 Allow invoke convention for synthetic property class InvokeTowerProcessor( - val scopeTower: ImplicitScopeTower, - val name: Name, - factoryProviderForInvoke: CandidateFactoryProviderForInvoke, - explicitReceiver: DetailedReceiver? + val scopeTower: ImplicitScopeTower, + val name: Name, + factoryProviderForInvoke: CandidateFactoryProviderForInvoke, + explicitReceiver: DetailedReceiver? ) : AbstractInvokeTowerProcessor( - factoryProviderForInvoke, - createVariableAndObjectProcessor(scopeTower, name, factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = false), explicitReceiver) + factoryProviderForInvoke, + createVariableAndObjectProcessor( + scopeTower, + name, + factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = false), + explicitReceiver + ) ) { // todo filter by operator override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor? { val (variableReceiver, invokeContext) = factoryProviderForInvoke.factoryForInvoke(variableCandidate, useExplicitReceiver = false) - ?: return null - return ExplicitReceiverScopeTowerProcessor(scopeTower, invokeContext, variableReceiver) { getFunctions(OperatorNameConventions.INVOKE, it) } + ?: return null + return ExplicitReceiverScopeTowerProcessor( + scopeTower, + invokeContext, + variableReceiver + ) { getFunctions(OperatorNameConventions.INVOKE, it) } } override fun mayDataBeApplicable(data: TowerData) = - data == TowerData.Empty || data is TowerData.TowerLevel + data == TowerData.Empty || data is TowerData.TowerLevel override fun recordLookups(skippedData: Collection, name: Name) { variableProcessor.recordLookups(skippedData, name) @@ -130,20 +138,25 @@ class InvokeTowerProcessor( } class InvokeExtensionTowerProcessor( - val scopeTower: ImplicitScopeTower, - val name: Name, - factoryProviderForInvoke: CandidateFactoryProviderForInvoke, - private val explicitReceiver: ReceiverValueWithSmartCastInfo? + val scopeTower: ImplicitScopeTower, + val name: Name, + factoryProviderForInvoke: CandidateFactoryProviderForInvoke, + private val explicitReceiver: ReceiverValueWithSmartCastInfo? ) : AbstractInvokeTowerProcessor( - factoryProviderForInvoke, - createVariableAndObjectProcessor(scopeTower, name, factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = true), explicitReceiver = null) + factoryProviderForInvoke, + createVariableAndObjectProcessor( + scopeTower, + name, + factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = true), + explicitReceiver = null + ) ) { override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor? { val (variableReceiver, invokeContext) = factoryProviderForInvoke.factoryForInvoke(variableCandidate, useExplicitReceiver = true) - ?: return null + ?: return null val invokeDescriptor = scopeTower.getExtensionInvokeCandidateDescriptor(variableReceiver) - ?: return null + ?: return null return InvokeExtensionScopeTowerProcessor(invokeContext, invokeDescriptor, explicitReceiver) } @@ -155,18 +168,30 @@ class InvokeExtensionTowerProcessor( } private class InvokeExtensionScopeTowerProcessor( - context: CandidateFactory, - private val invokeCandidateDescriptor: CandidateWithBoundDispatchReceiver, - private val explicitReceiver: ReceiverValueWithSmartCastInfo? + context: CandidateFactory, + private val invokeCandidateDescriptor: CandidateWithBoundDispatchReceiver, + private val explicitReceiver: ReceiverValueWithSmartCastInfo? ) : AbstractSimpleScopeTowerProcessor(context) { override fun simpleProcess(data: TowerData): Collection { if (explicitReceiver != null && data == TowerData.Empty) { - return listOf(candidateFactory.createCandidate(invokeCandidateDescriptor, ExplicitReceiverKind.BOTH_RECEIVERS, explicitReceiver)) + return listOf( + candidateFactory.createCandidate( + invokeCandidateDescriptor, + ExplicitReceiverKind.BOTH_RECEIVERS, + explicitReceiver + ) + ) } if (explicitReceiver == null && data is TowerData.OnlyImplicitReceiver) { - return listOf(candidateFactory.createCandidate(invokeCandidateDescriptor, ExplicitReceiverKind.DISPATCH_RECEIVER, data.implicitReceiver)) + return listOf( + candidateFactory.createCandidate( + invokeCandidateDescriptor, + ExplicitReceiverKind.DISPATCH_RECEIVER, + data.implicitReceiver + ) + ) } return emptyList() @@ -178,7 +203,7 @@ private class InvokeExtensionScopeTowerProcessor( // todo debug info private fun ImplicitScopeTower.getExtensionInvokeCandidateDescriptor( - extensionFunctionReceiver: ReceiverValueWithSmartCastInfo + extensionFunctionReceiver: ReceiverValueWithSmartCastInfo ): CandidateWithBoundDispatchReceiver? { val type = extensionFunctionReceiver.receiverValue.type if (!type.isBuiltinExtensionFunctionalType) return null // todo: missing smart cast? @@ -186,7 +211,7 @@ private fun ImplicitScopeTower.getExtensionInvokeCandidateDescriptor( val invokeDescriptor = type.memberScope.getContributedFunctions(OperatorNameConventions.INVOKE, location).single() val synthesizedInvokes = createSynthesizedInvokes(listOf(invokeDescriptor)) val synthesizedInvoke = synthesizedInvokes.singleOrNull() - ?: error("No single synthesized invoke for $invokeDescriptor: $synthesizedInvokes") + ?: error("No single synthesized invoke for $invokeDescriptor: $synthesizedInvokes") // here we don't add SynthesizedDescriptor diagnostic because it should has priority as member return CandidateWithBoundDispatchReceiverImpl(extensionFunctionReceiver, synthesizedInvoke, listOf()) @@ -194,31 +219,32 @@ private fun ImplicitScopeTower.getExtensionInvokeCandidateDescriptor( // case 1.(foo())() or (foo())() fun createCallTowerProcessorForExplicitInvoke( - scopeTower: ImplicitScopeTower, - functionContext: CandidateFactory, - expressionForInvoke: ReceiverValueWithSmartCastInfo, - explicitReceiver: ReceiverValueWithSmartCastInfo? + scopeTower: ImplicitScopeTower, + functionContext: CandidateFactory, + expressionForInvoke: ReceiverValueWithSmartCastInfo, + explicitReceiver: ReceiverValueWithSmartCastInfo? ): ScopeTowerProcessor { val invokeExtensionDescriptor = scopeTower.getExtensionInvokeCandidateDescriptor(expressionForInvoke) if (explicitReceiver != null) { return if (invokeExtensionDescriptor == null) { // case 1.(foo())(), where foo() isn't extension function KnownResultProcessor(emptyList()) - } - else { + } else { InvokeExtensionScopeTowerProcessor(functionContext, invokeExtensionDescriptor, explicitReceiver = explicitReceiver) } - } - else { - val usualInvoke = ExplicitReceiverScopeTowerProcessor(scopeTower, functionContext, expressionForInvoke) { getFunctions(OperatorNameConventions.INVOKE, it) } // todo operator + } else { + val usualInvoke = ExplicitReceiverScopeTowerProcessor( + scopeTower, + functionContext, + expressionForInvoke + ) { getFunctions(OperatorNameConventions.INVOKE, it) } // todo operator return if (invokeExtensionDescriptor == null) { usualInvoke - } - else { + } else { PrioritizedCompositeScopeTowerProcessor( - usualInvoke, - InvokeExtensionScopeTowerProcessor(functionContext, invokeExtensionDescriptor, explicitReceiver = null) + usualInvoke, + InvokeExtensionScopeTowerProcessor(functionContext, invokeExtensionDescriptor, explicitReceiver = null) ) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt index e20cc7c0c37..817bd8e664f 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/ScopeTowerProcessors.kt @@ -24,17 +24,16 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastI class KnownResultProcessor( - val result: Collection -): ScopeTowerProcessor { - override fun process(data: TowerData) - = if (data == TowerData.Empty) listOfNotNull(result.takeIf { it.isNotEmpty() }) else emptyList() + val result: Collection +) : ScopeTowerProcessor { + override fun process(data: TowerData) = if (data == TowerData.Empty) listOfNotNull(result.takeIf { it.isNotEmpty() }) else emptyList() override fun recordLookups(skippedData: Collection, name: Name) {} } // use this if processors priority is important class PrioritizedCompositeScopeTowerProcessor( - vararg val processors: ScopeTowerProcessor + vararg val processors: ScopeTowerProcessor ) : ScopeTowerProcessor { override fun process(data: TowerData): List> = processors.flatMap { it.process(data) } @@ -46,8 +45,8 @@ class PrioritizedCompositeScopeTowerProcessor( // use this if all processors has same priority class SamePriorityCompositeScopeTowerProcessor( - private vararg val processors: SimpleScopeTowerProcessor -): SimpleScopeTowerProcessor { + private vararg val processors: SimpleScopeTowerProcessor +) : SimpleScopeTowerProcessor { override fun simpleProcess(data: TowerData): Collection = processors.flatMap { it.simpleProcess(data) } override fun recordLookups(skippedData: Collection, name: Name) { processors.forEach { it.recordLookups(skippedData, name) } @@ -55,19 +54,19 @@ class SamePriorityCompositeScopeTowerProcessor( } -internal abstract class AbstractSimpleScopeTowerProcessor( - val candidateFactory: CandidateFactory +internal abstract class AbstractSimpleScopeTowerProcessor( + val candidateFactory: CandidateFactory ) : SimpleScopeTowerProcessor private typealias CandidatesCollector = - ScopeTowerLevel.(extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection + ScopeTowerLevel.(extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection -internal class ExplicitReceiverScopeTowerProcessor( - val scopeTower: ImplicitScopeTower, - context: CandidateFactory, - val explicitReceiver: ReceiverValueWithSmartCastInfo, - val collectCandidates: CandidatesCollector -): AbstractSimpleScopeTowerProcessor(context) { +internal class ExplicitReceiverScopeTowerProcessor( + val scopeTower: ImplicitScopeTower, + context: CandidateFactory, + val explicitReceiver: ReceiverValueWithSmartCastInfo, + val collectCandidates: CandidatesCollector +) : AbstractSimpleScopeTowerProcessor(context) { override fun simpleProcess(data: TowerData): Collection { return when (data) { TowerData.Empty -> resolveAsMember() @@ -80,7 +79,13 @@ internal class ExplicitReceiverScopeTowerProcessor( val members = mutableListOf() for (memberCandidate in MemberScopeTowerLevel(scopeTower, explicitReceiver).collectCandidates(null)) { if (!memberCandidate.requiresExtensionReceiver) { - members.add(candidateFactory.createCandidate(memberCandidate, ExplicitReceiverKind.DISPATCH_RECEIVER, extensionReceiver = null)) + members.add( + candidateFactory.createCandidate( + memberCandidate, + ExplicitReceiverKind.DISPATCH_RECEIVER, + extensionReceiver = null + ) + ) } } return members @@ -90,7 +95,13 @@ internal class ExplicitReceiverScopeTowerProcessor( val extensions = mutableListOf() for (extensionCandidate in level.collectCandidates(explicitReceiver)) { if (extensionCandidate.requiresExtensionReceiver) { - extensions.add(candidateFactory.createCandidate(extensionCandidate, ExplicitReceiverKind.EXTENSION_RECEIVER, extensionReceiver = explicitReceiver)) + extensions.add( + candidateFactory.createCandidate( + extensionCandidate, + ExplicitReceiverKind.EXTENSION_RECEIVER, + extensionReceiver = explicitReceiver + ) + ) } } return extensions @@ -105,19 +116,25 @@ internal class ExplicitReceiverScopeTowerProcessor( } } -private class QualifierScopeTowerProcessor( - val scopeTower: ImplicitScopeTower, - context: CandidateFactory, - val qualifier: QualifierReceiver, - val collectCandidates: CandidatesCollector -): AbstractSimpleScopeTowerProcessor(context) { +private class QualifierScopeTowerProcessor( + val scopeTower: ImplicitScopeTower, + context: CandidateFactory, + val qualifier: QualifierReceiver, + val collectCandidates: CandidatesCollector +) : AbstractSimpleScopeTowerProcessor(context) { override fun simpleProcess(data: TowerData): Collection { if (data != TowerData.Empty) return emptyList() val staticMembers = mutableListOf() for (towerCandidate in QualifierScopeTowerLevel(scopeTower, qualifier).collectCandidates(null)) { if (!towerCandidate.requiresExtensionReceiver) { - staticMembers.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null)) + staticMembers.add( + candidateFactory.createCandidate( + towerCandidate, + ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, + extensionReceiver = null + ) + ) } } return staticMembers @@ -127,32 +144,43 @@ private class QualifierScopeTowerProcessor( override fun recordLookups(skippedData: Collection, name: Name) {} } -private class NoExplicitReceiverScopeTowerProcessor( - context: CandidateFactory, - val collectCandidates: CandidatesCollector +private class NoExplicitReceiverScopeTowerProcessor( + context: CandidateFactory, + val collectCandidates: CandidatesCollector ) : AbstractSimpleScopeTowerProcessor(context) { - override fun simpleProcess(data: TowerData): Collection - = when(data) { - is TowerData.TowerLevel -> { - val result = mutableListOf() - for (towerCandidate in data.level.collectCandidates(null)) { - if (!towerCandidate.requiresExtensionReceiver) { - result.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null)) - } - } - result + override fun simpleProcess(data: TowerData): Collection = when (data) { + is TowerData.TowerLevel -> { + val result = mutableListOf() + for (towerCandidate in data.level.collectCandidates(null)) { + if (!towerCandidate.requiresExtensionReceiver) { + result.add( + candidateFactory.createCandidate( + towerCandidate, + ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, + extensionReceiver = null + ) + ) } - is TowerData.BothTowerLevelAndImplicitReceiver -> { - val result = mutableListOf() - for (towerCandidate in data.level.collectCandidates(data.implicitReceiver)) { - if (towerCandidate.requiresExtensionReceiver) { - result.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = data.implicitReceiver)) - } - } - result - } - else -> emptyList() } + result + } + is TowerData.BothTowerLevelAndImplicitReceiver -> { + val result = mutableListOf() + for (towerCandidate in data.level.collectCandidates(data.implicitReceiver)) { + if (towerCandidate.requiresExtensionReceiver) { + result.add( + candidateFactory.createCandidate( + towerCandidate, + ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, + extensionReceiver = data.implicitReceiver + ) + ) + } + } + result + } + else -> emptyList() + } override fun recordLookups(skippedData: Collection, name: Name) { for (data in skippedData) { @@ -166,73 +194,77 @@ private class NoExplicitReceiverScopeTowerProcessor( } private fun createSimpleProcessorWithoutClassValueReceiver( - scopeTower: ImplicitScopeTower, - context: CandidateFactory, - explicitReceiver: DetailedReceiver?, - collectCandidates: CandidatesCollector + scopeTower: ImplicitScopeTower, + context: CandidateFactory, + explicitReceiver: DetailedReceiver?, + collectCandidates: CandidatesCollector ): SimpleScopeTowerProcessor = - when (explicitReceiver) { - is ReceiverValueWithSmartCastInfo -> ExplicitReceiverScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) - is QualifierReceiver -> QualifierScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) - else -> { - assert(explicitReceiver == null) { - "Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!::class.java.simpleName})" - } - NoExplicitReceiverScopeTowerProcessor(context, collectCandidates) + when (explicitReceiver) { + is ReceiverValueWithSmartCastInfo -> ExplicitReceiverScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) + is QualifierReceiver -> QualifierScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) + else -> { + assert(explicitReceiver == null) { + "Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!::class.java.simpleName})" } + NoExplicitReceiverScopeTowerProcessor(context, collectCandidates) } + } private fun createSimpleProcessor( - scopeTower: ImplicitScopeTower, - context: CandidateFactory, - explicitReceiver: DetailedReceiver?, - classValueReceiver: Boolean, - collectCandidates: CandidatesCollector -) : ScopeTowerProcessor { - val withoutClassValueProcessor = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver, collectCandidates) + scopeTower: ImplicitScopeTower, + context: CandidateFactory, + explicitReceiver: DetailedReceiver?, + classValueReceiver: Boolean, + collectCandidates: CandidatesCollector +): ScopeTowerProcessor { + val withoutClassValueProcessor = + createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver, collectCandidates) if (classValueReceiver && explicitReceiver is QualifierReceiver) { val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return withoutClassValueProcessor return PrioritizedCompositeScopeTowerProcessor( - withoutClassValueProcessor, - ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates) + withoutClassValueProcessor, + ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates) ) } return withoutClassValueProcessor } fun createCallableReferenceProcessor( - scopeTower: ImplicitScopeTower, - name: Name, context: CandidateFactory, - explicitReceiver: DetailedReceiver? + scopeTower: ImplicitScopeTower, + name: Name, context: CandidateFactory, + explicitReceiver: DetailedReceiver? ): SimpleScopeTowerProcessor { val variable = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver) { getVariables(name, it) } val function = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver) { getFunctions(name, it) } return SamePriorityCompositeScopeTowerProcessor(variable, function) } -fun createVariableProcessor(scopeTower: ImplicitScopeTower, name: Name, - context: CandidateFactory, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true +fun createVariableProcessor( + scopeTower: ImplicitScopeTower, name: Name, + context: CandidateFactory, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true ) = createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getVariables(name, it) } -fun createVariableAndObjectProcessor(scopeTower: ImplicitScopeTower, name: Name, - context: CandidateFactory, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true +fun createVariableAndObjectProcessor( + scopeTower: ImplicitScopeTower, name: Name, + context: CandidateFactory, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true ) = PrioritizedCompositeScopeTowerProcessor( - createVariableProcessor(scopeTower, name, context, explicitReceiver), - createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getObjects(name, it) } + createVariableProcessor(scopeTower, name, context, explicitReceiver), + createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getObjects(name, it) } ) -fun createSimpleFunctionProcessor(scopeTower: ImplicitScopeTower, name: Name, - context: CandidateFactory, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true +fun createSimpleFunctionProcessor( + scopeTower: ImplicitScopeTower, name: Name, + context: CandidateFactory, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true ) = createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getFunctions(name, it) } -fun <С: Candidate> createFunctionProcessor( - scopeTower: ImplicitScopeTower, - name: Name, - simpleContext: CandidateFactory<С>, - factoryProviderForInvoke: CandidateFactoryProviderForInvoke<С>, - explicitReceiver: DetailedReceiver? +fun <С : Candidate> createFunctionProcessor( + scopeTower: ImplicitScopeTower, + name: Name, + simpleContext: CandidateFactory<С>, + factoryProviderForInvoke: CandidateFactoryProviderForInvoke<С>, + explicitReceiver: DetailedReceiver? ): PrioritizedCompositeScopeTowerProcessor<С> { // a.foo() -- simple function call @@ -250,15 +282,14 @@ fun <С: Candidate> createFunctionProcessor( } -fun createProcessorWithReceiverValueOrEmpty( - explicitReceiver: DetailedReceiver?, - create: (ReceiverValueWithSmartCastInfo?) -> ScopeTowerProcessor +fun createProcessorWithReceiverValueOrEmpty( + explicitReceiver: DetailedReceiver?, + create: (ReceiverValueWithSmartCastInfo?) -> ScopeTowerProcessor ): ScopeTowerProcessor { return if (explicitReceiver is QualifierReceiver) { explicitReceiver.classValueReceiverWithSmartCastInfo?.let(create) - ?: KnownResultProcessor(listOf()) - } - else { + ?: KnownResultProcessor(listOf()) + } else { create(explicitReceiver as ReceiverValueWithSmartCastInfo?) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt index 12444d28bc7..7638912c155 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt @@ -42,23 +42,22 @@ import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* internal abstract class AbstractScopeTowerLevel( - protected val scopeTower: ImplicitScopeTower -): ScopeTowerLevel { + protected val scopeTower: ImplicitScopeTower +) : ScopeTowerLevel { protected val location: LookupLocation get() = scopeTower.location protected fun createCandidateDescriptor( - descriptor: CallableDescriptor, - dispatchReceiver: ReceiverValueWithSmartCastInfo?, - specialError: ResolutionDiagnostic? = null, - dispatchReceiverSmartCastType: KotlinType? = null + descriptor: CallableDescriptor, + dispatchReceiver: ReceiverValueWithSmartCastInfo?, + specialError: ResolutionDiagnostic? = null, + dispatchReceiverSmartCastType: KotlinType? = null ): CandidateWithBoundDispatchReceiver { val diagnostics = SmartList() diagnostics.addIfNotNull(specialError) if (ErrorUtils.isError(descriptor)) { diagnostics.add(ErrorDescriptorDiagnostic) - } - else { + } else { if (descriptor.hasLowPriorityInOverloadResolution() || descriptor.isLowPriorityFromStdlibJre7Or8()) { diagnostics.add(LowPriorityDescriptorDiagnostic) } @@ -67,9 +66,9 @@ internal abstract class AbstractScopeTowerLevel( val shouldSkipVisibilityCheck = scopeTower.isDebuggerContext || scopeTower.isNewInferenceEnabled if (!shouldSkipVisibilityCheck) { Visibilities.findInvisibleMember( - getReceiverValueWithSmartCast(dispatchReceiver?.receiverValue, dispatchReceiverSmartCastType), - descriptor, - scopeTower.lexicalScope.ownerDescriptor + getReceiverValueWithSmartCast(dispatchReceiver?.receiverValue, dispatchReceiverSmartCastType), + descriptor, + scopeTower.lexicalScope.ownerDescriptor )?.let { diagnostics.add(VisibilityError(it)) } } } @@ -81,15 +80,15 @@ internal abstract class AbstractScopeTowerLevel( // todo KT-9538 Unresolved inner class via subclass reference // todo add static methods & fields with error internal class MemberScopeTowerLevel( - scopeTower: ImplicitScopeTower, - val dispatchReceiver: ReceiverValueWithSmartCastInfo -): AbstractScopeTowerLevel(scopeTower) { + scopeTower: ImplicitScopeTower, + val dispatchReceiver: ReceiverValueWithSmartCastInfo +) : AbstractScopeTowerLevel(scopeTower) { private val syntheticScopes = scopeTower.syntheticScopes private val isNewInferenceEnabled = scopeTower.isNewInferenceEnabled private fun collectMembers( - getMembers: ResolutionScope.(KotlinType?) -> Collection + getMembers: ResolutionScope.(KotlinType?) -> Collection ): Collection { val result = ArrayList(0) val receiverValue = dispatchReceiver.receiverValue @@ -103,9 +102,9 @@ internal class MemberScopeTowerLevel( for (possibleType in dispatchReceiver.possibleTypes) { possibleType.memberScope.getMembers(possibleType).mapTo(unstableCandidates ?: result) { createCandidateDescriptor( - it, - dispatchReceiver.smartCastReceiver(possibleType), - unstableError, dispatchReceiverSmartCastType = possibleType + it, + dispatchReceiver.smartCastReceiver(possibleType), + unstableError, dispatchReceiverSmartCastType = possibleType ) } } @@ -113,8 +112,7 @@ internal class MemberScopeTowerLevel( if (dispatchReceiver.possibleTypes.isNotEmpty()) { if (unstableCandidates == null) { result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() }) - } - else { + } else { result.addAll(unstableCandidates.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() }) } } @@ -142,8 +140,14 @@ internal class MemberScopeTowerLevel( override fun get(key: KotlinType): TypeProjection? = null override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = when (position) { Variance.INVARIANT -> null - Variance.OUT_VARIANCE -> approximator.approximateToSuperType(topLevelType.unwrap(), TypeApproximatorConfiguration.CapturedTypesApproximation) - Variance.IN_VARIANCE -> approximator.approximateToSubType(topLevelType.unwrap(), TypeApproximatorConfiguration.CapturedTypesApproximation) + Variance.OUT_VARIANCE -> approximator.approximateToSuperType( + topLevelType.unwrap(), + TypeApproximatorConfiguration.CapturedTypesApproximation + ) + Variance.IN_VARIANCE -> approximator.approximateToSubType( + topLevelType.unwrap(), + TypeApproximatorConfiguration.CapturedTypesApproximation + ) } ?: topLevelType } return substitute(TypeSubstitutor.create(wrappedSubstitution)) @@ -156,18 +160,27 @@ internal class MemberScopeTowerLevel( return ReceiverValueWithSmartCastInfo(newReceiverValue, possibleTypes, isStable) } - override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection { + override fun getVariables( + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo? + ): Collection { return collectMembers { getContributedVariables(name, location) } } - override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection { + override fun getObjects( + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo? + ): Collection { return emptyList() } - override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection { + override fun getFunctions( + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo? + ): Collection { return collectMembers { getContributedFunctions(name, location) + it.getInnerConstructors(name, location) + - syntheticScopes.collectSyntheticMemberFunctions(listOfNotNull(it), name, location) + syntheticScopes.collectSyntheticMemberFunctions(listOfNotNull(it), name, location) } } @@ -179,71 +192,86 @@ internal class MemberScopeTowerLevel( } } -internal class QualifierScopeTowerLevel(scopeTower: ImplicitScopeTower, val qualifier: QualifierReceiver) : AbstractScopeTowerLevel(scopeTower) { +internal class QualifierScopeTowerLevel(scopeTower: ImplicitScopeTower, val qualifier: QualifierReceiver) : + AbstractScopeTowerLevel(scopeTower) { override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = qualifier.staticScope - .getContributedVariables(name, location).map { - createCandidateDescriptor(it, dispatchReceiver = null) - } + .getContributedVariables(name, location).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = qualifier.staticScope - .getContributedObjectVariables(name, location).map { - createCandidateDescriptor(it, dispatchReceiver = null) - } + .getContributedObjectVariables(name, location).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = qualifier.staticScope - .getContributedFunctionsAndConstructors(name, - location, - scopeTower.syntheticScopes, - qualifier.staticScope).map { - createCandidateDescriptor(it, dispatchReceiver = null) - } + .getContributedFunctionsAndConstructors( + name, + location, + scopeTower.syntheticScopes, + qualifier.staticScope + ).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } override fun recordLookup(name: Name) {} } // KT-3335 Creating imported super class' inner class fails in codegen internal open class ScopeBasedTowerLevel protected constructor( - scopeTower: ImplicitScopeTower, - private val resolutionScope: ResolutionScope + scopeTower: ImplicitScopeTower, + private val resolutionScope: ResolutionScope ) : AbstractScopeTowerLevel(scopeTower) { internal constructor(scopeTower: ImplicitScopeTower, lexicalScope: LexicalScope) : this(scopeTower, lexicalScope as ResolutionScope) - override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection - = resolutionScope.getContributedVariables(name, location).map { - createCandidateDescriptor(it, dispatchReceiver = null) - } + override fun getVariables( + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo? + ): Collection = resolutionScope.getContributedVariables(name, location).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } - override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection - = resolutionScope.getContributedObjectVariables(name, location).map { - createCandidateDescriptor(it, dispatchReceiver = null) - } + override fun getObjects( + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo? + ): Collection = resolutionScope.getContributedObjectVariables(name, location).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } - override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection - = resolutionScope.getContributedFunctionsAndConstructors(name, - location, - scopeTower.syntheticScopes, - resolutionScope).map { - createCandidateDescriptor(it, dispatchReceiver = null) - } + override fun getFunctions( + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo? + ): Collection = resolutionScope.getContributedFunctionsAndConstructors( + name, + location, + scopeTower.syntheticScopes, + resolutionScope + ).map { + createCandidateDescriptor(it, dispatchReceiver = null) + } override fun recordLookup(name: Name) { resolutionScope.recordLookup(name, location) } } + internal class ImportingScopeBasedTowerLevel( - scopeTower: ImplicitScopeTower, - importingScope: ImportingScope -): ScopeBasedTowerLevel(scopeTower, importingScope) + scopeTower: ImplicitScopeTower, + importingScope: ImportingScope +) : ScopeBasedTowerLevel(scopeTower, importingScope) internal class SyntheticScopeBasedTowerLevel( - scopeTower: ImplicitScopeTower, - private val syntheticScopes: SyntheticScopes -): AbstractScopeTowerLevel(scopeTower) { + scopeTower: ImplicitScopeTower, + private val syntheticScopes: SyntheticScopes +) : AbstractScopeTowerLevel(scopeTower) { private val ReceiverValueWithSmartCastInfo.allTypes: Set get() = possibleTypes + receiverValue.type - override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection { + override fun getVariables( + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo? + ): Collection { if (extensionReceiver == null) return emptyList() return syntheticScopes.collectSyntheticExtensionProperties(extensionReceiver.allTypes, name, location).map { @@ -252,43 +280,43 @@ internal class SyntheticScopeBasedTowerLevel( } override fun getObjects( - name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo? + name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo? ): Collection = - emptyList() + emptyList() override fun getFunctions( - name: Name, - extensionReceiver: ReceiverValueWithSmartCastInfo? + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo? ): Collection = - emptyList() + emptyList() override fun recordLookup(name: Name) { } } -internal class HidesMembersTowerLevel(scopeTower: ImplicitScopeTower): AbstractScopeTowerLevel(scopeTower) { - override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) - = getCandidates(name, extensionReceiver, LexicalScope::collectVariables) +internal class HidesMembersTowerLevel(scopeTower: ImplicitScopeTower) : AbstractScopeTowerLevel(scopeTower) { + override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = + getCandidates(name, extensionReceiver, LexicalScope::collectVariables) - override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) - = emptyList() + override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = + emptyList() - override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) - = getCandidates(name, extensionReceiver, LexicalScope::collectFunctions) + override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = + getCandidates(name, extensionReceiver, LexicalScope::collectFunctions) private fun getCandidates( - name: Name, - extensionReceiver: ReceiverValueWithSmartCastInfo?, - collectCandidates: LexicalScope.(Name, LookupLocation) -> Collection + name: Name, + extensionReceiver: ReceiverValueWithSmartCastInfo?, + collectCandidates: LexicalScope.(Name, LookupLocation) -> Collection ): Collection { if (extensionReceiver == null || name !in HIDES_MEMBERS_NAME_LIST) return emptyList() return scopeTower.lexicalScope.collectCandidates(name, location).filter { it.extensionReceiverParameter != null && it.hasHidesMembersAnnotation() }.map { - createCandidateDescriptor(it, dispatchReceiver = null) - } + createCandidateDescriptor(it, dispatchReceiver = null) + } } override fun recordLookup(name: Name) {} @@ -309,10 +337,10 @@ private fun KotlinType?.getInnerConstructors(name: Name, location: LookupLocatio } private fun ResolutionScope.getContributedFunctionsAndConstructors( - name: Name, - location: LookupLocation, - syntheticScopes: SyntheticScopes, - scope: ResolutionScope + name: Name, + location: LookupLocation, + syntheticScopes: SyntheticScopes, + scope: ResolutionScope ): Collection { val result = ArrayList(getContributedFunctions(name, location)) @@ -338,27 +366,27 @@ private fun ResolutionScope.getContributedObjectVariables(name: Name, location: } fun getFakeDescriptorForObject(classifier: ClassifierDescriptor?): FakeCallableDescriptorForObject? = - when (classifier) { - is TypeAliasDescriptor -> - classifier.classDescriptor?.let { classDescriptor -> - if (classDescriptor.hasClassValueDescriptor) - FakeCallableDescriptorForTypeAliasObject(classifier) - else - null - } - is ClassDescriptor -> - if (classifier.hasClassValueDescriptor) - FakeCallableDescriptorForObject(classifier) + when (classifier) { + is TypeAliasDescriptor -> + classifier.classDescriptor?.let { classDescriptor -> + if (classDescriptor.hasClassValueDescriptor) + FakeCallableDescriptorForTypeAliasObject(classifier) else null - else -> null - } + } + is ClassDescriptor -> + if (classifier.hasClassValueDescriptor) + FakeCallableDescriptorForObject(classifier) + else + null + else -> null + } private fun getClassWithConstructors(classifier: ClassifierDescriptor?): ClassDescriptor? = - if (classifier !is ClassDescriptor || !classifier.canHaveCallableConstructors) - null - else - classifier + if (classifier !is ClassDescriptor || !classifier.canHaveCallableConstructors) + null + else + classifier private val ClassDescriptor.canHaveCallableConstructors: Boolean get() = !ErrorUtils.isError(this) && !kind.isSingleton diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt index e7db86f3494..6d759387e41 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerResolver.kt @@ -37,11 +37,11 @@ interface Candidate { val resultingApplicability: ResolutionCandidateApplicability } -interface CandidateFactory { +interface CandidateFactory { fun createCandidate( - towerCandidate: CandidateWithBoundDispatchReceiver, - explicitReceiverKind: ExplicitReceiverKind, - extensionReceiver: ReceiverValueWithSmartCastInfo? + towerCandidate: CandidateWithBoundDispatchReceiver, + explicitReceiverKind: ExplicitReceiverKind, + extensionReceiver: ReceiverValueWithSmartCastInfo? ): C } @@ -59,7 +59,7 @@ interface CandidateFactoryProviderForInvoke { sealed class TowerData { object Empty : TowerData() - class OnlyImplicitReceiver(val implicitReceiver: ReceiverValueWithSmartCastInfo): TowerData() + class OnlyImplicitReceiver(val implicitReceiver: ReceiverValueWithSmartCastInfo) : TowerData() class TowerLevel(val level: ScopeTowerLevel) : TowerData() class BothTowerLevelAndImplicitReceiver(val level: ScopeTowerLevel, val implicitReceiver: ReceiverValueWithSmartCastInfo) : TowerData() // Has the same meaning as BothTowerLevelAndImplicitReceiver, but it's only used for names lookup, so it doesn't need implicit receiver @@ -81,41 +81,40 @@ interface SimpleScopeTowerProcessor : ScopeTowerProcessor { } class TowerResolver { - fun runResolve( - scopeTower: ImplicitScopeTower, - processor: ScopeTowerProcessor, - useOrder: Boolean, - name: Name + fun runResolve( + scopeTower: ImplicitScopeTower, + processor: ScopeTowerProcessor, + useOrder: Boolean, + name: Name ): Collection = scopeTower.run(processor, SuccessfulResultCollector(), useOrder, name) - fun collectAllCandidates( - scopeTower: ImplicitScopeTower, - processor: ScopeTowerProcessor, - name: Name - ): Collection - = scopeTower.run(processor, AllCandidatesCollector(), false, name) + fun collectAllCandidates( + scopeTower: ImplicitScopeTower, + processor: ScopeTowerProcessor, + name: Name + ): Collection = scopeTower.run(processor, AllCandidatesCollector(), false, name) fun ImplicitScopeTower.run( - processor: ScopeTowerProcessor, - resultCollector: ResultCollector, - useOrder: Boolean, - name: Name + processor: ScopeTowerProcessor, + resultCollector: ResultCollector, + useOrder: Boolean, + name: Name ): Collection = Task(this, processor, resultCollector, useOrder, name).run() private inner class Task( - private val implicitScopeTower: ImplicitScopeTower, - private val processor: ScopeTowerProcessor, - private val resultCollector: ResultCollector, - private val useOrder: Boolean, - private val name: Name + private val implicitScopeTower: ImplicitScopeTower, + private val processor: ScopeTowerProcessor, + private val resultCollector: ResultCollector, + private val useOrder: Boolean, + private val name: Name ) { private val isNameForHidesMember = name in HIDES_MEMBERS_NAME_LIST private val skippedDataForLookup = mutableListOf() private val localLevels: Collection by lazy(LazyThreadSafetyMode.NONE) { - implicitScopeTower.lexicalScope.parentsWithSelf. - filterIsInstance().filter { it.kind.withLocalDescriptors && it.mayFitForName(name) }. - map { ScopeBasedTowerLevel(implicitScopeTower, it) }.toList() + implicitScopeTower.lexicalScope.parentsWithSelf.filterIsInstance() + .filter { it.kind.withLocalDescriptors && it.mayFitForName(name) }.map { ScopeBasedTowerLevel(implicitScopeTower, it) } + .toList() } private val nonLocalLevels: Collection by lazy(LazyThreadSafetyMode.NONE) { @@ -131,8 +130,7 @@ class TowerResolver { fun addLevel(scopeTowerLevel: ScopeTowerLevel, mayFitForName: Boolean) { if (mayFitForName) { mainResult.add(scopeTowerLevel) - } - else { + } else { skippedDataForLookup.add(TowerData.ForLookupForNoExplicitReceiver(scopeTowerLevel)) } } @@ -141,22 +139,21 @@ class TowerResolver { if (scope is LexicalScope) { if (!scope.kind.withLocalDescriptors) { addLevel( - ScopeBasedTowerLevel(this@createNonLocalLevels, scope), - scope.mayFitForName(name) + ScopeBasedTowerLevel(this@createNonLocalLevels, scope), + scope.mayFitForName(name) ) } getImplicitReceiver(scope)?.let { addLevel( - MemberScopeTowerLevel(this@createNonLocalLevels, it), - it.mayFitForName(name) + MemberScopeTowerLevel(this@createNonLocalLevels, it), + it.mayFitForName(name) ) } - } - else { + } else { addLevel( - ImportingScopeBasedTowerLevel(this@createNonLocalLevels, scope as ImportingScope), - scope.mayFitForName(name) + ImportingScopeBasedTowerLevel(this@createNonLocalLevels, scope as ImportingScope), + scope.mayFitForName(name) ) } } @@ -197,16 +194,15 @@ class TowerResolver { // statics if (!scope.kind.withLocalDescriptors) { TowerData.TowerLevel(ScopeBasedTowerLevel(implicitScopeTower, scope)) - .process(scope.mayFitForName(name))?.let { return it } + .process(scope.mayFitForName(name))?.let { return it } } implicitScopeTower.getImplicitReceiver(scope) - ?.let(this::processImplicitReceiver) - ?.let { return it } - } - else { + ?.let(this::processImplicitReceiver) + ?.let { return it } + } else { TowerData.TowerLevel(ImportingScopeBasedTowerLevel(implicitScopeTower, scope as ImportingScope)) - .process(scope.mayFitForName(name))?.let { return it } + .process(scope.mayFitForName(name))?.let { return it } } } @@ -223,7 +219,7 @@ class TowerResolver { // members of implicit receiver or member extension for explicit receiver TowerData.TowerLevel(MemberScopeTowerLevel(implicitScopeTower, implicitReceiver)) - .process(implicitReceiver.mayFitForName(name))?.let { return it } + .process(implicitReceiver.mayFitForName(name))?.let { return it } // synthetic properties TowerData.BothTowerLevelAndImplicitReceiver(syntheticLevel, implicitReceiver).process()?.let { return it } @@ -255,32 +251,31 @@ class TowerResolver { } private fun KotlinType.mayFitForName(name: Name) = - isDynamic() || - !memberScope.definitelyDoesNotContainName(name) || - !memberScope.definitelyDoesNotContainName(OperatorNameConventions.INVOKE) + isDynamic() || + !memberScope.definitelyDoesNotContainName(name) || + !memberScope.definitelyDoesNotContainName(OperatorNameConventions.INVOKE) private fun ResolutionScope.mayFitForName(name: Name) = - !definitelyDoesNotContainName(name) || !definitelyDoesNotContainName(OperatorNameConventions.INVOKE) + !definitelyDoesNotContainName(name) || !definitelyDoesNotContainName(OperatorNameConventions.INVOKE) } fun runWithEmptyTowerData( - processor: ScopeTowerProcessor, - resultCollector: ResultCollector, - useOrder: Boolean + processor: ScopeTowerProcessor, + resultCollector: ResultCollector, + useOrder: Boolean ): Collection = processTowerData(processor, resultCollector, useOrder, TowerData.Empty) ?: resultCollector.getFinalCandidates() private fun processTowerData( - processor: ScopeTowerProcessor, - resultCollector: ResultCollector, - useOrder: Boolean, - towerData: TowerData + processor: ScopeTowerProcessor, + resultCollector: ResultCollector, + useOrder: Boolean, + towerData: TowerData ): Collection? { ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() val candidatesGroups = if (useOrder) { processor.process(towerData) - } - else { + } else { listOf(processor.process(towerData).flatMap { it }) } @@ -301,7 +296,7 @@ class TowerResolver { abstract fun pushCandidates(candidates: Collection) } - class AllCandidatesCollector: ResultCollector() { + class AllCandidatesCollector : ResultCollector() { private val allCandidates = ArrayList() override fun getSuccessfulCandidates(): Collection? = null @@ -352,7 +347,8 @@ class TowerResolver { return moreSuitableGroup.filter { it.resultingApplicability == groupApplicability } } - private val Collection.groupApplicability get() = - minBy { it.resultingApplicability }?.resultingApplicability ?: ResolutionCandidateApplicability.HIDDEN + private val Collection.groupApplicability + get() = + minBy { it.resultingApplicability }?.resultingApplicability ?: ResolutionCandidateApplicability.HIDDEN } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerUtils.kt index f7b83e6f5b6..d9fd2e5c8ed 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerUtils.kt @@ -21,9 +21,10 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo private val INAPPLICABLE_STATUSES = setOf( - ResolutionCandidateApplicability.INAPPLICABLE, - ResolutionCandidateApplicability.INAPPLICABLE_ARGUMENTS_MAPPING_ERROR, - ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER) + ResolutionCandidateApplicability.INAPPLICABLE, + ResolutionCandidateApplicability.INAPPLICABLE_ARGUMENTS_MAPPING_ERROR, + ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER +) val ResolutionCandidateApplicability.isSuccess: Boolean get() = this <= ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY @@ -38,9 +39,9 @@ val ResolutionCandidateApplicability.isInapplicable: Boolean get() = this in INAPPLICABLE_STATUSES internal class CandidateWithBoundDispatchReceiverImpl( - override val dispatchReceiver: ReceiverValueWithSmartCastInfo?, - override val descriptor: CallableDescriptor, - override val diagnostics: List + override val dispatchReceiver: ReceiverValueWithSmartCastInfo?, + override val descriptor: CallableDescriptor, + override val diagnostics: List ) : CandidateWithBoundDispatchReceiver fun C.forceResolution(): C { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt index a3355645b97..2f79cc4a3c5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForObject.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.types.TypeSubstitutor import java.util.* open class FakeCallableDescriptorForObject( - val classDescriptor: ClassDescriptor + val classDescriptor: ClassDescriptor ) : DeclarationDescriptorWithVisibility by classDescriptor.getClassObjectReferenceTarget(), VariableDescriptor { init { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForTypeAliasObject.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForTypeAliasObject.kt index 4387613f6d5..b395f35ae2b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForTypeAliasObject.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForTypeAliasObject.kt @@ -20,16 +20,15 @@ import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.impl.DescriptorDerivedFromTypeAlias class FakeCallableDescriptorForTypeAliasObject(override val typeAliasDescriptor: TypeAliasDescriptor) : - FakeCallableDescriptorForObject(typeAliasDescriptor.classDescriptor!!), - DescriptorDerivedFromTypeAlias -{ + FakeCallableDescriptorForObject(typeAliasDescriptor.classDescriptor!!), + DescriptorDerivedFromTypeAlias { override fun getReferencedDescriptor() = - typeAliasDescriptor + typeAliasDescriptor override fun equals(other: Any?): Boolean = - other is FakeCallableDescriptorForTypeAliasObject && - typeAliasDescriptor == other.typeAliasDescriptor + other is FakeCallableDescriptorForTypeAliasObject && + typeAliasDescriptor == other.typeAliasDescriptor override fun hashCode(): Int = - typeAliasDescriptor.hashCode() + typeAliasDescriptor.hashCode() } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/functionTypeResolveUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/functionTypeResolveUtils.kt index 73daca8b278..bb4eedfe58a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/functionTypeResolveUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/functionTypeResolveUtils.kt @@ -28,16 +28,16 @@ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeProjection fun createValueParametersForInvokeInFunctionType( - functionDescriptor: FunctionDescriptor, parameterTypes: List + functionDescriptor: FunctionDescriptor, parameterTypes: List ): List { return parameterTypes.mapIndexed { i, typeProjection -> ValueParameterDescriptorImpl( - functionDescriptor, null, i, Annotations.EMPTY, - Name.identifier("p${i + 1}"), typeProjection.type, - /* declaresDefaultValue = */ false, - /* isCrossinline = */ false, - /* isNoinline = */ false, - null, SourceElement.NO_SOURCE + functionDescriptor, null, i, Annotations.EMPTY, + Name.identifier("p${i + 1}"), typeProjection.type, + /* declaresDefaultValue = */ false, + /* isCrossinline = */ false, + /* isNoinline = */ false, + null, SourceElement.NO_SOURCE ) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/isFromStdlibJre7Or8.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/isFromStdlibJre7Or8.kt index abada9fa740..8b5f919cb41 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/isFromStdlibJre7Or8.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/isFromStdlibJre7Or8.kt @@ -46,10 +46,10 @@ fun CallableDescriptor.isLowPriorityFromStdlibJre7Or8(): Boolean { if (!packageFqName.startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) return false val isFromStdlibJre7Or8 = - packageFqName == kotlin && name == use || - packageFqName == kotlinText && name == get || - packageFqName == kotlinCollections && (name == getOrDefault || name == remove) || - packageFqName == kotlinStreams + packageFqName == kotlin && name == use || + packageFqName == kotlinText && name == get || + packageFqName == kotlinCollections && (name == getOrDefault || name == remove) || + packageFqName == kotlinStreams if (!isFromStdlibJre7Or8) return false diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalChainedScope.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalChainedScope.kt index 27a668a8843..c0d3702406e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalChainedScope.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalChainedScope.kt @@ -26,31 +26,36 @@ import org.jetbrains.kotlin.util.collectionUtils.getFromAllScopes import org.jetbrains.kotlin.utils.Printer class LexicalChainedScope @JvmOverloads constructor( - parent: LexicalScope, - override val ownerDescriptor: DeclarationDescriptor, - override val isOwnerDescriptorAccessibleByLabel: Boolean, - override val implicitReceiver: ReceiverParameterDescriptor?, - override val kind: LexicalScopeKind, - private val memberScopes: List, - @Deprecated("This value is temporary hack for resolve -- don't use it!") - val isStaticScope: Boolean = false -): LexicalScope { + parent: LexicalScope, + override val ownerDescriptor: DeclarationDescriptor, + override val isOwnerDescriptorAccessibleByLabel: Boolean, + override val implicitReceiver: ReceiverParameterDescriptor?, + override val kind: LexicalScopeKind, + private val memberScopes: List, + @Deprecated("This value is temporary hack for resolve -- don't use it!") + val isStaticScope: Boolean = false +) : LexicalScope { override val parent = parent.takeSnapshot() - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) - = getFromAllScopes(memberScopes) { it.getContributedDescriptors() } + override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = + getFromAllScopes(memberScopes) { it.getContributedDescriptors() } - override fun getContributedClassifier(name: Name, location: LookupLocation) = getFirstClassifierDiscriminateHeaders(memberScopes) { it.getContributedClassifier(name, location) } + override fun getContributedClassifier(name: Name, location: LookupLocation) = + getFirstClassifierDiscriminateHeaders(memberScopes) { it.getContributedClassifier(name, location) } - override fun getContributedVariables(name: Name, location: LookupLocation) = getFromAllScopes(memberScopes) { it.getContributedVariables(name, location) } + override fun getContributedVariables(name: Name, location: LookupLocation) = + getFromAllScopes(memberScopes) { it.getContributedVariables(name, location) } - override fun getContributedFunctions(name: Name, location: LookupLocation) = getFromAllScopes(memberScopes) { it.getContributedFunctions(name, location) } + override fun getContributedFunctions(name: Name, location: LookupLocation) = + getFromAllScopes(memberScopes) { it.getContributedFunctions(name, location) } override fun toString(): String = kind.toString() override fun printStructure(p: Printer) { - p.println(this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name, - " with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {") + p.println( + this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name, + " with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {" + ) p.pushIndent() for (scope in memberScopes) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalScopeImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalScopeImpl.kt index aa9f1bae089..1d2add35fd3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalScopeImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalScopeImpl.kt @@ -20,14 +20,14 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.utils.Printer class LexicalScopeImpl @JvmOverloads constructor( - parent: HierarchicalScope, - override val ownerDescriptor: DeclarationDescriptor, - override val isOwnerDescriptorAccessibleByLabel: Boolean, - override val implicitReceiver: ReceiverParameterDescriptor?, - override val kind: LexicalScopeKind, - redeclarationChecker: LocalRedeclarationChecker = LocalRedeclarationChecker.DO_NOTHING, - initialize: LexicalScopeImpl.InitializeHandler.() -> Unit = {} -): LexicalScope, LexicalScopeStorage(parent, redeclarationChecker) { + parent: HierarchicalScope, + override val ownerDescriptor: DeclarationDescriptor, + override val isOwnerDescriptorAccessibleByLabel: Boolean, + override val implicitReceiver: ReceiverParameterDescriptor?, + override val kind: LexicalScopeKind, + redeclarationChecker: LocalRedeclarationChecker = LocalRedeclarationChecker.DO_NOTHING, + initialize: LexicalScopeImpl.InitializeHandler.() -> Unit = {} +) : LexicalScope, LexicalScopeStorage(parent, redeclarationChecker) { init { InitializeHandler().initialize() @@ -36,8 +36,10 @@ class LexicalScopeImpl @JvmOverloads constructor( override fun toString(): String = kind.toString() override fun printStructure(p: Printer) { - p.println(this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name, - " with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {") + p.println( + this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name, + " with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {" + ) p.pushIndent() p.print("parent = ") @@ -49,14 +51,14 @@ class LexicalScopeImpl @JvmOverloads constructor( inner class InitializeHandler() { - fun addVariableDescriptor(variableDescriptor: VariableDescriptor): Unit - = this@LexicalScopeImpl.addVariableOrClassDescriptor(variableDescriptor) + fun addVariableDescriptor(variableDescriptor: VariableDescriptor): Unit = + this@LexicalScopeImpl.addVariableOrClassDescriptor(variableDescriptor) - fun addFunctionDescriptor(functionDescriptor: FunctionDescriptor): Unit - = this@LexicalScopeImpl.addFunctionDescriptorInternal(functionDescriptor) + fun addFunctionDescriptor(functionDescriptor: FunctionDescriptor): Unit = + this@LexicalScopeImpl.addFunctionDescriptorInternal(functionDescriptor) - fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor): Unit - = this@LexicalScopeImpl.addVariableOrClassDescriptor(classifierDescriptor) + fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor): Unit = + this@LexicalScopeImpl.addVariableOrClassDescriptor(classifierDescriptor) } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalScopeStorage.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalScopeStorage.kt index f2e67b63155..34dc986a6f6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalScopeStorage.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalScopeStorage.kt @@ -35,9 +35,9 @@ interface LocalRedeclarationChecker { } abstract class LexicalScopeStorage( - parent: HierarchicalScope, - val redeclarationChecker: LocalRedeclarationChecker -): LexicalScope { + parent: HierarchicalScope, + val redeclarationChecker: LocalRedeclarationChecker +) : LexicalScope { override val parent = parent.takeSnapshot() protected val addedDescriptors: MutableList = SmartList() @@ -45,13 +45,15 @@ abstract class LexicalScopeStorage( private var functionsByName: MutableMap? = null private var variablesAndClassifiersByName: MutableMap? = null - override fun getContributedClassifier(name: Name, location: LookupLocation) = variableOrClassDescriptorByName(name) as? ClassifierDescriptor - override fun getContributedVariables(name: Name, location: LookupLocation) = listOfNotNull(variableOrClassDescriptorByName(name) as? VariableDescriptor) + override fun getContributedClassifier(name: Name, location: LookupLocation) = + variableOrClassDescriptorByName(name) as? ClassifierDescriptor + + override fun getContributedVariables(name: Name, location: LookupLocation) = + listOfNotNull(variableOrClassDescriptorByName(name) as? VariableDescriptor) override fun getContributedFunctions(name: Name, location: LookupLocation) = functionsByName(name) - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) - = addedDescriptors + override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = addedDescriptors protected fun addVariableOrClassDescriptor(descriptor: DeclarationDescriptor) { val name = descriptor.name @@ -115,7 +117,7 @@ abstract class LexicalScopeStorage( private operator fun IntList?.plus(value: Int) = IntList(value, this) - private fun IntList.toDescriptors(): List { + private fun IntList.toDescriptors(): List { val result = ArrayList(1) var rest: IntList? = this do { @@ -126,5 +128,5 @@ abstract class LexicalScopeStorage( } override fun definitelyDoesNotContainName(name: Name) = - functionsByName?.get(name) == null && variablesAndClassifiersByName?.get(name) == null + functionsByName?.get(name) == null && variablesAndClassifiersByName?.get(name) == null } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalWritableScope.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalWritableScope.kt index 08872a763e7..cea0ab2a0f8 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalWritableScope.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/LexicalWritableScope.kt @@ -22,11 +22,11 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.Printer class LexicalWritableScope( - parent: LexicalScope, - override val ownerDescriptor: DeclarationDescriptor, - override val isOwnerDescriptorAccessibleByLabel: Boolean, - redeclarationChecker: LocalRedeclarationChecker, - override val kind: LexicalScopeKind + parent: LexicalScope, + override val ownerDescriptor: DeclarationDescriptor, + override val isOwnerDescriptorAccessibleByLabel: Boolean, + redeclarationChecker: LocalRedeclarationChecker, + override val kind: LexicalScopeKind ) : LexicalScopeStorage(parent, redeclarationChecker) { override val implicitReceiver: ReceiverParameterDescriptor? @@ -68,11 +68,14 @@ class LexicalWritableScope( } private inner class Snapshot(val descriptorLimit: Int) : LexicalScope by this { - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) - = addedDescriptors.subList(0, descriptorLimit) + override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = + addedDescriptors.subList(0, descriptorLimit) - override fun getContributedClassifier(name: Name, location: LookupLocation) = variableOrClassDescriptorByName(name, descriptorLimit) as? ClassifierDescriptor - override fun getContributedVariables(name: Name, location: LookupLocation) = listOfNotNull(variableOrClassDescriptorByName(name, descriptorLimit) as? VariableDescriptor) + override fun getContributedClassifier(name: Name, location: LookupLocation) = + variableOrClassDescriptorByName(name, descriptorLimit) as? ClassifierDescriptor + + override fun getContributedVariables(name: Name, location: LookupLocation) = + listOfNotNull(variableOrClassDescriptorByName(name, descriptorLimit) as? VariableDescriptor) override fun getContributedFunctions(name: Name, location: LookupLocation) = functionsByName(name, descriptorLimit) @@ -88,8 +91,10 @@ class LexicalWritableScope( override fun toString(): String = kind.toString() override fun printStructure(p: Printer) { - p.println(this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name, - " with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {") + p.println( + this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name, + " with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {" + ) p.pushIndent() p.print("parent = ") diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/Scopes.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/Scopes.kt index 8d84419555b..12453861863 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/Scopes.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/Scopes.kt @@ -40,8 +40,8 @@ interface LexicalScope : HierarchicalScope { val kind: LexicalScopeKind class Base( - parent: HierarchicalScope, - override val ownerDescriptor: DeclarationDescriptor + parent: HierarchicalScope, + override val ownerDescriptor: DeclarationDescriptor ) : BaseHierarchicalScope(parent), LexicalScope { override val parent: HierarchicalScope get() = super.parent!! @@ -112,12 +112,15 @@ interface ImportingScope : HierarchicalScope { fun getContributedPackage(name: Name): PackageViewDescriptor? fun getContributedDescriptors( - kindFilter: DescriptorKindFilter = DescriptorKindFilter.ALL, - nameFilter: (Name) -> Boolean = MemberScope.ALL_NAME_FILTER, - changeNamesForAliased: Boolean + kindFilter: DescriptorKindFilter = DescriptorKindFilter.ALL, + nameFilter: (Name) -> Boolean = MemberScope.ALL_NAME_FILTER, + changeNamesForAliased: Boolean ): Collection - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection { + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean + ): Collection { return getContributedDescriptors(kindFilter, nameFilter, changeNamesForAliased = false) } @@ -135,7 +138,10 @@ interface ImportingScope : HierarchicalScope { } abstract class BaseHierarchicalScope(override val parent: HierarchicalScope?) : HierarchicalScope { - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection = emptyList() + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean + ): Collection = emptyList() override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null @@ -150,10 +156,16 @@ abstract class BaseImportingScope(parent: ImportingScope?) : BaseHierarchicalSco override fun getContributedPackage(name: Name): PackageViewDescriptor? = null - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection { + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean + ): Collection { return getContributedDescriptors(kindFilter, nameFilter, changeNamesForAliased = false) } - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, changeNamesForAliased: Boolean): Collection - = emptyList() + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean, + changeNamesForAliased: Boolean + ): Collection = emptyList() } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/SubpackagesImportingScope.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/SubpackagesImportingScope.kt index ac0db8a37df..c19133949a8 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/SubpackagesImportingScope.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/SubpackagesImportingScope.kt @@ -27,9 +27,9 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.Printer class SubpackagesImportingScope( - override val parent: ImportingScope?, - moduleDescriptor: ModuleDescriptor, - fqName: FqName + override val parent: ImportingScope?, + moduleDescriptor: ModuleDescriptor, + fqName: FqName ) : SubpackagesScope(moduleDescriptor, fqName), ImportingScope by ImportingScope.Empty { override fun getContributedPackage(name: Name): PackageViewDescriptor? = getPackage(name) @@ -42,11 +42,18 @@ class SubpackagesImportingScope( //TODO: kept old behavior, but it seems very strange (super call seems more applicable) override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection = - emptyList() + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean + ): Collection = + emptyList() //TODO: kept old behavior, but it seems very strange (super call seems more applicable) - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, changeNamesForAliased: Boolean): Collection - = emptyList() + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean, + changeNamesForAliased: Boolean + ): Collection = emptyList() + override fun computeImportedNames() = emptySet() } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/receivers/QualifierReceiver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/receivers/QualifierReceiver.kt index 5fee630579a..74adef110c6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/receivers/QualifierReceiver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/receivers/QualifierReceiver.kt @@ -25,10 +25,10 @@ import org.jetbrains.kotlin.types.checker.prepareArgumentTypeRegardingCaptureTyp interface DetailedReceiver class ReceiverValueWithSmartCastInfo( - val receiverValue: ReceiverValue, - val possibleTypes: Set, // doesn't include receiver.type - val isStable: Boolean -): DetailedReceiver { + val receiverValue: ReceiverValue, + val possibleTypes: Set, // doesn't include receiver.type + val isStable: Boolean +) : DetailedReceiver { override fun toString() = receiverValue.toString() } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt index bd78a00c28f..c671013af99 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/utils/ScopeUtils.kt @@ -42,17 +42,16 @@ fun LexicalScope.getImplicitReceiversHierarchy(): List = collectAllFromMeAndParent { if (it is LexicalScope && it.isOwnerDescriptorAccessibleByLabel && it.ownerDescriptor.name == labelName) { listOf(it.ownerDescriptor) - } - else { + } else { listOf() } } // Result is guaranteed to be filtered by kind and name. fun HierarchicalScope.collectDescriptorsFiltered( - kindFilter: DescriptorKindFilter = DescriptorKindFilter.ALL, - nameFilter: (Name) -> Boolean = { true }, - changeNamesForAliased: Boolean = false + kindFilter: DescriptorKindFilter = DescriptorKindFilter.ALL, + nameFilter: (Name) -> Boolean = { true }, + changeNamesForAliased: Boolean = false ): Collection { if (kindFilter.kindMask == 0) return listOf() return collectAllFromMeAndParent { @@ -63,38 +62,49 @@ fun HierarchicalScope.collectDescriptorsFiltered( }.filter { kindFilter.accepts(it) && nameFilter(it.name) } } -@Deprecated("Use getContributedProperties instead") fun LexicalScope.findLocalVariable(name: Name): VariableDescriptor? { +@Deprecated("Use getContributedProperties instead") +fun LexicalScope.findLocalVariable(name: Name): VariableDescriptor? { return findFirstFromMeAndParent { when { it is LexicalScopeWrapper -> it.delegate.findLocalVariable(name) - it !is ImportingScope && it !is LexicalChainedScope -> it.getContributedVariables(name, NoLookupLocation.WHEN_GET_LOCAL_VARIABLE).singleOrNull() /* todo check this*/ + it !is ImportingScope && it !is LexicalChainedScope -> it.getContributedVariables( + name, + NoLookupLocation.WHEN_GET_LOCAL_VARIABLE + ).singleOrNull() /* todo check this*/ else -> null } } } -fun HierarchicalScope.findClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? - = findFirstFromMeAndParent { it.getContributedClassifier(name, location) } +fun HierarchicalScope.findClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = + findFirstFromMeAndParent { it.getContributedClassifier(name, location) } -fun HierarchicalScope.findPackage(name: Name): PackageViewDescriptor? - = findFirstFromImportingScopes { it.getContributedPackage(name) } +fun HierarchicalScope.findPackage(name: Name): PackageViewDescriptor? = findFirstFromImportingScopes { it.getContributedPackage(name) } -fun HierarchicalScope.collectVariables(name: Name, location: LookupLocation): Collection - = collectAllFromMeAndParent { it.getContributedVariables(name, location) } +fun HierarchicalScope.collectVariables(name: Name, location: LookupLocation): Collection = + collectAllFromMeAndParent { it.getContributedVariables(name, location) } -fun HierarchicalScope.collectFunctions(name: Name, location: LookupLocation): Collection - = collectAllFromMeAndParent { it.getContributedFunctions(name, location) } +fun HierarchicalScope.collectFunctions(name: Name, location: LookupLocation): Collection = + collectAllFromMeAndParent { it.getContributedFunctions(name, location) } -fun HierarchicalScope.findVariable(name: Name, location: LookupLocation, predicate: (VariableDescriptor) -> Boolean = { true }): VariableDescriptor? { +fun HierarchicalScope.findVariable( + name: Name, + location: LookupLocation, + predicate: (VariableDescriptor) -> Boolean = { true } +): VariableDescriptor? { processForMeAndParent { it.getContributedVariables(name, location).firstOrNull(predicate)?.let { return it } } return null } -fun HierarchicalScope.findFunction(name: Name, location: LookupLocation, predicate: (FunctionDescriptor) -> Boolean = { true }): FunctionDescriptor? { +fun HierarchicalScope.findFunction( + name: Name, + location: LookupLocation, + predicate: (FunctionDescriptor) -> Boolean = { true } +): FunctionDescriptor? { processForMeAndParent { it.getContributedFunctions(name, location).firstOrNull(predicate)?.let { return it } } @@ -103,13 +113,18 @@ fun HierarchicalScope.findFunction(name: Name, location: LookupLocation, predica fun HierarchicalScope.takeSnapshot(): HierarchicalScope = if (this is LexicalWritableScope) takeSnapshot() else this -@JvmOverloads fun MemberScope.memberScopeAsImportingScope(parentScope: ImportingScope? = null): ImportingScope = MemberScopeToImportingScopeAdapter(parentScope, this) +@JvmOverloads +fun MemberScope.memberScopeAsImportingScope(parentScope: ImportingScope? = null): ImportingScope = + MemberScopeToImportingScopeAdapter(parentScope, this) private class MemberScopeToImportingScopeAdapter(override val parent: ImportingScope?, val memberScope: MemberScope) : ImportingScope { override fun getContributedPackage(name: Name): PackageViewDescriptor? = null - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, changeNamesForAliased: Boolean) - = memberScope.getContributedDescriptors(kindFilter, nameFilter) + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean, + changeNamesForAliased: Boolean + ) = memberScope.getContributedDescriptors(kindFilter, nameFilter) override fun getContributedClassifier(name: Name, location: LookupLocation) = memberScope.getContributedClassifier(name, location) @@ -144,8 +159,8 @@ inline fun HierarchicalScope.processForMeAndParent(process: (HierarchicalScope) } } -private inline fun HierarchicalScope.collectFromMeAndParent( - collect: (HierarchicalScope) -> T? +private inline fun HierarchicalScope.collectFromMeAndParent( + collect: (HierarchicalScope) -> T? ): List { var result: MutableList? = null processForMeAndParent { @@ -160,26 +175,26 @@ private inline fun HierarchicalScope.collectFromMeAndParent( return result ?: emptyList() } -inline fun HierarchicalScope.collectAllFromMeAndParent( - collect: (HierarchicalScope) -> Collection +inline fun HierarchicalScope.collectAllFromMeAndParent( + collect: (HierarchicalScope) -> Collection ): Collection { var result: Collection? = null processForMeAndParent { result = result.concat(collect(it)) } return result ?: emptySet() } -inline fun HierarchicalScope.findFirstFromMeAndParent(fetch: (HierarchicalScope) -> T?): T? { +inline fun HierarchicalScope.findFirstFromMeAndParent(fetch: (HierarchicalScope) -> T?): T? { processForMeAndParent { fetch(it)?.let { return it } } return null } -inline fun HierarchicalScope.collectAllFromImportingScopes( - collect: (ImportingScope) -> Collection +inline fun HierarchicalScope.collectAllFromImportingScopes( + collect: (ImportingScope) -> Collection ): Collection { return collectAllFromMeAndParent { if (it is ImportingScope) collect(it) else emptyList() } } -inline fun HierarchicalScope.findFirstFromImportingScopes(fetch: (ImportingScope) -> T?): T? { +inline fun HierarchicalScope.findFirstFromImportingScopes(fetch: (ImportingScope) -> T?): T? { return findFirstFromMeAndParent { if (it is ImportingScope) fetch(it) else null } } @@ -190,11 +205,10 @@ fun LexicalScope.addImportingScopes(importScopes: List): Lexical return replaceImportingScopes(newFirstImporting) } -fun LexicalScope.addImportingScope(importScope: ImportingScope): LexicalScope - = addImportingScopes(listOf(importScope)) +fun LexicalScope.addImportingScope(importScope: ImportingScope): LexicalScope = addImportingScopes(listOf(importScope)) fun ImportingScope.withParent(newParent: ImportingScope?): ImportingScope { - return object: ImportingScope by this { + return object : ImportingScope by this { override val parent: ImportingScope? get() = newParent } @@ -210,13 +224,13 @@ fun LexicalScope.replaceImportingScopes(importingScopeChain: ImportingScope?): L fun LexicalScope.createScopeForDestructuring(newReceiver: ReceiverParameterDescriptor?): LexicalScope { return LexicalScopeImpl( - parent, ownerDescriptor, isOwnerDescriptorAccessibleByLabel, - newReceiver, - LexicalScopeKind.FUNCTION_HEADER_FOR_DESTRUCTURING + parent, ownerDescriptor, isOwnerDescriptorAccessibleByLabel, + newReceiver, + LexicalScopeKind.FUNCTION_HEADER_FOR_DESTRUCTURING ) } -private class LexicalScopeWrapper(val delegate: LexicalScope, val newImportingScopeChain: ImportingScope): LexicalScope by delegate { +private class LexicalScopeWrapper(val delegate: LexicalScope, val newImportingScopeChain: ImportingScope) : LexicalScope by delegate { init { assert(delegate !is LexicalScopeWrapper) { "Do not wrap again to avoid performance issues" @@ -229,8 +243,7 @@ private class LexicalScopeWrapper(val delegate: LexicalScope, val newImportingSc val parent = delegate.parent if (parent is LexicalScope) { parent.replaceImportingScopes(newImportingScopeChain) - } - else { + } else { newImportingScopeChain } } @@ -240,10 +253,10 @@ private class LexicalScopeWrapper(val delegate: LexicalScope, val newImportingSc fun chainImportingScopes(scopes: List, tail: ImportingScope? = null): ImportingScope? { return scopes.asReversed() - .fold(tail) { current, scope -> - assert(scope.parent == null) - scope.withParent(current) - } + .fold(tail) { current, scope -> + assert(scope.parent == null) + scope.withParent(current) + } } class ErrorLexicalScope : LexicalScope { @@ -260,7 +273,10 @@ class ErrorLexicalScope : LexicalScope { override fun getContributedFunctions(name: Name, location: LookupLocation): Collection = emptySet() - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection = emptySet() + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean + ): Collection = emptySet() } override fun printStructure(p: Printer) { @@ -278,5 +294,8 @@ class ErrorLexicalScope : LexicalScope { override fun getContributedFunctions(name: Name, location: LookupLocation): Collection = emptySet() - override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection = emptySet() + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean + ): Collection = emptySet() } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/sinceKotlinUtil.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/sinceKotlinUtil.kt index ccc62b48016..bfc5da11d17 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/sinceKotlinUtil.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/sinceKotlinUtil.kt @@ -30,12 +30,12 @@ val SINCE_KOTLIN_FQ_NAME = FqName("kotlin.SinceKotlin") * callback is called with the version specified in the [SinceKotlin] annotation if the descriptor is inaccessible. */ fun DeclarationDescriptor.checkSinceKotlinVersionAccessibility( - languageVersionSettings: LanguageVersionSettings, - actionIfInaccessible: ((ApiVersion) -> Unit)? = null + languageVersionSettings: LanguageVersionSettings, + actionIfInaccessible: ((ApiVersion) -> Unit)? = null ): Boolean { val version = - if (this is CallableMemberDescriptor && !kind.isReal) getSinceKotlinVersionByOverridden(this) - else getOwnSinceKotlinVersion() + if (this is CallableMemberDescriptor && !kind.isReal) getSinceKotlinVersionByOverridden(this) + else getOwnSinceKotlinVersion() // Allow access in the following cases: // 1) There's no @SinceKotlin annotation for this descriptor @@ -59,16 +59,15 @@ private fun getSinceKotlinVersionByOverridden(descriptor: CallableMemberDescript private fun DeclarationDescriptor.getOwnSinceKotlinVersion(): ApiVersion? { // TODO: use-site targeted annotations fun DeclarationDescriptor.loadAnnotationValue(): ApiVersion? = - (annotations.findAnnotation(SINCE_KOTLIN_FQ_NAME)?.allValueArguments?.values?.singleOrNull()?.value as? String) - ?.let(ApiVersion.Companion::parse) + (annotations.findAnnotation(SINCE_KOTLIN_FQ_NAME)?.allValueArguments?.values?.singleOrNull()?.value as? String) + ?.let(ApiVersion.Companion::parse) val ownVersion = loadAnnotationValue() val ctorClass = (this as? ConstructorDescriptor)?.containingDeclaration?.loadAnnotationValue() val property = (this as? PropertyAccessorDescriptor)?.correspondingProperty?.loadAnnotationValue() - val typeAliasDescriptor = (this as? TypeAliasDescriptor) ?: - (this as? TypeAliasConstructorDescriptor)?.typeAliasDescriptor ?: - (this as? FakeCallableDescriptorForTypeAliasObject)?.typeAliasDescriptor + val typeAliasDescriptor = (this as? TypeAliasDescriptor) ?: (this as? TypeAliasConstructorDescriptor)?.typeAliasDescriptor + ?: (this as? FakeCallableDescriptorForTypeAliasObject)?.typeAliasDescriptor val typeAlias = typeAliasDescriptor?.loadAnnotationValue() diff --git a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt index 1e6cd4014fa..9f82cb0a48a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/types/TypeApproximator.kt @@ -35,6 +35,7 @@ open class TypeApproximatorConfiguration { TO_FIRST, TO_COMMON_SUPERTYPE } + open val flexible get() = false // simple flexible types (FlexibleTypeImpl) open val dynamic get() = false // DynamicType open val rawType get() = false // RawTypeImpl @@ -65,7 +66,8 @@ open class TypeApproximatorConfiguration { override val definitelyNotNullType get() = false } - abstract class AbstractCapturedTypesApproximation(val approximatedCapturedStatus: CaptureStatus): TypeApproximatorConfiguration.AllFlexibleSameValue() { + abstract class AbstractCapturedTypesApproximation(val approximatedCapturedStatus: CaptureStatus) : + TypeApproximatorConfiguration.AllFlexibleSameValue() { override val allFlexible get() = true override val errorType get() = true @@ -94,39 +96,42 @@ class TypeApproximator { // null means that this input type is the result, i.e. input type not contains not-allowed kind of types // type <: resultType fun approximateToSuperType(type: UnwrappedType, conf: TypeApproximatorConfiguration): UnwrappedType? = - approximateToSuperType(type, conf, - type.typeDepth()) + approximateToSuperType(type, conf, -type.typeDepth()) // resultType <: type fun approximateToSubType(type: UnwrappedType, conf: TypeApproximatorConfiguration): UnwrappedType? = - approximateToSubType(type, conf, - type.typeDepth()) + approximateToSubType(type, conf, -type.typeDepth()) private fun approximateToSuperType(type: UnwrappedType, conf: TypeApproximatorConfiguration, depth: Int): UnwrappedType? { if (type is TypeUtils.SpecialType) return null - return approximateTo(NewKotlinTypeChecker.transformToNewType(type), conf, FlexibleType::upperBound, - referenceApproximateToSuperType, depth) + return approximateTo( + NewKotlinTypeChecker.transformToNewType(type), conf, FlexibleType::upperBound, + referenceApproximateToSuperType, depth + ) } private fun approximateToSubType(type: UnwrappedType, conf: TypeApproximatorConfiguration, depth: Int): UnwrappedType? { if (type is TypeUtils.SpecialType) return null - return approximateTo(NewKotlinTypeChecker.transformToNewType(type), conf, FlexibleType::lowerBound, - referenceApproximateToSubType, depth) + return approximateTo( + NewKotlinTypeChecker.transformToNewType(type), conf, FlexibleType::lowerBound, + referenceApproximateToSubType, depth + ) } // comments for case bound = upperBound, approximateTo = toSuperType private fun approximateTo( - type: UnwrappedType, - conf: TypeApproximatorConfiguration, - bound: FlexibleType.() -> SimpleType, - approximateTo: (SimpleType, TypeApproximatorConfiguration, depth: Int) -> UnwrappedType?, - depth: Int + type: UnwrappedType, + conf: TypeApproximatorConfiguration, + bound: FlexibleType.() -> SimpleType, + approximateTo: (SimpleType, TypeApproximatorConfiguration, depth: Int) -> UnwrappedType?, + depth: Int ): UnwrappedType? { when (type) { is SimpleType -> return approximateTo(type, conf, depth) is FlexibleType -> { if (type is DynamicType) { return if (conf.dynamic) null else type.bound() - } - else if (type is RawType) { + } else if (type is RawType) { return if (conf.rawType) null else type.bound() } @@ -157,17 +162,23 @@ class TypeApproximator { * * If U_1 <: U_2.lower .. U_2.upper, then we know only that U_1 <: U_2.upper. */ - return KotlinTypeFactory.flexibleType(lowerResult?.lowerIfFlexible() ?: type.lowerBound, - upperResult?.upperIfFlexible() ?: type.upperBound) - } - else { + return KotlinTypeFactory.flexibleType( + lowerResult?.lowerIfFlexible() ?: type.lowerBound, + upperResult?.upperIfFlexible() ?: type.upperBound + ) + } else { return type.bound().let { approximateTo(it, conf, depth) ?: it } } } } } - private fun approximateIntersectionType(type: SimpleType, conf: TypeApproximatorConfiguration, toSuper: Boolean, depth: Int): UnwrappedType? { + private fun approximateIntersectionType( + type: SimpleType, + conf: TypeApproximatorConfiguration, + toSuper: Boolean, + depth: Int + ): UnwrappedType? { val typeConstructor = type.constructor assert(typeConstructor is IntersectionTypeConstructor) { "Should be intersection type: $type, typeConstructor class: ${typeConstructor::class.java.canonicalName}" @@ -194,35 +205,42 @@ class TypeApproximator { val baseResult = when (conf.intersection) { ALLOWED -> if (!thereIsApproximation) return null else intersectTypes(newTypes) TO_FIRST -> if (toSuper) newTypes.first() else return type.defaultResult(toSuper = false) - // commonSupertypeCalculator should handle flexible types correctly - TO_COMMON_SUPERTYPE -> if (toSuper) NewCommonSuperTypeCalculator.commonSuperType(newTypes) else return type.defaultResult(toSuper = false) + // commonSupertypeCalculator should handle flexible types correctly + TO_COMMON_SUPERTYPE -> if (toSuper) NewCommonSuperTypeCalculator.commonSuperType(newTypes) else return type.defaultResult( + toSuper = false + ) } return if (type.isMarkedNullable) baseResult.makeNullableAsSpecified(true) else baseResult } - private fun approximateCapturedType(type: NewCapturedType, conf: TypeApproximatorConfiguration, toSuper: Boolean, depth: Int): UnwrappedType? { + private fun approximateCapturedType( + type: NewCapturedType, + conf: TypeApproximatorConfiguration, + toSuper: Boolean, + depth: Int + ): UnwrappedType? { val supertypes = type.constructor.supertypes val baseSuperType = when (supertypes.size) { 0 -> type.builtIns.nullableAnyType // Let C = in Int, then superType for C and C? is Any? 1 -> supertypes.single() - // Consider the following example: - // A.getA()::class.java, where `getA()` returns some class from Java - // From `::class` we are getting type KClass>, where Cap have two supertypes: - // - Any (from declared upper bound of type parameter for KClass) - // - (A..A?) -- from A!, projection type of captured type + // Consider the following example: + // A.getA()::class.java, where `getA()` returns some class from Java + // From `::class` we are getting type KClass>, where Cap have two supertypes: + // - Any (from declared upper bound of type parameter for KClass) + // - (A..A?) -- from A!, projection type of captured type - // Now, after approximation we were getting type `KClass`, because { Any & (A..A?) } = A, - // but in old inference type was equal to `KClass`. + // Now, after approximation we were getting type `KClass`, because { Any & (A..A?) } = A, + // but in old inference type was equal to `KClass`. - // Important note that from the point of type system first type is more specific: - // Here, approximation of KClass> is a type KClass such that KClass> <: KClass => - // So, the the more specific type for T would be "some non-null (because of declared upper bound type) subtype of A", which is `out A` + // Important note that from the point of type system first type is more specific: + // Here, approximation of KClass> is a type KClass such that KClass> <: KClass => + // So, the the more specific type for T would be "some non-null (because of declared upper bound type) subtype of A", which is `out A` - // But for now, to reduce differences in behaviour of old and new inference, we'll approximate such types to `KClass` + // But for now, to reduce differences in behaviour of old and new inference, we'll approximate such types to `KClass` - // Once NI will be more stabilized, we'll use more specific type + // Once NI will be more stabilized, we'll use more specific type else -> type.constructor.projection.type.unwrap() } @@ -241,7 +259,11 @@ class TypeApproximator { return null } } - val baseResult = if (toSuper) approximateToSuperType(baseSuperType, conf, depth) ?: baseSuperType else approximateToSubType(baseSubType, conf, depth) ?: baseSubType + val baseResult = if (toSuper) approximateToSuperType(baseSuperType, conf, depth) ?: baseSuperType else approximateToSubType( + baseSubType, + conf, + depth + ) ?: baseSubType // C = in Int, Int <: C => Int? <: C? // C = out Number, C <: Number => C? <: Number? @@ -249,9 +271,10 @@ class TypeApproximator { } private fun approximateSimpleToSuperType(type: SimpleType, conf: TypeApproximatorConfiguration, depth: Int) = - approximateTo(type, conf, toSuper = true, depth = depth) + approximateTo(type, conf, toSuper = true, depth = depth) + private fun approximateSimpleToSubType(type: SimpleType, conf: TypeApproximatorConfiguration, depth: Int) = - approximateTo(type, conf, toSuper = false, depth = depth) + approximateTo(type, conf, toSuper = false, depth = depth) private fun approximateTo(type: SimpleType, conf: TypeApproximatorConfiguration, toSuper: Boolean, depth: Int): UnwrappedType? { if (type.isError) { @@ -272,9 +295,10 @@ class TypeApproximator { val typeConstructor = type.constructor if (typeConstructor is NewCapturedTypeConstructor) { - assert(type is NewCapturedType) { // KT-16147 + assert(type is NewCapturedType) { + // KT-16147 "Type is inconsistent -- somewhere we create type with typeConstructor = $typeConstructor " + - "and class: ${type::class.java.canonicalName}. type.toString() = $type" + "and class: ${type::class.java.canonicalName}. type.toString() = $type" } return approximateCapturedType(type as NewCapturedType, conf, toSuper, depth) } @@ -291,16 +315,15 @@ class TypeApproximator { } private fun approximateDefinitelyNotNullType( - type: DefinitelyNotNullType, - conf: TypeApproximatorConfiguration, - toSuper: Boolean, - depth: Int + type: DefinitelyNotNullType, + conf: TypeApproximatorConfiguration, + toSuper: Boolean, + depth: Int ): UnwrappedType? { val approximatedOriginalType = approximateTo(type.original, conf, toSuper, depth) return if (conf.definitelyNotNullType) { approximatedOriginalType?.makeDefinitelyNotNullOrNotNull() - } - else { + } else { if (toSuper) (approximatedOriginalType ?: type.original).makeNullableAsSpecified(false) else @@ -309,20 +332,24 @@ class TypeApproximator { } private fun isApproximateDirectionToSuper(effectiveVariance: Variance, toSuper: Boolean) = - when (effectiveVariance) { - Variance.OUT_VARIANCE -> toSuper - Variance.IN_VARIANCE -> !toSuper - Variance.INVARIANT -> throw AssertionError("Incorrect variance $effectiveVariance") - } + when (effectiveVariance) { + Variance.OUT_VARIANCE -> toSuper + Variance.IN_VARIANCE -> !toSuper + Variance.INVARIANT -> throw AssertionError("Incorrect variance $effectiveVariance") + } - private fun approximateParametrizedType(type: SimpleType, conf: TypeApproximatorConfiguration, toSuper: Boolean, depth: Int): SimpleType? { + private fun approximateParametrizedType( + type: SimpleType, + conf: TypeApproximatorConfiguration, + toSuper: Boolean, + depth: Int + ): SimpleType? { val parameters = type.constructor.parameters val arguments = type.arguments if (parameters.size != arguments.size) { return if (conf.errorType) { ErrorUtils.createErrorType("Inconsistent type: $type (parameters.size = ${parameters.size}, arguments.size = ${arguments.size})") - } - else type.defaultResult(toSuper) + } else type.defaultResult(toSuper) } val newArguments = arrayOfNulls(arguments.size) @@ -338,8 +365,10 @@ class TypeApproximator { when (effectiveVariance) { null -> { return if (conf.errorType) { - ErrorUtils.createErrorType("Inconsistent type: $type ($index parameter has declared variance: ${parameter.variance}, " + - "but argument variance is ${argument.projectionKind})") + ErrorUtils.createErrorType( + "Inconsistent type: $type ($index parameter has declared variance: ${parameter.variance}, " + + "but argument variance is ${argument.projectionKind})" + ) } else type.defaultResult(toSuper) } Variance.OUT_VARIANCE, Variance.IN_VARIANCE -> { @@ -353,8 +382,7 @@ class TypeApproximator { val approximatedArgument = argumentType.let { if (isApproximateDirectionToSuper(effectiveVariance, toSuper)) { approximateToSuperType(it, conf, depth) - } - else { + } else { approximateToSubType(it, conf, depth) } } ?: continue@loop @@ -397,9 +425,11 @@ class TypeApproximator { } } - val approximatedSuperType = approximateToSuperType(argumentType, conf, depth) ?: continue@loop // null means that this type we can leave as is + val approximatedSuperType = + approximateToSuperType(argumentType, conf, depth) ?: continue@loop // null means that this type we can leave as is if (approximatedSuperType.isTrivialSuper()) { - val approximatedSubType = approximateToSubType(argumentType, conf, depth) ?: continue@loop // seems like this is never null + val approximatedSubType = + approximateToSubType(argumentType, conf, depth) ?: continue@loop // seems like this is never null if (!approximatedSubType.isTrivialSub()) { newArguments[index] = TypeProjectionImpl(Variance.IN_VARIANCE, approximatedSubType) continue@loop @@ -408,8 +438,7 @@ class TypeApproximator { if (NewKotlinTypeChecker.equalTypes(argumentType, approximatedSuperType)) { newArguments[index] = approximatedSuperType.asTypeProjection() - } - else { + } else { newArguments[index] = TypeProjectionImpl(Variance.OUT_VARIANCE, approximatedSuperType) } } @@ -434,10 +463,10 @@ class TypeApproximator { } internal fun UnwrappedType.typeDepth() = - when (this) { - is SimpleType -> typeDepth() - is FlexibleType -> Math.max(lowerBound.typeDepth(), upperBound.typeDepth()) - } + when (this) { + is SimpleType -> typeDepth() + is FlexibleType -> Math.max(lowerBound.typeDepth(), upperBound.typeDepth()) + } internal fun SimpleType.typeDepth(): Int { if (this is TypeUtils.SpecialType) return 0