Reformat 'resolution' module according to new codestyle
This commit is contained in:
+1
-2
@@ -87,8 +87,7 @@ class ContractDescriptionRenderer(private val builder: StringBuilder) : Contract
|
|||||||
builder.append("(")
|
builder.append("(")
|
||||||
block()
|
block()
|
||||||
builder.append(")")
|
builder.append(")")
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-3
@@ -25,7 +25,10 @@ interface ContractDescriptionVisitor<out R, in D> {
|
|||||||
|
|
||||||
// Effects
|
// Effects
|
||||||
fun visitEffectDeclaration(effectDeclaration: EffectDeclaration, data: D): R = visitContractDescriptionElement(effectDeclaration, data)
|
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 visitReturnsEffectDeclaration(returnsEffect: ReturnsEffectDeclaration, data: D): R = visitEffectDeclaration(returnsEffect, data)
|
||||||
fun visitCallsEffectDeclaration(callsEffect: CallsEffectDeclaration, data: D): R = visitEffectDeclaration(callsEffect, data)
|
fun visitCallsEffectDeclaration(callsEffect: CallsEffectDeclaration, data: D): R = visitEffectDeclaration(callsEffect, data)
|
||||||
|
|
||||||
@@ -43,7 +46,10 @@ interface ContractDescriptionVisitor<out R, in D> {
|
|||||||
fun visitValue(value: ContractDescriptionValue, data: D): R = visitContractDescriptionElement(value, data)
|
fun visitValue(value: ContractDescriptionValue, data: D): R = visitContractDescriptionElement(value, data)
|
||||||
|
|
||||||
fun visitConstantDescriptor(constantReference: ConstantReference, data: D): R = visitValue(constantReference, 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 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)
|
||||||
}
|
}
|
||||||
+2
-1
@@ -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.functors.IsFunctor
|
||||||
import org.jetbrains.kotlin.contracts.model.structure.*
|
import org.jetbrains.kotlin.contracts.model.structure.*
|
||||||
|
|
||||||
internal class ConditionInterpreter(private val dispatcher: ContractInterpretationDispatcher) : ContractDescriptionVisitor<ESExpression?, Unit> {
|
internal class ConditionInterpreter(private val dispatcher: ContractInterpretationDispatcher) :
|
||||||
|
ContractDescriptionVisitor<ESExpression?, Unit> {
|
||||||
override fun visitLogicalOr(logicalOr: LogicalOr, data: Unit): ESExpression? {
|
override fun visitLogicalOr(logicalOr: LogicalOr, data: Unit): ESExpression? {
|
||||||
val left = logicalOr.left.accept(this, data) ?: return null
|
val left = logicalOr.left.accept(this, data) ?: return null
|
||||||
val right = logicalOr.right.accept(this, data) ?: return null
|
val right = logicalOr.right.accept(this, data) ?: return null
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ internal class ConstantValuesInterpreter {
|
|||||||
fun interpretConstant(constantReference: ConstantReference): ESConstant? = when (constantReference) {
|
fun interpretConstant(constantReference: ConstantReference): ESConstant? = when (constantReference) {
|
||||||
BooleanConstantReference.TRUE -> true.lift()
|
BooleanConstantReference.TRUE -> true.lift()
|
||||||
BooleanConstantReference.FALSE -> false.lift()
|
BooleanConstantReference.FALSE -> false.lift()
|
||||||
ConstantReference.NULL-> ESConstant.NULL
|
ConstantReference.NULL -> ESConstant.NULL
|
||||||
ConstantReference.NOT_NULL -> ESConstant.NOT_NULL
|
ConstantReference.NOT_NULL -> ESConstant.NOT_NULL
|
||||||
ConstantReference.WILDCARD -> ESConstant.WILDCARD
|
ConstantReference.WILDCARD -> ESConstant.WILDCARD
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
+2
-2
@@ -38,6 +38,7 @@ class ContractInterpretationDispatcher {
|
|||||||
ReturnsEffectInterpreter(this),
|
ReturnsEffectInterpreter(this),
|
||||||
CallsEffectInterpreter(this)
|
CallsEffectInterpreter(this)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun resolveFunctor(functionDescriptor: FunctionDescriptor): Functor? {
|
fun resolveFunctor(functionDescriptor: FunctionDescriptor): Functor? {
|
||||||
val contractDescriptor = functionDescriptor.getUserData(ContractProviderKey)?.getContractDescription() ?: return null
|
val contractDescriptor = functionDescriptor.getUserData(ContractProviderKey)?.getContractDescription() ?: return null
|
||||||
return convertContractDescriptorToFunctor(contractDescriptor)
|
return convertContractDescriptorToFunctor(contractDescriptor)
|
||||||
@@ -47,8 +48,7 @@ class ContractInterpretationDispatcher {
|
|||||||
val resultingClauses = contractDescription.effects.map { effect ->
|
val resultingClauses = contractDescription.effects.map { effect ->
|
||||||
if (effect is ConditionalEffectDeclaration) {
|
if (effect is ConditionalEffectDeclaration) {
|
||||||
conditionalEffectInterpreter.interpret(effect) ?: return null
|
conditionalEffectInterpreter.interpret(effect) ?: return null
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
effectsInterpreters.mapNotNull { it.tryInterpret(effect) }.singleOrNull() ?: return null
|
effectsInterpreters.mapNotNull { it.tryInterpret(effect) }.singleOrNull() ?: return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class MutableContextInfo private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
append("Fired effects: ")
|
append("Fired effects: ")
|
||||||
append(info.firedEffects.joinToString(separator = ", " ))
|
append(info.firedEffects.joinToString(separator = ", "))
|
||||||
appendln("")
|
appendln("")
|
||||||
|
|
||||||
subtypes.printMapEntriesWithSeparator("is")
|
subtypes.printMapEntriesWithSeparator("is")
|
||||||
|
|||||||
+4
-1
@@ -56,5 +56,8 @@ abstract class AbstractBinaryFunctor : AbstractReducingFunctor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun invokeWithConstant(computation: Computation, constant: ESConstant): List<ESEffect>
|
protected abstract fun invokeWithConstant(computation: Computation, constant: ESConstant): List<ESEffect>
|
||||||
protected abstract fun invokeWithReturningEffects(left: List<ConditionalEffect>, right: List<ConditionalEffect>): List<ConditionalEffect>
|
protected abstract fun invokeWithReturningEffects(
|
||||||
|
left: List<ConditionalEffect>,
|
||||||
|
right: List<ConditionalEffect>
|
||||||
|
): List<ConditionalEffect>
|
||||||
}
|
}
|
||||||
+1
-1
@@ -30,5 +30,5 @@ abstract class AbstractReducingFunctor : Functor {
|
|||||||
|
|
||||||
override fun invokeWithArguments(arguments: List<Computation>): List<ESEffect> = reducer.reduceEffects(doInvocation(arguments))
|
override fun invokeWithArguments(arguments: List<Computation>): List<ESEffect> = reducer.reduceEffects(doInvocation(arguments))
|
||||||
|
|
||||||
abstract protected fun doInvocation(arguments: List<Computation>): List<ESEffect>
|
protected abstract fun doInvocation(arguments: List<Computation>): List<ESEffect>
|
||||||
}
|
}
|
||||||
+5
-1
@@ -84,7 +84,11 @@ class EqualsFunctor(val isNegated: Boolean) : AbstractReducingFunctor() {
|
|||||||
resultingClauses.add(trueClause)
|
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()))
|
val falseClause = ConditionalEffect(effect.condition, ESReturns(isNegated.lift()))
|
||||||
resultingClauses.add(falseClause)
|
resultingClauses.add(falseClause)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -48,7 +48,10 @@ internal fun foldConditionsWithOr(list: List<ConditionalEffect>): ESExpression?
|
|||||||
/**
|
/**
|
||||||
* Places all clauses that equal to `firstModel` into first list, and all clauses that equal to `secondModel` into second list
|
* Places all clauses that equal to `firstModel` into first list, and all clauses that equal to `secondModel` into second list
|
||||||
*/
|
*/
|
||||||
internal fun List<ConditionalEffect>.strictPartition(firstModel: ESEffect, secondModel: ESEffect): Pair<List<ConditionalEffect>, List<ConditionalEffect>> {
|
internal fun List<ConditionalEffect>.strictPartition(
|
||||||
|
firstModel: ESEffect,
|
||||||
|
secondModel: ESEffect
|
||||||
|
): Pair<List<ConditionalEffect>, List<ConditionalEffect>> {
|
||||||
val first = mutableListOf<ConditionalEffect>()
|
val first = mutableListOf<ConditionalEffect>()
|
||||||
val second = mutableListOf<ConditionalEffect>()
|
val second = mutableListOf<ConditionalEffect>()
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -30,11 +30,13 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
class SubstitutingFunctor(private val basicEffects: List<ESEffect>, private val ownerFunction: FunctionDescriptor) : AbstractReducingFunctor() {
|
class SubstitutingFunctor(private val basicEffects: List<ESEffect>, private val ownerFunction: FunctionDescriptor) :
|
||||||
|
AbstractReducingFunctor() {
|
||||||
override fun doInvocation(arguments: List<Computation>): List<ESEffect> {
|
override fun doInvocation(arguments: List<Computation>): List<ESEffect> {
|
||||||
if (basicEffects.isEmpty()) return emptyList()
|
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() }
|
val parameters = receiver + ownerFunction.valueParameters.map { it.toESVariable() }
|
||||||
|
|
||||||
assert(parameters.size == arguments.size) {
|
assert(parameters.size == arguments.size) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.contracts.model.ESEffect
|
|||||||
import org.jetbrains.kotlin.contracts.model.ESValue
|
import org.jetbrains.kotlin.contracts.model.ESValue
|
||||||
import org.jetbrains.kotlin.contracts.model.SimpleEffect
|
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? {
|
override fun isImplies(other: ESEffect): Boolean? {
|
||||||
if (other !is ESCalls) return null
|
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? {
|
override fun isImplies(other: ESEffect): Boolean? {
|
||||||
if (other !is ESReturns) return null
|
if (other !is ESReturns) return null
|
||||||
|
|
||||||
|
|||||||
@@ -22,28 +22,28 @@ import org.jetbrains.kotlin.contracts.model.ESOperator
|
|||||||
import org.jetbrains.kotlin.contracts.model.ESValue
|
import org.jetbrains.kotlin.contracts.model.ESValue
|
||||||
import org.jetbrains.kotlin.contracts.model.functors.*
|
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 val functor: AndFunctor = AndFunctor()
|
||||||
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitAnd(this)
|
override fun <T> accept(visitor: ESExpressionVisitor<T>): 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 val functor: OrFunctor = OrFunctor()
|
||||||
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitOr(this)
|
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitOr(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ESNot(val arg: ESExpression): ESOperator {
|
class ESNot(val arg: ESExpression) : ESOperator {
|
||||||
override val functor = NotFunctor()
|
override val functor = NotFunctor()
|
||||||
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitNot(this)
|
override fun <T> accept(visitor: ESExpressionVisitor<T>): 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
|
val type = functor.type
|
||||||
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitIs(this)
|
override fun <T> accept(visitor: ESExpressionVisitor<T>): 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 val functor: EqualsFunctor = EqualsFunctor(isNegated)
|
||||||
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitEqual(this)
|
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitEqual(this)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -24,7 +24,9 @@ class InfoCollector(private val observedEffect: ESEffect) : ESExpressionVisitor<
|
|||||||
private var isInverted: Boolean = false
|
private var isInverted: Boolean = false
|
||||||
|
|
||||||
fun collectFromSchema(schema: List<ESEffect>): MutableContextInfo =
|
fun collectFromSchema(schema: List<ESEffect>): 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? {
|
private fun collectFromEffect(effect: ESEffect): MutableContextInfo? {
|
||||||
if (effect !is ConditionalEffect) {
|
if (effect !is ConditionalEffect) {
|
||||||
@@ -42,7 +44,10 @@ class InfoCollector(private val observedEffect: ESEffect) : ESExpressionVisitor<
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitIs(isOperator: ESIs): MutableContextInfo = with(isOperator) {
|
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) {
|
override fun visitEqual(equal: ESEqual): MutableContextInfo = with(equal) {
|
||||||
|
|||||||
+1
-2
@@ -54,8 +54,7 @@ class Substitutor(private val substitutions: Map<ESVariable, Computation>) : ESE
|
|||||||
return CallComputation(DefaultBuiltIns.Instance.booleanType, or.functor.invokeWithArguments(left, right))
|
return CallComputation(DefaultBuiltIns.Instance.booleanType, or.functor.invokeWithArguments(left, right))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitVariable(esVariable: ESVariable): Computation?
|
override fun visitVariable(esVariable: ESVariable): Computation? = substitutions[esVariable] ?: esVariable
|
||||||
= substitutions[esVariable] ?: esVariable
|
|
||||||
|
|
||||||
override fun visitConstant(esConstant: ESConstant): Computation? = esConstant
|
override fun visitConstant(esConstant: ESConstant): Computation? = esConstant
|
||||||
}
|
}
|
||||||
@@ -45,12 +45,18 @@ class KotlinCallResolver(
|
|||||||
kotlinCall.checkCallInvariants()
|
kotlinCall.checkCallInvariants()
|
||||||
|
|
||||||
val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall)
|
val candidateFactory = SimpleCandidateFactory(callComponents, scopeTower, kotlinCall)
|
||||||
val processor = when(kotlinCall.callKind) {
|
val processor = when (kotlinCall.callKind) {
|
||||||
KotlinCallKind.VARIABLE -> {
|
KotlinCallKind.VARIABLE -> {
|
||||||
createVariableAndObjectProcessor(scopeTower, kotlinCall.name, candidateFactory, kotlinCall.explicitReceiver?.receiver)
|
createVariableAndObjectProcessor(scopeTower, kotlinCall.name, candidateFactory, kotlinCall.explicitReceiver?.receiver)
|
||||||
}
|
}
|
||||||
KotlinCallKind.FUNCTION -> {
|
KotlinCallKind.FUNCTION -> {
|
||||||
createFunctionProcessor(scopeTower, kotlinCall.name, candidateFactory, factoryProviderForInvoke, kotlinCall.explicitReceiver?.receiver)
|
createFunctionProcessor(
|
||||||
|
scopeTower,
|
||||||
|
kotlinCall.name,
|
||||||
|
candidateFactory,
|
||||||
|
factoryProviderForInvoke,
|
||||||
|
kotlinCall.explicitReceiver?.receiver
|
||||||
|
)
|
||||||
}
|
}
|
||||||
KotlinCallKind.UNSUPPORTED -> throw UnsupportedOperationException()
|
KotlinCallKind.UNSUPPORTED -> throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
@@ -60,7 +66,12 @@ class KotlinCallResolver(
|
|||||||
return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks)
|
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)
|
return choseMostSpecific(candidateFactory, resolutionCallbacks, expectedType, candidates)
|
||||||
}
|
}
|
||||||
@@ -79,15 +90,19 @@ class KotlinCallResolver(
|
|||||||
val resolutionCandidates = givenCandidates.map { candidateFactory.createCandidate(it).forceResolution() }
|
val resolutionCandidates = givenCandidates.map { candidateFactory.createCandidate(it).forceResolution() }
|
||||||
|
|
||||||
if (collectAllCandidates) {
|
if (collectAllCandidates) {
|
||||||
val allCandidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates),
|
val allCandidates = towerResolver.runWithEmptyTowerData(
|
||||||
|
KnownResultProcessor(resolutionCandidates),
|
||||||
TowerResolver.AllCandidatesCollector(),
|
TowerResolver.AllCandidatesCollector(),
|
||||||
useOrder = false)
|
useOrder = false
|
||||||
|
)
|
||||||
return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks)
|
return kotlinCallCompleter.createAllCandidatesResult(allCandidates, expectedType, resolutionCallbacks)
|
||||||
|
|
||||||
}
|
}
|
||||||
val candidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolutionCandidates),
|
val candidates = towerResolver.runWithEmptyTowerData(
|
||||||
|
KnownResultProcessor(resolutionCandidates),
|
||||||
TowerResolver.SuccessfulResultCollector(),
|
TowerResolver.SuccessfulResultCollector(),
|
||||||
useOrder = true)
|
useOrder = true
|
||||||
|
)
|
||||||
return choseMostSpecific(candidateFactory, resolutionCallbacks, expectedType, candidates)
|
return choseMostSpecific(candidateFactory, resolutionCallbacks, expectedType, candidates)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +126,8 @@ class KotlinCallResolver(
|
|||||||
refinedCandidates,
|
refinedCandidates,
|
||||||
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||||
discriminateGenerics = true, // todo
|
discriminateGenerics = true, // todo
|
||||||
isDebuggerContext = isDebuggerContext)
|
isDebuggerContext = isDebuggerContext
|
||||||
|
)
|
||||||
|
|
||||||
return kotlinCallCompleter.runCompletion(candidateFactory, maximallySpecificCandidates, expectedType, resolutionCallbacks)
|
return kotlinCallCompleter.runCompletion(candidateFactory, maximallySpecificCandidates, expectedType, resolutionCallbacks)
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-14
@@ -89,7 +89,7 @@ object NewCommonSuperTypeCalculator {
|
|||||||
private fun commonSuperTypeForNotNullTypes(types: List<SimpleType>, depth: Int): SimpleType {
|
private fun commonSuperTypeForNotNullTypes(types: List<SimpleType>, depth: Int): SimpleType {
|
||||||
val uniqueTypes = types.uniquify()
|
val uniqueTypes = types.uniquify()
|
||||||
val filteredType = uniqueTypes.filterNot { type ->
|
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
|
// seems like all types are equal
|
||||||
if (filteredType.isEmpty()) return uniqueTypes.first()
|
if (filteredType.isEmpty()) return uniqueTypes.first()
|
||||||
@@ -129,7 +129,12 @@ object NewCommonSuperTypeCalculator {
|
|||||||
constructor: TypeConstructor,
|
constructor: TypeConstructor,
|
||||||
depth: Int
|
depth: Int
|
||||||
): SimpleType {
|
): 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)
|
val typeCheckerContext = TypeCheckerContext(false)
|
||||||
|
|
||||||
@@ -160,8 +165,7 @@ object NewCommonSuperTypeCalculator {
|
|||||||
val argument =
|
val argument =
|
||||||
if (thereIsStar || typeProjections.isEmpty()) {
|
if (thereIsStar || typeProjections.isEmpty()) {
|
||||||
StarProjectionImpl(parameter)
|
StarProjectionImpl(parameter)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
calculateArgument(parameter, typeProjections, depth)
|
calculateArgument(parameter, typeProjections, depth)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,20 +189,17 @@ object NewCommonSuperTypeCalculator {
|
|||||||
val asOut: Boolean
|
val asOut: Boolean
|
||||||
if (parameter.variance != Variance.INVARIANT) {
|
if (parameter.variance != Variance.INVARIANT) {
|
||||||
asOut = parameter.variance == Variance.OUT_VARIANCE
|
asOut = parameter.variance == Variance.OUT_VARIANCE
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val thereIsOut = arguments.any { it.projectionKind == Variance.OUT_VARIANCE }
|
val thereIsOut = arguments.any { it.projectionKind == Variance.OUT_VARIANCE }
|
||||||
val thereIsIn = arguments.any { it.projectionKind == Variance.IN_VARIANCE }
|
val thereIsIn = arguments.any { it.projectionKind == Variance.IN_VARIANCE }
|
||||||
if (thereIsOut) {
|
if (thereIsOut) {
|
||||||
if (thereIsIn) {
|
if (thereIsIn) {
|
||||||
// CS(Inv<out X>, Inv<in Y>) = Inv<*>
|
// CS(Inv<out X>, Inv<in Y>) = Inv<*>
|
||||||
return StarProjectionImpl(parameter)
|
return StarProjectionImpl(parameter)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
asOut = true
|
asOut = true
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
asOut = !thereIsIn
|
asOut = !thereIsIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,11 +208,16 @@ object NewCommonSuperTypeCalculator {
|
|||||||
// CS(In<X>, In<Y>) = In<X & Y>
|
// CS(In<X>, In<Y>) = In<X & Y>
|
||||||
if (asOut) {
|
if (asOut) {
|
||||||
val type = commonSuperType(arguments.map { it.type.unwrap() }, depth + 1)
|
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)
|
return if (parameter.variance != Variance.INVARIANT) return type.asTypeProjection() else TypeProjectionImpl(
|
||||||
}
|
Variance.OUT_VARIANCE,
|
||||||
else {
|
type
|
||||||
|
)
|
||||||
|
} else {
|
||||||
val type = intersectTypes(arguments.map { it.type.unwrap() })
|
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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-2
@@ -79,10 +79,20 @@ class AdditionalDiagnosticReporter(private val languageVersionSettings: Language
|
|||||||
diagnostics: Collection<KotlinCallDiagnostic>
|
diagnostics: Collection<KotlinCallDiagnostic>
|
||||||
) {
|
) {
|
||||||
kotlinDiagnosticsHolder.addDiagnosticIfNotNull(
|
kotlinDiagnosticsHolder.addDiagnosticIfNotNull(
|
||||||
reportSmartCastOnReceiver(candidate, candidate.extensionReceiverArgument, resultingDescriptor.extensionReceiverParameter, diagnostics)
|
reportSmartCastOnReceiver(
|
||||||
|
candidate,
|
||||||
|
candidate.extensionReceiverArgument,
|
||||||
|
resultingDescriptor.extensionReceiverParameter,
|
||||||
|
diagnostics
|
||||||
|
)
|
||||||
)
|
)
|
||||||
kotlinDiagnosticsHolder.addDiagnosticIfNotNull(
|
kotlinDiagnosticsHolder.addDiagnosticIfNotNull(
|
||||||
reportSmartCastOnReceiver(candidate, candidate.dispatchReceiverArgument, resultingDescriptor.dispatchReceiverParameter, diagnostics)
|
reportSmartCastOnReceiver(
|
||||||
|
candidate,
|
||||||
|
candidate.dispatchReceiverArgument,
|
||||||
|
resultingDescriptor.dispatchReceiverParameter,
|
||||||
|
diagnostics
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
for (parameter in resultingDescriptor.valueParameters) {
|
for (parameter in resultingDescriptor.valueParameters) {
|
||||||
|
|||||||
+5
-10
@@ -48,8 +48,7 @@ class ArgumentsToParametersMapper {
|
|||||||
// optimization for case of variable
|
// optimization for case of variable
|
||||||
if (argumentsInParenthesis.isEmpty() && externalArgument == null && descriptor.valueParameters.isEmpty()) {
|
if (argumentsInParenthesis.isEmpty() && externalArgument == null && descriptor.valueParameters.isEmpty()) {
|
||||||
return EmptyArgumentMapping
|
return EmptyArgumentMapping
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val processor = CallArgumentProcessor(descriptor)
|
val processor = CallArgumentProcessor(descriptor)
|
||||||
processor.processArgumentsInParenthesis(argumentsInParenthesis)
|
processor.processArgumentsInParenthesis(argumentsInParenthesis)
|
||||||
|
|
||||||
@@ -171,8 +170,7 @@ class ArgumentsToParametersMapper {
|
|||||||
return valueParameter
|
return valueParameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
parameter.getOverriddenParameterWithOtherName()?.let {
|
parameter.getOverriddenParameterWithOtherName()?.let {
|
||||||
addDiagnostic(NameForAmbiguousParameter(argument, parameter, it))
|
addDiagnostic(NameForAmbiguousParameter(argument, parameter, it))
|
||||||
}
|
}
|
||||||
@@ -237,8 +235,7 @@ class ArgumentsToParametersMapper {
|
|||||||
if (!parameter.isVararg) {
|
if (!parameter.isVararg) {
|
||||||
if (resolvedArgument !is ResolvedCallArgument.SimpleArgument) {
|
if (resolvedArgument !is ResolvedCallArgument.SimpleArgument) {
|
||||||
error("Incorrect resolved argument for parameter $parameter :$resolvedArgument")
|
error("Incorrect resolved argument for parameter $parameter :$resolvedArgument")
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (resolvedArgument.callArgument.isSpread) {
|
if (resolvedArgument.callArgument.isSpread) {
|
||||||
addDiagnostic(NonVarargSpread(resolvedArgument.callArgument))
|
addDiagnostic(NonVarargSpread(resolvedArgument.callArgument))
|
||||||
}
|
}
|
||||||
@@ -250,11 +247,9 @@ class ArgumentsToParametersMapper {
|
|||||||
if (!result.containsKey(parameter.original)) {
|
if (!result.containsKey(parameter.original)) {
|
||||||
if (parameter.hasDefaultValue()) {
|
if (parameter.hasDefaultValue()) {
|
||||||
result[parameter.original] = ResolvedCallArgument.DefaultArgument
|
result[parameter.original] = ResolvedCallArgument.DefaultArgument
|
||||||
}
|
} else if (parameter.isVararg) {
|
||||||
else if (parameter.isVararg) {
|
|
||||||
result[parameter.original] = ResolvedCallArgument.VarargArgument(emptyList())
|
result[parameter.original] = ResolvedCallArgument.VarargArgument(emptyList())
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
addDiagnostic(NoValueForParameter(parameter, descriptor))
|
addDiagnostic(NoValueForParameter(parameter, descriptor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -51,8 +51,7 @@ internal val ReceiverValueWithSmartCastInfo.stableType: UnwrappedType
|
|||||||
internal fun KotlinCallArgument.getExpectedType(parameter: ParameterDescriptor, languageVersionSettings: LanguageVersionSettings) =
|
internal fun KotlinCallArgument.getExpectedType(parameter: ParameterDescriptor, languageVersionSettings: LanguageVersionSettings) =
|
||||||
if (this.isSpread || this.isArrayAssignedAsNamedArgumentInAnnotation(parameter, languageVersionSettings)) {
|
if (this.isSpread || this.isArrayAssignedAsNamedArgumentInAnnotation(parameter, languageVersionSettings)) {
|
||||||
parameter.type.unwrap()
|
parameter.type.unwrap()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
parameter.safeAs<ValueParameterDescriptor>()?.varargElementType?.unwrap() ?: parameter.type.unwrap()
|
parameter.safeAs<ValueParameterDescriptor>()?.varargElementType?.unwrap() ?: parameter.type.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+52
-27
@@ -46,7 +46,8 @@ sealed class CallableReceiver(val receiver: ReceiverValueWithSmartCastInfo) {
|
|||||||
class UnboundReference(val qualifier: QualifierReceiver, receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
class UnboundReference(val qualifier: QualifierReceiver, receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||||
class BoundValueReference(val qualifier: QualifierReceiver, receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
class BoundValueReference(val qualifier: QualifierReceiver, receiver: ReceiverValueWithSmartCastInfo) : CallableReceiver(receiver)
|
||||||
class ScopeReceiver(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
|
// todo investigate similar code in CheckVisibility
|
||||||
@@ -132,8 +133,10 @@ fun ConstraintSystemOperation.checkCallableReference(
|
|||||||
addReceiverConstraint(toFreshSubstitutor, dispatchReceiver, candidateDescriptor.dispatchReceiverParameter, position)
|
addReceiverConstraint(toFreshSubstitutor, dispatchReceiver, candidateDescriptor.dispatchReceiverParameter, position)
|
||||||
addReceiverConstraint(toFreshSubstitutor, extensionReceiver, candidateDescriptor.extensionReceiverParameter, position)
|
addReceiverConstraint(toFreshSubstitutor, extensionReceiver, candidateDescriptor.extensionReceiverParameter, position)
|
||||||
|
|
||||||
val invisibleMember = Visibilities.findInvisibleMember(dispatchReceiver?.asReceiverValueForVisibilityChecks,
|
val invisibleMember = Visibilities.findInvisibleMember(
|
||||||
candidateDescriptor, ownerDescriptor)
|
dispatchReceiver?.asReceiverValueForVisibilityChecks,
|
||||||
|
candidateDescriptor, ownerDescriptor
|
||||||
|
)
|
||||||
return toFreshSubstitutor to invisibleMember?.let(::VisibilityError)
|
return toFreshSubstitutor to invisibleMember?.let(::VisibilityError)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +175,8 @@ class CallableReferencesCandidateFactory(
|
|||||||
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
): CallableReferenceCandidate {
|
): 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 extensionCallableReceiver = extensionReceiver?.let { toCallableReceiver(it, explicitReceiverKind == EXTENSION_RECEIVER) }
|
||||||
val candidateDescriptor = towerCandidate.descriptor
|
val candidateDescriptor = towerCandidate.descriptor
|
||||||
val diagnostics = SmartList<KotlinCallDiagnostic>()
|
val diagnostics = SmartList<KotlinCallDiagnostic>()
|
||||||
@@ -181,16 +185,19 @@ class CallableReferencesCandidateFactory(
|
|||||||
candidateDescriptor,
|
candidateDescriptor,
|
||||||
dispatchCallableReceiver,
|
dispatchCallableReceiver,
|
||||||
extensionCallableReceiver,
|
extensionCallableReceiver,
|
||||||
expectedType)
|
expectedType
|
||||||
|
)
|
||||||
|
|
||||||
if (defaults != 0) {
|
if (defaults != 0) {
|
||||||
diagnostics.add(CallableReferencesDefaultArgumentUsed(argument, candidateDescriptor, defaults))
|
diagnostics.add(CallableReferencesDefaultArgumentUsed(argument, candidateDescriptor, defaults))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (candidateDescriptor !is CallableMemberDescriptor) {
|
if (candidateDescriptor !is CallableMemberDescriptor) {
|
||||||
return CallableReferenceCandidate(candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver,
|
return CallableReferenceCandidate(
|
||||||
|
candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver,
|
||||||
explicitReceiverKind, reflectionCandidateType, defaults,
|
explicitReceiverKind, reflectionCandidateType, defaults,
|
||||||
listOf(NotCallableMemberReference(argument, candidateDescriptor)))
|
listOf(NotCallableMemberReference(argument, candidateDescriptor))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
diagnostics.addAll(towerCandidate.diagnostics)
|
diagnostics.addAll(towerCandidate.diagnostics)
|
||||||
@@ -201,15 +208,25 @@ class CallableReferencesCandidateFactory(
|
|||||||
|
|
||||||
val (_, visibilityError) = it.checkCallableReference(
|
val (_, visibilityError) = it.checkCallableReference(
|
||||||
argument, dispatchCallableReceiver, extensionCallableReceiver, candidateDescriptor,
|
argument, dispatchCallableReceiver, extensionCallableReceiver, candidateDescriptor,
|
||||||
reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor)
|
reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor
|
||||||
|
)
|
||||||
|
|
||||||
diagnostics.addIfNotNull(visibilityError)
|
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,
|
return CallableReferenceCandidate(
|
||||||
explicitReceiverKind, reflectionCandidateType, defaults, diagnostics)
|
candidateDescriptor, dispatchCallableReceiver, extensionCallableReceiver,
|
||||||
|
explicitReceiverKind, reflectionCandidateType, defaults, diagnostics
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getArgumentAndReturnTypeUseMappingByExpectedType(
|
private fun getArgumentAndReturnTypeUseMappingByExpectedType(
|
||||||
@@ -223,7 +240,8 @@ class CallableReferencesCandidateFactory(
|
|||||||
if (expectedArgumentCount < 0) return null
|
if (expectedArgumentCount < 0) return null
|
||||||
|
|
||||||
val fakeArguments = (0..(expectedArgumentCount - 1)).map { FakeKotlinCallArgumentForCallableReference(it) }
|
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
|
if (argumentMapping.diagnostics.any { !it.candidateApplicability.isSuccess }) return null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -274,24 +292,32 @@ class CallableReferencesCandidateFactory(
|
|||||||
is PropertyDescriptor -> {
|
is PropertyDescriptor -> {
|
||||||
val mutable = descriptor.isVar && run {
|
val mutable = descriptor.isVar && run {
|
||||||
val setter = descriptor.setter
|
val setter = descriptor.setter
|
||||||
setter == null || Visibilities.isVisible(dispatchReceiver?.asReceiverValueForVisibilityChecks, setter,
|
setter == null || Visibilities.isVisible(
|
||||||
scopeTower.lexicalScope.ownerDescriptor)
|
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 -> {
|
is FunctionDescriptor -> {
|
||||||
val returnType: KotlinType
|
val returnType: KotlinType
|
||||||
val defaults: Int
|
val defaults: Int
|
||||||
val argumentsAndExpectedTypeCoercion = getArgumentAndReturnTypeUseMappingByExpectedType(descriptor, expectedType,
|
val argumentsAndExpectedTypeCoercion = getArgumentAndReturnTypeUseMappingByExpectedType(
|
||||||
unboundReceiverCount = argumentsAndReceivers.size)
|
descriptor, expectedType,
|
||||||
|
unboundReceiverCount = argumentsAndReceivers.size
|
||||||
|
)
|
||||||
|
|
||||||
if (argumentsAndExpectedTypeCoercion == null) {
|
if (argumentsAndExpectedTypeCoercion == null) {
|
||||||
descriptor.valueParameters.mapTo(argumentsAndReceivers) { it.type }
|
descriptor.valueParameters.mapTo(argumentsAndReceivers) { it.type }
|
||||||
returnType = descriptorReturnType
|
returnType = descriptorReturnType
|
||||||
defaults = 0
|
defaults = 0
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val (arguments, coercion) = argumentsAndExpectedTypeCoercion
|
val (arguments, coercion) = argumentsAndExpectedTypeCoercion
|
||||||
defaults = argumentsAndExpectedTypeCoercion.third
|
defaults = argumentsAndExpectedTypeCoercion.third
|
||||||
argumentsAndReceivers.addAll(arguments)
|
argumentsAndReceivers.addAll(arguments)
|
||||||
@@ -299,8 +325,10 @@ class CallableReferencesCandidateFactory(
|
|||||||
returnType = if (coercion == CoercionStrategy.COERCION_TO_UNIT) descriptor.builtIns.unitType else descriptorReturnType
|
returnType = if (coercion == CoercionStrategy.COERCION_TO_UNIT) descriptor.builtIns.unitType else descriptorReturnType
|
||||||
}
|
}
|
||||||
|
|
||||||
return callComponents.reflectionTypes.getKFunctionType(Annotations.EMPTY, null, argumentsAndReceivers, null,
|
return callComponents.reflectionTypes.getKFunctionType(
|
||||||
returnType, descriptor.builtIns) to defaults
|
Annotations.EMPTY, null, argumentsAndReceivers, null,
|
||||||
|
returnType, descriptor.builtIns
|
||||||
|
) to defaults
|
||||||
}
|
}
|
||||||
else -> error("Unsupported descriptor type: $descriptor")
|
else -> error("Unsupported descriptor type: $descriptor")
|
||||||
}
|
}
|
||||||
@@ -315,8 +343,7 @@ class CallableReferencesCandidateFactory(
|
|||||||
is LHSResult.Type -> {
|
is LHSResult.Type -> {
|
||||||
if (lhsResult.qualifier.classValueReceiver?.type == receiver.receiverValue.type) {
|
if (lhsResult.qualifier.classValueReceiver?.type == receiver.receiverValue.type) {
|
||||||
CallableReceiver.BoundValueReference(lhsResult.qualifier, receiver)
|
CallableReceiver.BoundValueReference(lhsResult.qualifier, receiver)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
CallableReceiver.UnboundReference(lhsResult.qualifier, receiver)
|
CallableReceiver.UnboundReference(lhsResult.qualifier, receiver)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,11 +358,9 @@ fun getFunctionTypeFromCallableReferenceExpectedType(expectedType: UnwrappedType
|
|||||||
|
|
||||||
return if (expectedType.isFunctionType) {
|
return if (expectedType.isFunctionType) {
|
||||||
expectedType
|
expectedType
|
||||||
}
|
} else if (ReflectionTypes.isNumberedKFunction(expectedType)) {
|
||||||
else if (ReflectionTypes.isNumberedKFunction(expectedType)) {
|
|
||||||
expectedType.immediateSupertypes().first { it.isFunctionType }.unwrap()
|
expectedType.immediateSupertypes().first { it.isFunctionType }.unwrap()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+10
-9
@@ -44,7 +44,7 @@ class CallableReferenceOverloadConflictResolver(
|
|||||||
Companion::createFlatSignature,
|
Companion::createFlatSignature,
|
||||||
{ null },
|
{ null },
|
||||||
{ statelessCallbacks.isDescriptorFromSource(it) }
|
{ statelessCallbacks.isDescriptorFromSource(it) }
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
private fun createFlatSignature(candidate: CallableReferenceCandidate) =
|
private fun createFlatSignature(candidate: CallableReferenceCandidate) =
|
||||||
FlatSignature.createFromReflectionType(candidate, candidate.candidate, candidate.numDefaults, candidate.reflectionCandidateType)
|
FlatSignature.createFromReflectionType(candidate, candidate.candidate, candidate.numDefaults, candidate.reflectionCandidateType)
|
||||||
@@ -73,17 +73,17 @@ class CallableReferenceResolver(
|
|||||||
val chosenCandidate = candidates.singleOrNull()
|
val chosenCandidate = candidates.singleOrNull()
|
||||||
if (chosenCandidate != null) {
|
if (chosenCandidate != null) {
|
||||||
val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) {
|
val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) {
|
||||||
csBuilder.checkCallableReference(argument, dispatchReceiver, extensionReceiver, candidate,
|
csBuilder.checkCallableReference(
|
||||||
reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor)
|
argument, dispatchReceiver, extensionReceiver, candidate,
|
||||||
|
reflectionCandidateType, expectedType, scopeTower.lexicalScope.ownerDescriptor
|
||||||
|
)
|
||||||
}
|
}
|
||||||
diagnosticsHolder.addDiagnosticIfNotNull(diagnostic)
|
diagnosticsHolder.addDiagnosticIfNotNull(diagnostic)
|
||||||
chosenCandidate.freshSubstitutor = toFreshSubstitutor
|
chosenCandidate.freshSubstitutor = toFreshSubstitutor
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (candidates.isEmpty()) {
|
if (candidates.isEmpty()) {
|
||||||
diagnosticsHolder.addDiagnostic(NoneCallableReferenceCandidates(argument))
|
diagnosticsHolder.addDiagnostic(NoneCallableReferenceCandidates(argument))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
diagnosticsHolder.addDiagnostic(CallableReferenceCandidatesAmbiguity(argument, candidates))
|
diagnosticsHolder.addDiagnostic(CallableReferenceCandidatesAmbiguity(argument, candidates))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ class CallableReferenceResolver(
|
|||||||
private fun buildResolvedKtArgument(lhsResult: LHSResult): ResolvedAtom? {
|
private fun buildResolvedKtArgument(lhsResult: LHSResult): ResolvedAtom? {
|
||||||
if (lhsResult !is LHSResult.Expression) return null
|
if (lhsResult !is LHSResult.Expression) return null
|
||||||
val lshCallArgument = lhsResult.lshCallArgument
|
val lshCallArgument = lhsResult.lshCallArgument
|
||||||
return when(lshCallArgument) {
|
return when (lshCallArgument) {
|
||||||
is SubKotlinCallArgument -> lshCallArgument.callResult
|
is SubKotlinCallArgument -> lshCallArgument.callResult
|
||||||
is ExpressionKotlinCallArgument -> ResolvedExpressionAtom(lshCallArgument)
|
is ExpressionKotlinCallArgument -> ResolvedExpressionAtom(lshCallArgument)
|
||||||
else -> unexpectedArgument(lshCallArgument)
|
else -> unexpectedArgument(lshCallArgument)
|
||||||
@@ -117,7 +117,8 @@ class CallableReferenceResolver(
|
|||||||
candidates,
|
candidates,
|
||||||
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||||
discriminateGenerics = false, // we can't specify generics explicitly for callable references
|
discriminateGenerics = false, // we can't specify generics explicitly for callable references
|
||||||
isDebuggerContext = scopeTower.isDebuggerContext)
|
isDebuggerContext = scopeTower.isDebuggerContext
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-8
@@ -54,7 +54,13 @@ class KotlinCallCompleter(
|
|||||||
if (candidate == null || candidate.csBuilder.hasContradiction) {
|
if (candidate == null || candidate.csBuilder.hasContradiction) {
|
||||||
val candidateForCompletion = candidate ?: factory.createErrorCandidate().forceResolution()
|
val candidateForCompletion = candidate ?: factory.createErrorCandidate().forceResolution()
|
||||||
candidateForCompletion.prepareForCompletion(expectedType, resolutionCallbacks)
|
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
|
val systemStorage = candidate?.getSystem()?.asReadOnlyStorage() ?: ConstraintStorage.Empty
|
||||||
return CallResolutionResult(
|
return CallResolutionResult(
|
||||||
@@ -76,8 +82,7 @@ class KotlinCallCompleter(
|
|||||||
diagnosticHolder.getDiagnostics() + diagnosticsFromResolutionParts,
|
diagnosticHolder.getDiagnostics() + diagnosticsFromResolutionParts,
|
||||||
constraintSystem.asReadOnlyStorage()
|
constraintSystem.asReadOnlyStorage()
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
CallResolutionResult(
|
CallResolutionResult(
|
||||||
CallResolutionResult.Type.PARTIAL,
|
CallResolutionResult.Type.PARTIAL,
|
||||||
candidate.resolvedCall,
|
candidate.resolvedCall,
|
||||||
@@ -101,7 +106,8 @@ class KotlinCallCompleter(
|
|||||||
diagnosticsHolder,
|
diagnosticsHolder,
|
||||||
candidate.getSystem(),
|
candidate.getSystem(),
|
||||||
resolutionCallbacks,
|
resolutionCallbacks,
|
||||||
skipPostponedArguments = true)
|
skipPostponedArguments = true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return CallResolutionResult(CallResolutionResult.Type.ALL_CANDIDATES, null, emptyList(), ConstraintStorage.Empty, candidates)
|
return CallResolutionResult(CallResolutionResult.Type.ALL_CANDIDATES, null, emptyList(), ConstraintStorage.Empty, candidates)
|
||||||
}
|
}
|
||||||
@@ -115,7 +121,12 @@ class KotlinCallCompleter(
|
|||||||
skipPostponedArguments: Boolean = false
|
skipPostponedArguments: Boolean = false
|
||||||
) {
|
) {
|
||||||
val returnType = resolvedCallAtom.freshReturnType ?: constraintSystem.builtIns.unitType
|
val returnType = resolvedCallAtom.freshReturnType ?: constraintSystem.builtIns.unitType
|
||||||
kotlinConstraintSystemCompleter.runCompletion(constraintSystem.asConstraintSystemCompleterContext(), completionMode, resolvedCallAtom, returnType) {
|
kotlinConstraintSystemCompleter.runCompletion(
|
||||||
|
constraintSystem.asConstraintSystemCompleterContext(),
|
||||||
|
completionMode,
|
||||||
|
resolvedCallAtom,
|
||||||
|
returnType
|
||||||
|
) {
|
||||||
if (!skipPostponedArguments) {
|
if (!skipPostponedArguments) {
|
||||||
postponedArgumentsAnalyzer.analyze(
|
postponedArgumentsAnalyzer.analyze(
|
||||||
constraintSystem.asPostponedArgumentsAnalyzerContext(),
|
constraintSystem.asPostponedArgumentsAnalyzerContext(),
|
||||||
@@ -141,14 +152,16 @@ class KotlinCallCompleter(
|
|||||||
val actualType = withSmartCastInfo?.stableType ?: unsubstitutedReturnType
|
val actualType = withSmartCastInfo?.stableType ?: unsubstitutedReturnType
|
||||||
|
|
||||||
val returnType = resolvedCall.substitutor.substituteKeepAnnotations(actualType)
|
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))
|
csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPosition(resolvedCall.atom))
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (expectedType != null || csBuilder.isProperType(returnType)) {
|
return if (expectedType != null || csBuilder.isProperType(returnType)) {
|
||||||
ConstraintSystemCompletionMode.FULL
|
ConstraintSystemCompletionMode.FULL
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ConstraintSystemCompletionMode.PARTIAL
|
ConstraintSystemCompletionMode.PARTIAL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -57,8 +57,7 @@ class NewOverloadingConflictResolver(
|
|||||||
for ((valueParameter, resolvedValueArgument) in resolvedCall.argumentMappingByOriginal) {
|
for ((valueParameter, resolvedValueArgument) in resolvedCall.argumentMappingByOriginal) {
|
||||||
if (resolvedValueArgument is ResolvedCallArgument.DefaultArgument) {
|
if (resolvedValueArgument is ResolvedCallArgument.DefaultArgument) {
|
||||||
numDefaults++
|
numDefaults++
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val originalValueParameter = originalValueParameters[valueParameter.index]
|
val originalValueParameter = originalValueParameters[valueParameter.index]
|
||||||
val parameterType = originalValueParameter.argumentValueType
|
val parameterType = originalValueParameter.argumentValueType
|
||||||
for (valueArgument in resolvedValueArgument.arguments) {
|
for (valueArgument in resolvedValueArgument.arguments) {
|
||||||
|
|||||||
+17
-7
@@ -55,8 +55,10 @@ private fun preprocessLambdaArgument(
|
|||||||
val resolvedArgument = extractLambdaInfoFromFunctionalType(expectedType, argument) ?: extraLambdaInfo(expectedType, argument, csBuilder)
|
val resolvedArgument = extractLambdaInfoFromFunctionalType(expectedType, argument) ?: extraLambdaInfo(expectedType, argument, csBuilder)
|
||||||
|
|
||||||
if (expectedType != null) {
|
if (expectedType != null) {
|
||||||
val lambdaType = createFunctionType(csBuilder.builtIns, Annotations.EMPTY, resolvedArgument.receiver,
|
val lambdaType = createFunctionType(
|
||||||
resolvedArgument.parameters, null, resolvedArgument.returnType, resolvedArgument.isSuspend)
|
csBuilder.builtIns, Annotations.EMPTY, resolvedArgument.receiver,
|
||||||
|
resolvedArgument.parameters, null, resolvedArgument.returnType, resolvedArgument.isSuspend
|
||||||
|
)
|
||||||
csBuilder.addSubtypeConstraint(lambdaType, expectedType, ArgumentConstraintPosition(argument))
|
csBuilder.addSubtypeConstraint(lambdaType, expectedType, ArgumentConstraintPosition(argument))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,9 +79,9 @@ private fun extraLambdaInfo(
|
|||||||
val typeVariable = TypeVariableForLambdaReturnType(argument, builtIns, "_L")
|
val typeVariable = TypeVariableForLambdaReturnType(argument, builtIns, "_L")
|
||||||
|
|
||||||
val receiverType = argumentAsFunctionExpression?.receiverType
|
val receiverType = argumentAsFunctionExpression?.receiverType
|
||||||
val returnType = argumentAsFunctionExpression?.returnType ?:
|
val returnType =
|
||||||
expectedType?.arguments?.singleOrNull()?.type?.unwrap()?.takeIf { isFunctionSupertype } ?:
|
argumentAsFunctionExpression?.returnType ?: expectedType?.arguments?.singleOrNull()?.type?.unwrap()?.takeIf { isFunctionSupertype }
|
||||||
typeVariable.defaultType
|
?: typeVariable.defaultType
|
||||||
|
|
||||||
val parameters = argument.parametersTypes?.map { it ?: builtIns.nothingType } ?: emptyList()
|
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 receiverType = argumentAsFunctionExpression?.receiverType ?: expectedType.getReceiverTypeFromFunctionType()?.unwrap()
|
||||||
val returnType = argumentAsFunctionExpression?.returnType ?: expectedType.getReturnTypeFromFunctionType().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<UnwrappedType> {
|
private fun extractLambdaParameters(expectedType: UnwrappedType, argument: LambdaKotlinCallArgument): List<UnwrappedType> {
|
||||||
@@ -130,7 +139,8 @@ private fun preprocessCallableReference(
|
|||||||
val result = ResolvedCallableReferenceAtom(argument, expectedType)
|
val result = ResolvedCallableReferenceAtom(argument, expectedType)
|
||||||
if (expectedType == null) return result
|
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) {
|
if (notCallableTypeConstructor != null) {
|
||||||
diagnosticsHolder.addDiagnostic(NotCallableExpectedType(argument, expectedType, notCallableTypeConstructor))
|
diagnosticsHolder.addDiagnostic(NotCallableExpectedType(argument, expectedType, notCallableTypeConstructor))
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-3
@@ -36,10 +36,16 @@ class PostponedArgumentsAnalyzer(
|
|||||||
|
|
||||||
// mutable operations
|
// mutable operations
|
||||||
fun addOtherSystem(otherSystem: ConstraintStorage)
|
fun addOtherSystem(otherSystem: ConstraintStorage)
|
||||||
|
|
||||||
fun getBuilder(): ConstraintSystemBuilder
|
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) {
|
when (argument) {
|
||||||
is ResolvedLambdaAtom ->
|
is ResolvedLambdaAtom ->
|
||||||
analyzeLambda(c, resolutionCallbacks, argument, diagnosticsHolder)
|
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()
|
val currentSubstitutor = c.buildCurrentSubstitutor()
|
||||||
fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(type)
|
fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(type)
|
||||||
|
|
||||||
@@ -64,7 +75,8 @@ class PostponedArgumentsAnalyzer(
|
|||||||
val parameters = lambda.parameters.map(::substitute)
|
val parameters = lambda.parameters.map(::substitute)
|
||||||
val expectedType = lambda.returnType.takeIf { c.canBeProper(it) }?.let(::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) }
|
returnArguments.forEach { c.addSubsystemFromArgument(it) }
|
||||||
|
|
||||||
|
|||||||
+30
-9
@@ -55,12 +55,19 @@ internal object CheckVisibility : ResolutionPart() {
|
|||||||
if (scopeTower.isDebuggerContext) return
|
if (scopeTower.isDebuggerContext) return
|
||||||
|
|
||||||
val receiverValue = dispatchReceiverArgument?.receiver?.receiverValue ?: Visibilities.ALWAYS_SUITABLE_RECEIVER
|
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) {
|
if (dispatchReceiverArgument is ExpressionKotlinCallArgument) {
|
||||||
val smartCastReceiver = getReceiverValueWithSmartCast(receiverValue, dispatchReceiverArgument.receiver.stableType)
|
val smartCastReceiver = getReceiverValueWithSmartCast(receiverValue, dispatchReceiverArgument.receiver.stableType)
|
||||||
if (Visibilities.findInvisibleMember(smartCastReceiver, candidateDescriptor, containingDescriptor) == null) {
|
if (Visibilities.findInvisibleMember(smartCastReceiver, candidateDescriptor, containingDescriptor) == null) {
|
||||||
addDiagnostic(SmartCastDiagnostic(dispatchReceiverArgument, dispatchReceiverArgument.receiver.stableType, resolvedCall.atom))
|
addDiagnostic(
|
||||||
|
SmartCastDiagnostic(
|
||||||
|
dispatchReceiverArgument,
|
||||||
|
dispatchReceiverArgument.receiver.stableType,
|
||||||
|
resolvedCall.atom
|
||||||
|
)
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,16 +154,23 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
|||||||
|
|
||||||
val knownTypeArgument = knownTypeParametersResultingSubstitutor?.substitute(typeParameter.defaultType)
|
val knownTypeArgument = knownTypeParametersResultingSubstitutor?.substitute(typeParameter.defaultType)
|
||||||
if (knownTypeArgument != null) {
|
if (knownTypeArgument != null) {
|
||||||
csBuilder.addEqualityConstraint(freshVariable.defaultType, knownTypeArgument.unwrap(), KnownTypeParameterConstraintPosition(knownTypeArgument))
|
csBuilder.addEqualityConstraint(
|
||||||
|
freshVariable.defaultType,
|
||||||
|
knownTypeArgument.unwrap(),
|
||||||
|
KnownTypeParameterConstraintPosition(knownTypeArgument)
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val typeArgument = resolvedCall.typeArgumentMappingByOriginal.getTypeArgument(typeParameter)
|
val typeArgument = resolvedCall.typeArgumentMappingByOriginal.getTypeArgument(typeParameter)
|
||||||
|
|
||||||
if (typeArgument is SimpleTypeArgument) {
|
if (typeArgument is SimpleTypeArgument) {
|
||||||
csBuilder.addEqualityConstraint(freshVariable.defaultType, typeArgument.type, ExplicitTypeParameterConstraintPosition(typeArgument))
|
csBuilder.addEqualityConstraint(
|
||||||
}
|
freshVariable.defaultType,
|
||||||
else {
|
typeArgument.type,
|
||||||
|
ExplicitTypeParameterConstraintPosition(typeArgument)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
assert(typeArgument == TypeArgumentPlaceholder) {
|
assert(typeArgument == TypeArgumentPlaceholder) {
|
||||||
"Unexpected typeArgument: $typeArgument, ${typeArgument.javaClass.canonicalName}"
|
"Unexpected typeArgument: $typeArgument, ${typeArgument.javaClass.canonicalName}"
|
||||||
}
|
}
|
||||||
@@ -193,9 +207,11 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
|||||||
|
|
||||||
internal object CheckExplicitReceiverKindConsistency : ResolutionPart() {
|
internal object CheckExplicitReceiverKindConsistency : ResolutionPart() {
|
||||||
private fun KotlinResolutionCandidate.hasError(): Nothing =
|
private fun KotlinResolutionCandidate.hasError(): Nothing =
|
||||||
error("Inconsistent call: $kotlinCall. \n" +
|
error(
|
||||||
|
"Inconsistent call: $kotlinCall. \n" +
|
||||||
"Candidate: $candidateDescriptor, explicitReceiverKind: ${resolvedCall.explicitReceiverKind}.\n" +
|
"Candidate: $candidateDescriptor, explicitReceiverKind: ${resolvedCall.explicitReceiverKind}.\n" +
|
||||||
"Explicit receiver: ${kotlinCall.explicitReceiver}, dispatchReceiverForInvokeExtension: ${kotlinCall.dispatchReceiverForInvokeExtension}")
|
"Explicit receiver: ${kotlinCall.explicitReceiver}, dispatchReceiverForInvokeExtension: ${kotlinCall.dispatchReceiverForInvokeExtension}"
|
||||||
|
)
|
||||||
|
|
||||||
override fun KotlinResolutionCandidate.process(workIndex: Int) {
|
override fun KotlinResolutionCandidate.process(workIndex: Int) {
|
||||||
when (resolvedCall.explicitReceiverKind) {
|
when (resolvedCall.explicitReceiverKind) {
|
||||||
@@ -212,7 +228,12 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument(
|
|||||||
isReceiver: Boolean
|
isReceiver: Boolean
|
||||||
) {
|
) {
|
||||||
val expectedType = candidateParameter?.let {
|
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))
|
addResolvedKtPrimitive(resolveKtPrimitive(csBuilder, argument, expectedType, this, isReceiver))
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-6
@@ -74,25 +74,30 @@ private fun checkExpressionArgument(
|
|||||||
if (expressionArgument.isSafeCall) {
|
if (expressionArgument.isSafeCall) {
|
||||||
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
|
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
|
||||||
diagnosticsHolder.addDiagnosticIfNotNull(
|
diagnosticsHolder.addDiagnosticIfNotNull(
|
||||||
unstableSmartCastOrSubtypeError(expressionArgument.receiver.unstableType, expectedNullableType, position))
|
unstableSmartCastOrSubtypeError(expressionArgument.receiver.unstableType, expectedNullableType, position)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return resolvedKtExpression
|
return resolvedKtExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedType, position)) {
|
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedType, position)) {
|
||||||
if (!isReceiver) {
|
if (!isReceiver) {
|
||||||
diagnosticsHolder.addDiagnosticIfNotNull(unstableSmartCastOrSubtypeError(expressionArgument.receiver.unstableType, expectedType, position))
|
diagnosticsHolder.addDiagnosticIfNotNull(
|
||||||
|
unstableSmartCastOrSubtypeError(
|
||||||
|
expressionArgument.receiver.unstableType,
|
||||||
|
expectedType,
|
||||||
|
position
|
||||||
|
)
|
||||||
|
)
|
||||||
return resolvedKtExpression
|
return resolvedKtExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
val unstableType = expressionArgument.receiver.unstableType
|
val unstableType = expressionArgument.receiver.unstableType
|
||||||
if (unstableType != null && csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
|
if (unstableType != null && csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
|
||||||
diagnosticsHolder.addDiagnostic(UnstableSmartCast(expressionArgument, unstableType))
|
diagnosticsHolder.addDiagnostic(UnstableSmartCast(expressionArgument, unstableType))
|
||||||
}
|
} else if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
|
||||||
else if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) {
|
|
||||||
diagnosticsHolder.addDiagnostic(UnsafeCallError(expressionArgument))
|
diagnosticsHolder.addDiagnostic(UnsafeCallError(expressionArgument))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
csBuilder.addSubtypeConstraint(argumentType, expectedType, position)
|
csBuilder.addSubtypeConstraint(argumentType, expectedType, position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -35,7 +35,7 @@ class TypeArgumentsToParametersMapper {
|
|||||||
class TypeArgumentsMappingImpl(
|
class TypeArgumentsMappingImpl(
|
||||||
diagnostics: List<KotlinCallDiagnostic>,
|
diagnostics: List<KotlinCallDiagnostic>,
|
||||||
private val typeParameterToArgumentMap: Map<TypeParameterDescriptor, TypeArgument>
|
private val typeParameterToArgumentMap: Map<TypeParameterDescriptor, TypeArgument>
|
||||||
): TypeArgumentsMapping(diagnostics) {
|
) : TypeArgumentsMapping(diagnostics) {
|
||||||
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument =
|
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) {
|
if (call.typeArguments.size != descriptor.typeParameters.size) {
|
||||||
return TypeArgumentsMapping.TypeArgumentsMappingImpl(
|
return TypeArgumentsMapping.TypeArgumentsMappingImpl(
|
||||||
listOf(WrongCountOfTypeArguments(descriptor, call.typeArguments.size)), emptyMap())
|
listOf(WrongCountOfTypeArguments(descriptor, call.typeArguments.size)), emptyMap()
|
||||||
}
|
)
|
||||||
else {
|
} else {
|
||||||
val typeParameterToArgumentMap = descriptor.typeParameters.zip(call.typeArguments).associate { it }
|
val typeParameterToArgumentMap = descriptor.typeParameters.zip(call.typeArguments).associate { it }
|
||||||
return TypeArgumentsMapping.TypeArgumentsMappingImpl(listOf(), typeParameterToArgumentMap)
|
return TypeArgumentsMapping.TypeArgumentsMappingImpl(listOf(), typeParameterToArgumentMap)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -47,7 +47,11 @@ interface ConstraintSystemBuilder : ConstraintSystemOperation {
|
|||||||
fun buildCurrentSubstitutor(): NewTypeSubstitutor
|
fun buildCurrentSubstitutor(): NewTypeSubstitutor
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible(lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition) =
|
fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible(
|
||||||
|
lowerType: UnwrappedType,
|
||||||
|
upperType: UnwrappedType,
|
||||||
|
position: ConstraintPosition
|
||||||
|
) =
|
||||||
runTransaction {
|
runTransaction {
|
||||||
if (!hasContradiction) addSubtypeConstraint(lowerType, upperType, position)
|
if (!hasContradiction) addSubtypeConstraint(lowerType, upperType, position)
|
||||||
!hasContradiction
|
!hasContradiction
|
||||||
|
|||||||
+6
-3
@@ -33,7 +33,10 @@ fun ConstraintStorage.buildResultingSubstitutor(): NewTypeSubstitutor {
|
|||||||
it.key to it.value
|
it.key to it.value
|
||||||
}
|
}
|
||||||
val uninferredSubstitutorMap = notFixedTypeVariables.entries.associate { (freshTypeConstructor, typeVariable) ->
|
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)
|
return NewTypeSubstitutorByConstructorMap(currentSubstitutorMap + uninferredSubstitutorMap)
|
||||||
@@ -62,8 +65,8 @@ fun CallableDescriptor.substituteAndApproximateCapturedTypes(substitutor: NewTyp
|
|||||||
|
|
||||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
||||||
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
|
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
|
||||||
TypeApproximator().approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedTypesApproximation) ?:
|
TypeApproximator().approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedTypesApproximation)
|
||||||
substitutedType
|
?: substitutedType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -32,6 +32,7 @@ interface NewConstraintSystem {
|
|||||||
|
|
||||||
// after this method we shouldn't mutate system via ConstraintSystemBuilder
|
// after this method we shouldn't mutate system via ConstraintSystemBuilder
|
||||||
fun asReadOnlyStorage(): ConstraintStorage
|
fun asReadOnlyStorage(): ConstraintStorage
|
||||||
|
|
||||||
fun asConstraintSystemCompleterContext(): KotlinConstraintSystemCompleter.Context
|
fun asConstraintSystemCompleterContext(): KotlinConstraintSystemCompleter.Context
|
||||||
fun asPostponedArgumentsAnalyzerContext(): PostponedArgumentsAnalyzer.Context
|
fun asPostponedArgumentsAnalyzerContext(): PostponedArgumentsAnalyzer.Context
|
||||||
}
|
}
|
||||||
+16
-8
@@ -113,19 +113,27 @@ class ConstraintIncorporator(val typeApproximator: TypeApproximator) {
|
|||||||
baseConstraint.type.substitute(otherVariable, otherConstraint.type)
|
baseConstraint.type.substitute(otherVariable, otherConstraint.type)
|
||||||
}
|
}
|
||||||
ConstraintKind.UPPER -> {
|
ConstraintKind.UPPER -> {
|
||||||
val newCapturedTypeConstructor = NewCapturedTypeConstructor(TypeProjectionImpl(Variance.OUT_VARIANCE, otherConstraint.type),
|
val newCapturedTypeConstructor = NewCapturedTypeConstructor(
|
||||||
listOf(otherConstraint.type))
|
TypeProjectionImpl(Variance.OUT_VARIANCE, otherConstraint.type),
|
||||||
val temporaryCapturedType = NewCapturedType(CaptureStatus.FOR_INCORPORATION,
|
listOf(otherConstraint.type)
|
||||||
|
)
|
||||||
|
val temporaryCapturedType = NewCapturedType(
|
||||||
|
CaptureStatus.FOR_INCORPORATION,
|
||||||
newCapturedTypeConstructor,
|
newCapturedTypeConstructor,
|
||||||
lowerType = null)
|
lowerType = null
|
||||||
|
)
|
||||||
baseConstraint.type.substitute(otherVariable, temporaryCapturedType)
|
baseConstraint.type.substitute(otherVariable, temporaryCapturedType)
|
||||||
}
|
}
|
||||||
ConstraintKind.LOWER -> {
|
ConstraintKind.LOWER -> {
|
||||||
val newCapturedTypeConstructor = NewCapturedTypeConstructor(TypeProjectionImpl(Variance.IN_VARIANCE, otherConstraint.type),
|
val newCapturedTypeConstructor = NewCapturedTypeConstructor(
|
||||||
emptyList())
|
TypeProjectionImpl(Variance.IN_VARIANCE, otherConstraint.type),
|
||||||
val temporaryCapturedType = NewCapturedType(CaptureStatus.FOR_INCORPORATION,
|
emptyList()
|
||||||
|
)
|
||||||
|
val temporaryCapturedType = NewCapturedType(
|
||||||
|
CaptureStatus.FOR_INCORPORATION,
|
||||||
newCapturedTypeConstructor,
|
newCapturedTypeConstructor,
|
||||||
lowerType = otherConstraint.type)
|
lowerType = otherConstraint.type
|
||||||
|
)
|
||||||
baseConstraint.type.substitute(otherVariable, temporaryCapturedType)
|
baseConstraint.type.substitute(otherVariable, temporaryCapturedType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-7
@@ -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<Pair<NewTypeVariable, Constraint>>()
|
val possibleNewConstraints = Stack<Pair<NewTypeVariable, Constraint>>()
|
||||||
val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType, possibleNewConstraints)
|
val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType, possibleNewConstraints)
|
||||||
typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
|
typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
|
||||||
@@ -72,7 +77,8 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
|
|||||||
val (typeVariable, constraint) = possibleNewConstraints.pop()
|
val (typeVariable, constraint) = possibleNewConstraints.pop()
|
||||||
if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue
|
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
|
// it is important, that we add constraint here(not inside TypeCheckerContext), because inside incorporation we read constraints
|
||||||
constraints.addConstraint(constraint)?.let {
|
constraints.addConstraint(constraint)?.let {
|
||||||
@@ -105,7 +111,8 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
|
|||||||
return false
|
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(
|
private inner class TypeCheckerContext(
|
||||||
val c: Context,
|
val c: Context,
|
||||||
@@ -126,6 +133,7 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
|
|||||||
|
|
||||||
// from TypeCheckerContextForConstraintSystem
|
// from TypeCheckerContextForConstraintSystem
|
||||||
override fun isMyTypeVariable(type: SimpleType): Boolean = c.allTypeVariables.containsKey(type.constructor)
|
override fun isMyTypeVariable(type: SimpleType): Boolean = c.allTypeVariables.containsKey(type.constructor)
|
||||||
|
|
||||||
override fun addUpperConstraint(typeVariable: TypeConstructor, superType: UnwrappedType) =
|
override fun addUpperConstraint(typeVariable: TypeConstructor, superType: UnwrappedType) =
|
||||||
addConstraint(typeVariable, superType, UPPER)
|
addConstraint(typeVariable, superType, UPPER)
|
||||||
|
|
||||||
@@ -148,14 +156,16 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
|
|||||||
if (type.contains(this::isCapturedTypeFromSubtyping)) {
|
if (type.contains(this::isCapturedTypeFromSubtyping)) {
|
||||||
// TypeVariable <: type -> if TypeVariable <: subType => TypeVariable <: type
|
// TypeVariable <: type -> if TypeVariable <: subType => TypeVariable <: type
|
||||||
if (kind == UPPER) {
|
if (kind == UPPER) {
|
||||||
val subType = typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation)
|
val subType =
|
||||||
|
typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation)
|
||||||
if (subType != null && !KotlinBuiltIns.isNothingOrNullableNothing(subType)) {
|
if (subType != null && !KotlinBuiltIns.isNothingOrNullableNothing(subType)) {
|
||||||
targetType = subType
|
targetType = subType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind == LOWER) {
|
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
|
if (superType != null && !KotlinBuiltIns.isAnyOrNullableAny(superType)) { // todo rethink error reporting for Any cases
|
||||||
targetType = superType
|
targetType = superType
|
||||||
}
|
}
|
||||||
@@ -193,8 +203,10 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
|
|||||||
?: fixedTypeVariable(typeVariable)
|
?: fixedTypeVariable(typeVariable)
|
||||||
|
|
||||||
fun fixedTypeVariable(variable: NewTypeVariable): Nothing {
|
fun fixedTypeVariable(variable: NewTypeVariable): Nothing {
|
||||||
error("Type variable $variable should not be fixed!\n" +
|
error(
|
||||||
renderBaseConstraint())
|
"Type variable $variable should not be fixed!\n" +
|
||||||
|
renderBaseConstraint()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderBaseConstraint() = "Base constraint: $baseLowerType <: $baseUpperType from position: $position"
|
private fun renderBaseConstraint() = "Base constraint: $baseLowerType <: $baseUpperType from position: $position"
|
||||||
|
|||||||
+10
-3
@@ -43,6 +43,7 @@ class KotlinConstraintSystemCompleter(
|
|||||||
|
|
||||||
// mutable operations
|
// mutable operations
|
||||||
fun addError(error: KotlinCallDiagnostic)
|
fun addError(error: KotlinCallDiagnostic)
|
||||||
|
|
||||||
fun fixVariable(variable: NewTypeVariable, resultType: UnwrappedType)
|
fun fixVariable(variable: NewTypeVariable, resultType: UnwrappedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +60,8 @@ class KotlinConstraintSystemCompleter(
|
|||||||
val allTypeVariables = getOrderedAllTypeVariables(c, topLevelPrimitive)
|
val allTypeVariables = getOrderedAllTypeVariables(c, topLevelPrimitive)
|
||||||
val postponedKtPrimitives = getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive)
|
val postponedKtPrimitives = getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive)
|
||||||
val variableForFixation = variableFixationFinder.findFirstVariableForFixation(
|
val variableForFixation = variableFixationFinder.findFirstVariableForFixation(
|
||||||
c, allTypeVariables, postponedKtPrimitives, completionMode, topLevelType)
|
c, allTypeVariables, postponedKtPrimitives, completionMode, topLevelType
|
||||||
|
)
|
||||||
|
|
||||||
if (shouldForceCallableReferenceOrLambdaResolution(completionMode, variableForFixation)) {
|
if (shouldForceCallableReferenceOrLambdaResolution(completionMode, variableForFixation)) {
|
||||||
if (forcePostponedAtomResolution<ResolvedCallableReferenceAtom>(topLevelPrimitive, analyze)) continue
|
if (forcePostponedAtomResolution<ResolvedCallableReferenceAtom>(topLevelPrimitive, analyze)) continue
|
||||||
@@ -98,7 +100,11 @@ class KotlinConstraintSystemCompleter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// true if we do analyze
|
// 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)) {
|
for (argument in getOrderedNotAnalyzedPostponedArguments(topLevelPrimitive)) {
|
||||||
if (canWeAnalyzeIt(c, argument)) {
|
if (canWeAnalyzeIt(c, argument)) {
|
||||||
analyze(argument)
|
analyze(argument)
|
||||||
@@ -129,7 +135,7 @@ class KotlinConstraintSystemCompleter(
|
|||||||
return arrayListOf<PostponedResolvedAtom>().apply { topLevelPrimitive.process(this) }
|
return arrayListOf<PostponedResolvedAtom>().apply { topLevelPrimitive.process(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getOrderedAllTypeVariables(c: Context, topLevelPrimitive: ResolvedAtom) : List<TypeConstructor> {
|
private fun getOrderedAllTypeVariables(c: Context, topLevelPrimitive: ResolvedAtom): List<TypeConstructor> {
|
||||||
fun ResolvedAtom.process(to: MutableList<TypeConstructor>) {
|
fun ResolvedAtom.process(to: MutableList<TypeConstructor>) {
|
||||||
val typeVariables = when (this) {
|
val typeVariables = when (this) {
|
||||||
is ResolvedCallAtom -> substitutor.freshVariables
|
is ResolvedCallAtom -> substitutor.freshVariables
|
||||||
@@ -146,6 +152,7 @@ class KotlinConstraintSystemCompleter(
|
|||||||
subResolvedAtoms.forEach { it.process(to) }
|
subResolvedAtoms.forEach { it.process(to) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = arrayListOf<TypeConstructor>().apply { topLevelPrimitive.process(this) }
|
val result = arrayListOf<TypeConstructor>().apply { topLevelPrimitive.process(this) }
|
||||||
|
|
||||||
assert(result.size == c.notFixedTypeVariables.size) {
|
assert(result.size == c.notFixedTypeVariables.size) {
|
||||||
|
|||||||
+21
-14
@@ -36,16 +36,17 @@ interface NewTypeSubstitutor {
|
|||||||
is SimpleType -> substitute(type, keepAnnotation, runCapturedChecks)
|
is SimpleType -> substitute(type, keepAnnotation, runCapturedChecks)
|
||||||
is FlexibleType -> if (type is DynamicType || type is RawType) {
|
is FlexibleType -> if (type is DynamicType || type is RawType) {
|
||||||
null
|
null
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val lowerBound = substitute(type.lowerBound, keepAnnotation, runCapturedChecks)
|
val lowerBound = substitute(type.lowerBound, keepAnnotation, runCapturedChecks)
|
||||||
val upperBound = substitute(type.upperBound, keepAnnotation, runCapturedChecks)
|
val upperBound = substitute(type.upperBound, keepAnnotation, runCapturedChecks)
|
||||||
if (lowerBound == null && upperBound == null) {
|
if (lowerBound == null && upperBound == null) {
|
||||||
null
|
null
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// todo discuss lowerIfFlexible and upperIfFlexible
|
// todo discuss lowerIfFlexible and upperIfFlexible
|
||||||
KotlinTypeFactory.flexibleType(lowerBound?.lowerIfFlexible() ?: type.lowerBound, upperBound?.upperIfFlexible() ?: type.upperBound)
|
KotlinTypeFactory.flexibleType(
|
||||||
|
lowerBound?.lowerIfFlexible() ?: type.lowerBound,
|
||||||
|
upperBound?.upperIfFlexible() ?: type.upperBound
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,10 +58,11 @@ interface NewTypeSubstitutor {
|
|||||||
val substitutedExpandedType = substitute(type.expandedType, keepAnnotation, runCapturedChecks)
|
val substitutedExpandedType = substitute(type.expandedType, keepAnnotation, runCapturedChecks)
|
||||||
val substitutedAbbreviation = substitute(type.abbreviation, keepAnnotation, runCapturedChecks)
|
val substitutedAbbreviation = substitute(type.abbreviation, keepAnnotation, runCapturedChecks)
|
||||||
if (substitutedExpandedType is SimpleType? && substitutedAbbreviation is SimpleType?) {
|
if (substitutedExpandedType is SimpleType? && substitutedAbbreviation is SimpleType?) {
|
||||||
return AbbreviatedType(substitutedExpandedType ?: type.expandedType,
|
return AbbreviatedType(
|
||||||
substitutedAbbreviation ?: type.abbreviation)
|
substitutedExpandedType ?: type.expandedType,
|
||||||
}
|
substitutedAbbreviation ?: type.abbreviation
|
||||||
else {
|
)
|
||||||
|
} else {
|
||||||
return substitutedExpandedType
|
return substitutedExpandedType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,21 +76,26 @@ interface NewTypeSubstitutor {
|
|||||||
if (typeConstructor is NewCapturedTypeConstructor) {
|
if (typeConstructor is NewCapturedTypeConstructor) {
|
||||||
if (!runCapturedChecks) return null
|
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 " +
|
"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 capturedType = if (type is DefinitelyNotNullType) type.original as NewCapturedType else type as NewCapturedType
|
||||||
val lower = capturedType.lowerType?.let { substitute(it, keepAnnotation, runCapturedChecks = false) }
|
val lower = capturedType.lowerType?.let { substitute(it, keepAnnotation, runCapturedChecks = false) }
|
||||||
if (lower != null) throw IllegalStateException("Illegal type substitutor: $this, " +
|
if (lower != null) throw IllegalStateException(
|
||||||
|
"Illegal type substitutor: $this, " +
|
||||||
"because for captured type '$type' lower type approximation should be null, but it is: '$lower'," +
|
"because for captured type '$type' lower type approximation should be null, but it is: '$lower'," +
|
||||||
"original lower type: '${capturedType.lowerType}")
|
"original lower type: '${capturedType.lowerType}"
|
||||||
|
)
|
||||||
|
|
||||||
typeConstructor.supertypes.forEach { supertype ->
|
typeConstructor.supertypes.forEach { supertype ->
|
||||||
substitute(supertype, keepAnnotation, runCapturedChecks = false)?.let {
|
substitute(supertype, keepAnnotation, runCapturedChecks = false)?.let {
|
||||||
throw IllegalStateException("Illegal type substitutor: $this, " +
|
throw IllegalStateException(
|
||||||
|
"Illegal type substitutor: $this, " +
|
||||||
"because for captured type '$type' supertype approximation should be null, but it is: '$supertype'," +
|
"because for captured type '$type' supertype approximation should be null, but it is: '$supertype'," +
|
||||||
"original supertype: '$supertype'")
|
"original supertype: '$supertype'"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -49,8 +49,7 @@ class ResultTypeResolver(
|
|||||||
val superType = findSuperType(c, variableWithConstraints)
|
val superType = findSuperType(c, variableWithConstraints)
|
||||||
val result = if (direction == ResolveDirection.TO_SUBTYPE || direction == ResolveDirection.UNKNOWN) {
|
val result = if (direction == ResolveDirection.TO_SUBTYPE || direction == ResolveDirection.UNKNOWN) {
|
||||||
c.resultType(subType, superType, variableWithConstraints)
|
c.resultType(subType, superType, variableWithConstraints)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
c.resultType(superType, subType, variableWithConstraints)
|
c.resultType(superType, subType, variableWithConstraints)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +67,7 @@ class ResultTypeResolver(
|
|||||||
|
|
||||||
if (isSuitableType(secondCandidate, variableWithConstraints)) {
|
if (isSuitableType(secondCandidate, variableWithConstraints)) {
|
||||||
return secondCandidate
|
return secondCandidate
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return firstCandidate
|
return firstCandidate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +103,10 @@ class ResultTypeResolver(
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return typeApproximator.approximateToSuperType(adjustedCommonSuperType, TypeApproximatorConfiguration.CapturedTypesApproximation)
|
return typeApproximator.approximateToSuperType(
|
||||||
|
adjustedCommonSuperType,
|
||||||
|
TypeApproximatorConfiguration.CapturedTypesApproximation
|
||||||
|
)
|
||||||
?: adjustedCommonSuperType
|
?: adjustedCommonSuperType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-4
@@ -31,6 +31,7 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT
|
|||||||
|
|
||||||
// super and sub type isSingleClassifierType
|
// super and sub type isSingleClassifierType
|
||||||
abstract fun addUpperConstraint(typeVariable: TypeConstructor, superType: UnwrappedType)
|
abstract fun addUpperConstraint(typeVariable: TypeConstructor, superType: UnwrappedType)
|
||||||
|
|
||||||
abstract fun addLowerConstraint(typeVariable: TypeConstructor, subType: UnwrappedType)
|
abstract fun addLowerConstraint(typeVariable: TypeConstructor, subType: UnwrappedType)
|
||||||
|
|
||||||
override fun getLowerCapturedTypePolicy(subType: SimpleType, superType: NewCapturedType) = when {
|
override fun getLowerCapturedTypePolicy(subType: SimpleType, superType: NewCapturedType) = when {
|
||||||
@@ -81,8 +82,7 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT
|
|||||||
|
|
||||||
if (subType.anyBound(this::isMyTypeVariable)) {
|
if (subType.anyBound(this::isMyTypeVariable)) {
|
||||||
return simplifyUpperConstraint(subType, superType) && (answer ?: true)
|
return simplifyUpperConstraint(subType, superType) && (answer ?: true)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return simplifyConstraintForPossibleIntersectionSubType(subType, superType) ?: answer
|
return simplifyConstraintForPossibleIntersectionSubType(subType, superType) ?: answer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,8 +225,11 @@ abstract class TypeCheckerContextForConstraintSystem : TypeCheckerContext(errorT
|
|||||||
with(NewKotlinTypeChecker) { this@TypeCheckerContextForConstraintSystem.isSubtypeOf(subType, superType) }
|
with(NewKotlinTypeChecker) { this@TypeCheckerContextForConstraintSystem.isSubtypeOf(subType, superType) }
|
||||||
|
|
||||||
private fun assertInputTypes(subType: UnwrappedType, superType: UnwrappedType) {
|
private fun assertInputTypes(subType: UnwrappedType, superType: UnwrappedType) {
|
||||||
fun correctSubType(subType: SimpleType) = subType.isSingleClassifierType || subType.isIntersectionType || isMyTypeVariable(subType) || subType.isError
|
fun correctSubType(subType: SimpleType) =
|
||||||
fun correctSuperType(superType: SimpleType) = superType.isSingleClassifierType || superType.isIntersectionType || isMyTypeVariable(superType) || superType.isError
|
subType.isSingleClassifierType || subType.isIntersectionType || isMyTypeVariable(subType) || subType.isError
|
||||||
|
|
||||||
|
fun correctSuperType(superType: SimpleType) =
|
||||||
|
superType.isSingleClassifierType || superType.isIntersectionType || isMyTypeVariable(superType) || superType.isError
|
||||||
|
|
||||||
assert(subType.bothBounds(::correctSubType)) {
|
assert(subType.bothBounds(::correctSubType)) {
|
||||||
"Not singleClassifierType and not intersection subType: $subType"
|
"Not singleClassifierType and not intersection subType: $subType"
|
||||||
|
|||||||
+4
-1
@@ -105,7 +105,10 @@ class TypeVariableDirectionCalculator(
|
|||||||
!(direction == ResolveDirection.TO_SUBTYPE && constraint.kind == ConstraintKind.UPPER) &&
|
!(direction == ResolveDirection.TO_SUBTYPE && constraint.kind == ConstraintKind.UPPER) &&
|
||||||
!(direction == ResolveDirection.TO_SUPERTYPE && constraint.kind == ConstraintKind.LOWER)
|
!(direction == ResolveDirection.TO_SUPERTYPE && constraint.kind == ConstraintKind.LOWER)
|
||||||
|
|
||||||
private fun UnwrappedType.visitType(startDirection: ResolveDirection, action: (variable: Variable, direction: ResolveDirection) -> Unit) =
|
private fun UnwrappedType.visitType(
|
||||||
|
startDirection: ResolveDirection,
|
||||||
|
action: (variable: Variable, direction: ResolveDirection) -> Unit
|
||||||
|
) =
|
||||||
when (this) {
|
when (this) {
|
||||||
is SimpleType -> visitType(startDirection, action)
|
is SimpleType -> visitType(startDirection, action)
|
||||||
is FlexibleType -> {
|
is FlexibleType -> {
|
||||||
|
|||||||
+5
@@ -30,12 +30,15 @@ sealed class ConstraintPosition
|
|||||||
class ExplicitTypeParameterConstraintPosition(val typeArgument: SimpleTypeArgument) : ConstraintPosition() {
|
class ExplicitTypeParameterConstraintPosition(val typeArgument: SimpleTypeArgument) : ConstraintPosition() {
|
||||||
override fun toString() = "TypeParameter $typeArgument"
|
override fun toString() = "TypeParameter $typeArgument"
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExpectedTypeConstraintPosition(val topLevelCall: KotlinCall) : ConstraintPosition() {
|
class ExpectedTypeConstraintPosition(val topLevelCall: KotlinCall) : ConstraintPosition() {
|
||||||
override fun toString() = "ExpectedType for call $topLevelCall"
|
override fun toString() = "ExpectedType for call $topLevelCall"
|
||||||
}
|
}
|
||||||
|
|
||||||
class DeclaredUpperBoundConstraintPosition(val typeParameterDescriptor: TypeParameterDescriptor) : ConstraintPosition() {
|
class DeclaredUpperBoundConstraintPosition(val typeParameterDescriptor: TypeParameterDescriptor) : ConstraintPosition() {
|
||||||
override fun toString() = "DeclaredUpperBound ${typeParameterDescriptor.name} from ${typeParameterDescriptor.containingDeclaration}"
|
override fun toString() = "DeclaredUpperBound ${typeParameterDescriptor.name} from ${typeParameterDescriptor.containingDeclaration}"
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArgumentConstraintPosition(val argument: KotlinCallArgument) : ConstraintPosition() {
|
class ArgumentConstraintPosition(val argument: KotlinCallArgument) : ConstraintPosition() {
|
||||||
override fun toString() = "Argument $argument"
|
override fun toString() = "Argument $argument"
|
||||||
}
|
}
|
||||||
@@ -47,9 +50,11 @@ class ReceiverConstraintPosition(val argument: KotlinCallArgument) : ConstraintP
|
|||||||
class FixVariableConstraintPosition(val variable: NewTypeVariable) : ConstraintPosition() {
|
class FixVariableConstraintPosition(val variable: NewTypeVariable) : ConstraintPosition() {
|
||||||
override fun toString() = "Fix variable $variable"
|
override fun toString() = "Fix variable $variable"
|
||||||
}
|
}
|
||||||
|
|
||||||
class KnownTypeParameterConstraintPosition(val typeArgument: KotlinType) : ConstraintPosition() {
|
class KnownTypeParameterConstraintPosition(val typeArgument: KotlinType) : ConstraintPosition() {
|
||||||
override fun toString() = "TypeArgument $typeArgument"
|
override fun toString() = "TypeArgument $typeArgument"
|
||||||
}
|
}
|
||||||
|
|
||||||
class LambdaArgumentConstraintPosition(val lambda: ResolvedLambdaAtom) : ConstraintPosition() {
|
class LambdaArgumentConstraintPosition(val lambda: ResolvedLambdaAtom) : ConstraintPosition() {
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "LambdaArgument $lambda"
|
return "LambdaArgument $lambda"
|
||||||
|
|||||||
+3
-3
@@ -28,7 +28,8 @@ class MutableVariableWithConstraints(
|
|||||||
override val typeVariable: NewTypeVariable,
|
override val typeVariable: NewTypeVariable,
|
||||||
constraints: Collection<Constraint> = emptyList()
|
constraints: Collection<Constraint> = emptyList()
|
||||||
) : VariableWithConstraints {
|
) : VariableWithConstraints {
|
||||||
override val constraints: List<Constraint> get() {
|
override val constraints: List<Constraint>
|
||||||
|
get() {
|
||||||
if (simplifiedConstraints == null) {
|
if (simplifiedConstraints == null) {
|
||||||
simplifiedConstraints = simplifyConstraints()
|
simplifiedConstraints = simplifyConstraints()
|
||||||
}
|
}
|
||||||
@@ -49,8 +50,7 @@ class MutableVariableWithConstraints(
|
|||||||
val actualConstraint = if (previousConstraintWithSameType.isNotEmpty()) {
|
val actualConstraint = if (previousConstraintWithSameType.isNotEmpty()) {
|
||||||
// i.e. previous is LOWER and new is UPPER or opposite situation
|
// i.e. previous is LOWER and new is UPPER or opposite situation
|
||||||
Constraint(ConstraintKind.EQUALITY, constraint.type, constraint.position, constraint.typeHashCode)
|
Constraint(ConstraintKind.EQUALITY, constraint.type, constraint.position, constraint.typeHashCode)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
constraint
|
constraint
|
||||||
}
|
}
|
||||||
mutableConstraints.add(actualConstraint)
|
mutableConstraints.add(actualConstraint)
|
||||||
|
|||||||
+28
-9
@@ -33,14 +33,13 @@ import org.jetbrains.kotlin.utils.SmartList
|
|||||||
class NewConstraintSystemImpl(
|
class NewConstraintSystemImpl(
|
||||||
private val constraintInjector: ConstraintInjector,
|
private val constraintInjector: ConstraintInjector,
|
||||||
override val builtIns: KotlinBuiltIns
|
override val builtIns: KotlinBuiltIns
|
||||||
):
|
) :
|
||||||
NewConstraintSystem,
|
NewConstraintSystem,
|
||||||
ConstraintSystemBuilder,
|
ConstraintSystemBuilder,
|
||||||
ConstraintInjector.Context,
|
ConstraintInjector.Context,
|
||||||
ResultTypeResolver.Context,
|
ResultTypeResolver.Context,
|
||||||
KotlinConstraintSystemCompleter.Context,
|
KotlinConstraintSystemCompleter.Context,
|
||||||
PostponedArgumentsAnalyzer.Context
|
PostponedArgumentsAnalyzer.Context {
|
||||||
{
|
|
||||||
private val storage = MutableConstraintStorage()
|
private val storage = MutableConstraintStorage()
|
||||||
private var state = State.BUILDING
|
private var state = State.BUILDING
|
||||||
private val typeVariablesTransaction: MutableList<NewTypeVariable> = SmartList()
|
private val typeVariablesTransaction: MutableList<NewTypeVariable> = SmartList()
|
||||||
@@ -83,10 +82,20 @@ class NewConstraintSystemImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun addSubtypeConstraint(lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition) =
|
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) =
|
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<TypeConstructor> {
|
override fun getProperSuperTypeConstructors(type: UnwrappedType): List<TypeConstructor> {
|
||||||
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
||||||
@@ -146,7 +155,14 @@ class NewConstraintSystemImpl(
|
|||||||
|
|
||||||
// ConstraintSystemBuilder, KotlinConstraintSystemCompleter.Context
|
// ConstraintSystemBuilder, KotlinConstraintSystemCompleter.Context
|
||||||
override val hasContradiction: Boolean
|
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) {
|
override fun addOtherSystem(otherSystem: ConstraintStorage) {
|
||||||
storage.allTypeVariables.putAll(otherSystem.allTypeVariables)
|
storage.allTypeVariables.putAll(otherSystem.allTypeVariables)
|
||||||
@@ -154,7 +170,8 @@ class NewConstraintSystemImpl(
|
|||||||
notFixedTypeVariables[variable] = MutableVariableWithConstraints(constraints.typeVariable, constraints.constraints)
|
notFixedTypeVariables[variable] = MutableVariableWithConstraints(constraints.typeVariable, constraints.constraints)
|
||||||
}
|
}
|
||||||
storage.initialConstraints.addAll(otherSystem.initialConstraints)
|
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.errors.addAll(otherSystem.errors)
|
||||||
storage.fixedTypeVariables.putAll(otherSystem.fixedTypeVariables)
|
storage.fixedTypeVariables.putAll(otherSystem.fixedTypeVariables)
|
||||||
}
|
}
|
||||||
@@ -173,7 +190,8 @@ class NewConstraintSystemImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConstraintInjector.Context
|
// ConstraintInjector.Context
|
||||||
override val allTypeVariables: Map<TypeConstructor, NewTypeVariable> get() {
|
override val allTypeVariables: Map<TypeConstructor, NewTypeVariable>
|
||||||
|
get() {
|
||||||
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
||||||
return storage.allTypeVariables
|
return storage.allTypeVariables
|
||||||
}
|
}
|
||||||
@@ -191,7 +209,8 @@ class NewConstraintSystemImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConstraintInjector.Context, FixationOrderCalculator.Context
|
// ConstraintInjector.Context, FixationOrderCalculator.Context
|
||||||
override val notFixedTypeVariables: MutableMap<TypeConstructor, MutableVariableWithConstraints> get() {
|
override val notFixedTypeVariables: MutableMap<TypeConstructor, MutableVariableWithConstraints>
|
||||||
|
get() {
|
||||||
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
||||||
return storage.notFixedTypeVariables
|
return storage.notFixedTypeVariables
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -29,7 +29,8 @@ import org.jetbrains.kotlin.types.TypeConstructor
|
|||||||
import org.jetbrains.kotlin.types.checker.NewTypeVariableConstructor
|
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<TypeParameterDescriptor> = emptyList()
|
override fun getParameters(): List<TypeParameterDescriptor> = emptyList()
|
||||||
override fun getSupertypes(): Collection<KotlinType> = emptyList()
|
override fun getSupertypes(): Collection<KotlinType> = emptyList()
|
||||||
override fun isFinal(): Boolean = false
|
override fun isFinal(): Boolean = false
|
||||||
@@ -48,7 +49,8 @@ sealed class NewTypeVariable(builtIns: KotlinBuiltIns, name: String) {
|
|||||||
// todo add to member scope methods from supertypes for type variable
|
// todo add to member scope methods from supertypes for type variable
|
||||||
val defaultType: SimpleType = KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
val defaultType: SimpleType = KotlinTypeFactory.simpleTypeWithNonTrivialMemberScope(
|
||||||
Annotations.EMPTY, freshTypeConstructor, arguments = emptyList(),
|
Annotations.EMPTY, freshTypeConstructor, arguments = emptyList(),
|
||||||
nullable = false, memberScope = builtIns.any.unsubstitutedMemberScope)
|
nullable = false, memberScope = builtIns.any.unsubstitutedMemberScope
|
||||||
|
)
|
||||||
|
|
||||||
override fun toString() = freshTypeConstructor.toString()
|
override fun toString() = freshTypeConstructor.toString()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class ReceiverExpressionKotlinCallArgument private constructor(
|
|||||||
) : ExpressionKotlinCallArgument {
|
) : ExpressionKotlinCallArgument {
|
||||||
override val isSpread: Boolean get() = false
|
override val isSpread: Boolean get() = false
|
||||||
override val argumentName: Name? get() = null
|
override val argumentName: Name? get() = null
|
||||||
override fun toString() = "$receiver" + if(isSafeCall) "?" else ""
|
override fun toString() = "$receiver" + if (isSafeCall) "?" else ""
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// we create ReceiverArgument and fix capture types
|
// we create ReceiverArgument and fix capture types
|
||||||
|
|||||||
@@ -78,8 +78,7 @@ fun KotlinCall.checkCallInvariants() {
|
|||||||
assert(dispatchReceiverForInvokeExtension == null) {
|
assert(dispatchReceiverForInvokeExtension == null) {
|
||||||
"Dispatch receiver for invoke should be null for not function call: $dispatchReceiverForInvokeExtension"
|
"Dispatch receiver for invoke should be null for not function call: $dispatchReceiverForInvokeExtension"
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
assert(externalArgument == null || !externalArgument!!.isSpread) {
|
assert(externalArgument == null || !externalArgument!!.isSpread) {
|
||||||
"External argument cannot nave spread element: $externalArgument"
|
"External argument cannot nave spread element: $externalArgument"
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-6
@@ -88,7 +88,7 @@ interface FunctionExpression : LambdaKotlinCallArgument {
|
|||||||
* D.E::foo <-> Expression
|
* D.E::foo <-> Expression
|
||||||
*/
|
*/
|
||||||
sealed class LHSResult {
|
sealed class LHSResult {
|
||||||
class Type(val qualifier: QualifierReceiver, resolvedType: UnwrappedType): LHSResult() {
|
class Type(val qualifier: QualifierReceiver, resolvedType: UnwrappedType) : LHSResult() {
|
||||||
val unboundDetailedReceiver: ReceiverValueWithSmartCastInfo
|
val unboundDetailedReceiver: ReceiverValueWithSmartCastInfo
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -101,7 +101,7 @@ sealed class LHSResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Object(val qualifier: QualifierReceiver): LHSResult() {
|
class Object(val qualifier: QualifierReceiver) : LHSResult() {
|
||||||
val objectValueReceiver: ReceiverValueWithSmartCastInfo
|
val objectValueReceiver: ReceiverValueWithSmartCastInfo
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -111,12 +111,13 @@ sealed class LHSResult {
|
|||||||
objectValueReceiver = qualifier.classValueReceiverWithSmartCastInfo ?: error("class value should be not null for $qualifier")
|
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
|
// todo this case is forbid for now
|
||||||
object Empty: LHSResult()
|
object Empty : LHSResult()
|
||||||
|
|
||||||
object Error: LHSResult()
|
object Error : LHSResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CallableReferenceKotlinCallArgument : PostponableKotlinCallArgument {
|
interface CallableReferenceKotlinCallArgument : PostponableKotlinCallArgument {
|
||||||
@@ -135,6 +136,6 @@ interface TypeArgument
|
|||||||
// todo allow '_' in frontend
|
// todo allow '_' in frontend
|
||||||
object TypeArgumentPlaceholder : TypeArgument
|
object TypeArgumentPlaceholder : TypeArgument
|
||||||
|
|
||||||
interface SimpleTypeArgument: TypeArgument {
|
interface SimpleTypeArgument : TypeArgument {
|
||||||
val type: UnwrappedType
|
val type: UnwrappedType
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -31,7 +31,8 @@ abstract class InapplicableArgumentDiagnostic : KotlinCallDiagnostic(INAPPLICABL
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ArgumentsToParameterMapper
|
// 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)
|
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +133,7 @@ class SmartCastDiagnostic(
|
|||||||
val argument: ExpressionKotlinCallArgument,
|
val argument: ExpressionKotlinCallArgument,
|
||||||
val smartCastType: UnwrappedType,
|
val smartCastType: UnwrappedType,
|
||||||
val kotlinCall: KotlinCall?
|
val kotlinCall: KotlinCall?
|
||||||
): KotlinCallDiagnostic(RESOLVED) {
|
) : KotlinCallDiagnostic(RESOLVED) {
|
||||||
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this)
|
override fun report(reporter: DiagnosticReporter) = reporter.onCallArgument(argument, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
-17
@@ -49,7 +49,7 @@ class SimpleCandidateFactory(
|
|||||||
val callComponents: KotlinCallComponents,
|
val callComponents: KotlinCallComponents,
|
||||||
val scopeTower: ImplicitScopeTower,
|
val scopeTower: ImplicitScopeTower,
|
||||||
val kotlinCall: KotlinCall
|
val kotlinCall: KotlinCall
|
||||||
): CandidateFactory<KotlinResolutionCandidate> {
|
) : CandidateFactory<KotlinResolutionCandidate> {
|
||||||
val baseSystem: ConstraintStorage
|
val baseSystem: ConstraintStorage
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -86,10 +86,13 @@ class SimpleCandidateFactory(
|
|||||||
fun createCandidate(givenCandidate: GivenCandidate): KotlinResolutionCandidate {
|
fun createCandidate(givenCandidate: GivenCandidate): KotlinResolutionCandidate {
|
||||||
val isSafeCall = (kotlinCall.explicitReceiver as? SimpleKotlinCallArgument)?.isSafeCall ?: false
|
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) }
|
val dispatchArgumentReceiver = givenCandidate.dispatchReceiver?.let { ReceiverExpressionKotlinCallArgument(it, isSafeCall) }
|
||||||
return createCandidate(givenCandidate.descriptor, explicitReceiverKind, dispatchArgumentReceiver, null,
|
return createCandidate(
|
||||||
listOf(), givenCandidate.knownTypeParametersResultingSubstitutor)
|
givenCandidate.descriptor, explicitReceiverKind, dispatchArgumentReceiver, null,
|
||||||
|
listOf(), givenCandidate.knownTypeParametersResultingSubstitutor
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCandidate(
|
override fun createCandidate(
|
||||||
@@ -97,12 +100,17 @@ class SimpleCandidateFactory(
|
|||||||
explicitReceiverKind: ExplicitReceiverKind,
|
explicitReceiverKind: ExplicitReceiverKind,
|
||||||
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
): KotlinResolutionCandidate {
|
): KotlinResolutionCandidate {
|
||||||
val dispatchArgumentReceiver = createReceiverArgument(kotlinCall.getExplicitDispatchReceiver(explicitReceiverKind),
|
val dispatchArgumentReceiver = createReceiverArgument(
|
||||||
towerCandidate.dispatchReceiver)
|
kotlinCall.getExplicitDispatchReceiver(explicitReceiverKind),
|
||||||
val extensionArgumentReceiver = createReceiverArgument(kotlinCall.getExplicitExtensionReceiver(explicitReceiverKind), extensionReceiver)
|
towerCandidate.dispatchReceiver
|
||||||
|
)
|
||||||
|
val extensionArgumentReceiver =
|
||||||
|
createReceiverArgument(kotlinCall.getExplicitExtensionReceiver(explicitReceiverKind), extensionReceiver)
|
||||||
|
|
||||||
return createCandidate(towerCandidate.descriptor, explicitReceiverKind, dispatchArgumentReceiver,
|
return createCandidate(
|
||||||
extensionArgumentReceiver, towerCandidate.diagnostics, knownSubstitutor = null)
|
towerCandidate.descriptor, explicitReceiverKind, dispatchArgumentReceiver,
|
||||||
|
extensionArgumentReceiver, towerCandidate.diagnostics, knownSubstitutor = null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCandidate(
|
private fun createCandidate(
|
||||||
@@ -113,11 +121,20 @@ class SimpleCandidateFactory(
|
|||||||
initialDiagnostics: Collection<KotlinCallDiagnostic>,
|
initialDiagnostics: Collection<KotlinCallDiagnostic>,
|
||||||
knownSubstitutor: TypeSubstitutor?
|
knownSubstitutor: TypeSubstitutor?
|
||||||
): KotlinResolutionCandidate {
|
): KotlinResolutionCandidate {
|
||||||
val resolvedKtCall = MutableResolvedCallAtom(kotlinCall, descriptor, explicitReceiverKind,
|
val resolvedKtCall = MutableResolvedCallAtom(
|
||||||
dispatchArgumentReceiver, extensionArgumentReceiver)
|
kotlinCall, descriptor, explicitReceiverKind,
|
||||||
|
dispatchArgumentReceiver, extensionArgumentReceiver
|
||||||
|
)
|
||||||
|
|
||||||
if (ErrorUtils.isError(descriptor)) {
|
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)
|
val candidate = KotlinResolutionCandidate(callComponents, scopeTower, baseSystem, resolvedKtCall, knownSubstitutor)
|
||||||
@@ -145,16 +162,18 @@ class SimpleCandidateFactory(
|
|||||||
val errorScope = ErrorUtils.createErrorScope("Error resolution candidate for call $kotlinCall")
|
val errorScope = ErrorUtils.createErrorScope("Error resolution candidate for call $kotlinCall")
|
||||||
val errorDescriptor = if (kotlinCall.callKind == KotlinCallKind.VARIABLE) {
|
val errorDescriptor = if (kotlinCall.callKind == KotlinCallKind.VARIABLE) {
|
||||||
errorScope.getContributedVariables(kotlinCall.name, scopeTower.location)
|
errorScope.getContributedVariables(kotlinCall.name, scopeTower.location)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
errorScope.getContributedFunctions(kotlinCall.name, scopeTower.location)
|
errorScope.getContributedFunctions(kotlinCall.name, scopeTower.location)
|
||||||
}.first()
|
}.first()
|
||||||
|
|
||||||
val dispatchReceiver = createReceiverArgument(kotlinCall.explicitReceiver, fromResolution = null)
|
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,
|
return createCandidate(
|
||||||
initialDiagnostics = listOf(), knownSubstitutor = null)
|
errorDescriptor, explicitReceiverKind, dispatchReceiver, extensionArgumentReceiver = null,
|
||||||
|
initialDiagnostics = listOf(), knownSubstitutor = null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ class ResolvedExpressionAtom(override val atom: ExpressionKotlinCallArgument) :
|
|||||||
setAnalyzedResults(listOf())
|
setAnalyzedResults(listOf())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class PostponedResolvedAtom : ResolvedAtom() {
|
sealed class PostponedResolvedAtom : ResolvedAtom() {
|
||||||
abstract val inputTypes: Collection<UnwrappedType>
|
abstract val inputTypes: Collection<UnwrappedType>
|
||||||
abstract val outputType: UnwrappedType?
|
abstract val outputType: UnwrappedType?
|
||||||
@@ -176,7 +177,8 @@ class CallResolutionResult(
|
|||||||
override fun toString() = "$type, resultCallAtom = $resultCallAtom, (${diagnostics.joinToString()})"
|
override fun toString() = "$type, resultCallAtom = $resultCallAtom, (${diagnostics.joinToString()})"
|
||||||
}
|
}
|
||||||
|
|
||||||
val ResolvedCallAtom.freshReturnType: UnwrappedType? get() {
|
val ResolvedCallAtom.freshReturnType: UnwrappedType?
|
||||||
|
get() {
|
||||||
val returnType = candidateDescriptor.returnType ?: return null
|
val returnType = candidateDescriptor.returnType ?: return null
|
||||||
return substitutor.safeSubstitute(returnType.unwrap())
|
return substitutor.safeSubstitute(returnType.unwrap())
|
||||||
}
|
}
|
||||||
+2
-2
@@ -56,6 +56,7 @@ interface KotlinDiagnosticsHolder {
|
|||||||
fun KotlinDiagnosticsHolder.addDiagnosticIfNotNull(diagnostic: KotlinCallDiagnostic?) {
|
fun KotlinDiagnosticsHolder.addDiagnosticIfNotNull(diagnostic: KotlinCallDiagnostic?) {
|
||||||
diagnostic?.let { addDiagnostic(it) }
|
diagnostic?.let { addDiagnostic(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* baseSystem contains all information from arguments, i.e. it is union of all system of arguments
|
* 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
|
* Also by convention we suppose that baseSystem has no contradiction
|
||||||
@@ -106,8 +107,7 @@ class KotlinResolutionCandidate(
|
|||||||
if (workStep >= workCount) {
|
if (workStep >= workCount) {
|
||||||
partIndex++
|
partIndex++
|
||||||
workStep -= workCount
|
workStep -= workCount
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -26,11 +26,11 @@ sealed class ResolvedCallArgument {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleArgument(val callArgument: KotlinCallArgument): ResolvedCallArgument() {
|
class SimpleArgument(val callArgument: KotlinCallArgument) : ResolvedCallArgument() {
|
||||||
override val arguments: List<KotlinCallArgument>
|
override val arguments: List<KotlinCallArgument>
|
||||||
get() = listOf(callArgument)
|
get() = listOf(callArgument)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class VarargArgument(override val arguments: List<KotlinCallArgument>): ResolvedCallArgument()
|
class VarargArgument(override val arguments: List<KotlinCallArgument>) : ResolvedCallArgument()
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ interface SpecificityComparisonCallbacks {
|
|||||||
interface TypeSpecificityComparator {
|
interface TypeSpecificityComparator {
|
||||||
fun isDefinitelyLessSpecific(specific: KotlinType, general: KotlinType): Boolean
|
fun isDefinitelyLessSpecific(specific: KotlinType, general: KotlinType): Boolean
|
||||||
|
|
||||||
object NONE: TypeSpecificityComparator {
|
object NONE : TypeSpecificityComparator {
|
||||||
override fun isDefinitelyLessSpecific(specific: KotlinType, general: KotlinType) = false
|
override fun isDefinitelyLessSpecific(specific: KotlinType, general: KotlinType) = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,8 @@ class FlatSignature<out T> private constructor(
|
|||||||
numDefaults: Int,
|
numDefaults: Int,
|
||||||
reflectionType: UnwrappedType
|
reflectionType: UnwrappedType
|
||||||
): FlatSignature<T> {
|
): FlatSignature<T> {
|
||||||
return FlatSignature(origin,
|
return FlatSignature(
|
||||||
|
origin,
|
||||||
descriptor.typeParameters,
|
descriptor.typeParameters,
|
||||||
reflectionType.arguments.map { it.type }, // should we drop return type?
|
reflectionType.arguments.map { it.type }, // should we drop return type?
|
||||||
hasExtensionReceiver = false,
|
hasExtensionReceiver = false,
|
||||||
@@ -76,7 +77,8 @@ class FlatSignature<out T> private constructor(
|
|||||||
): FlatSignature<T> {
|
): FlatSignature<T> {
|
||||||
val extensionReceiverType = descriptor.extensionReceiverParameter?.type
|
val extensionReceiverType = descriptor.extensionReceiverParameter?.type
|
||||||
|
|
||||||
return FlatSignature(origin,
|
return FlatSignature(
|
||||||
|
origin,
|
||||||
descriptor.typeParameters,
|
descriptor.typeParameters,
|
||||||
valueParameterTypes =
|
valueParameterTypes =
|
||||||
listOfNotNull(extensionReceiverType) + parameterTypes,
|
listOfNotNull(extensionReceiverType) + parameterTypes,
|
||||||
@@ -94,7 +96,8 @@ class FlatSignature<out T> private constructor(
|
|||||||
create(descriptor, descriptor, numDefaults = 0, parameterTypes = descriptor.valueParameters.map { it.argumentValueType })
|
create(descriptor, descriptor, numDefaults = 0, parameterTypes = descriptor.valueParameters.map { it.argumentValueType })
|
||||||
|
|
||||||
fun <D : CallableDescriptor> createForPossiblyShadowedExtension(descriptor: D): FlatSignature<D> =
|
fun <D : CallableDescriptor> createForPossiblyShadowedExtension(descriptor: D): FlatSignature<D> =
|
||||||
FlatSignature(descriptor,
|
FlatSignature(
|
||||||
|
descriptor,
|
||||||
descriptor.typeParameters,
|
descriptor.typeParameters,
|
||||||
valueParameterTypes = descriptor.valueParameters.map { it.argumentValueType },
|
valueParameterTypes = descriptor.valueParameters.map { it.argumentValueType },
|
||||||
hasExtensionReceiver = false,
|
hasExtensionReceiver = false,
|
||||||
@@ -143,8 +146,7 @@ fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val substitutedGeneralType = typeSubstitutor.safeSubstitute(generalType, Variance.INVARIANT)
|
val substitutedGeneralType = typeSubstitutor.safeSubstitute(generalType, Variance.INVARIANT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+35
-24
@@ -66,8 +66,7 @@ open class OverloadingConflictResolver<C : Any>(
|
|||||||
|
|
||||||
val fixedCandidates = if (getVariableCandidates(candidates.first()) != null) {
|
val fixedCandidates = if (getVariableCandidates(candidates.first()) != null) {
|
||||||
findMaximallySpecificVariableAsFunctionCalls(candidates, isDebuggerContext) ?: return LinkedHashSet(candidates)
|
findMaximallySpecificVariableAsFunctionCalls(candidates, isDebuggerContext) ?: return LinkedHashSet(candidates)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
candidates
|
candidates
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +130,7 @@ open class OverloadingConflictResolver<C : Any>(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Collection<C>.setIfOneOrEmpty() = when(size) {
|
private fun Collection<C>.setIfOneOrEmpty() = when (size) {
|
||||||
0 -> emptySet()
|
0 -> emptySet()
|
||||||
1 -> setOf(single())
|
1 -> setOf(single())
|
||||||
else -> null
|
else -> null
|
||||||
@@ -167,8 +166,10 @@ open class OverloadingConflictResolver<C : Any>(
|
|||||||
getVariableCandidates(it) ?: throw AssertionError("Regular call among variable-as-function calls: $it")
|
getVariableCandidates(it) ?: throw AssertionError("Regular call among variable-as-function calls: $it")
|
||||||
}
|
}
|
||||||
|
|
||||||
val maxSpecificVariableCalls = chooseMaximallySpecificCandidates(variableCalls, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
val maxSpecificVariableCalls = chooseMaximallySpecificCandidates(
|
||||||
isDebuggerContext = isDebuggerContext, discriminateGenerics = false)
|
variableCalls, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
|
||||||
|
isDebuggerContext = isDebuggerContext, discriminateGenerics = false
|
||||||
|
)
|
||||||
|
|
||||||
val maxSpecificVariableCall = maxSpecificVariableCalls.singleOrNull() ?: return null
|
val maxSpecificVariableCall = maxSpecificVariableCalls.singleOrNull() ?: return null
|
||||||
return candidates.filterTo(newResolvedCallSet(2)) {
|
return candidates.filterTo(newResolvedCallSet(2)) {
|
||||||
@@ -185,21 +186,17 @@ open class OverloadingConflictResolver<C : Any>(
|
|||||||
|
|
||||||
if (filteredCandidates.size <= 1) return filteredCandidates.singleOrNull()
|
if (filteredCandidates.size <= 1) return filteredCandidates.singleOrNull()
|
||||||
|
|
||||||
val conflictingCandidates = filteredCandidates.map {
|
val conflictingCandidates = filteredCandidates.map { candidateCall ->
|
||||||
candidateCall ->
|
|
||||||
createFlatSignature(candidateCall)
|
createFlatSignature(candidateCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
val bestCandidatesByParameterTypes = conflictingCandidates.filter {
|
val bestCandidatesByParameterTypes = conflictingCandidates.filter { candidate ->
|
||||||
candidate ->
|
isMostSpecific(candidate, conflictingCandidates) { call1, call2 ->
|
||||||
isMostSpecific(candidate, conflictingCandidates) {
|
|
||||||
call1, call2 ->
|
|
||||||
isNotLessSpecificCallWithArgumentMapping(call1, call2, discriminateGenerics)
|
isNotLessSpecificCallWithArgumentMapping(call1, call2, discriminateGenerics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestCandidatesByParameterTypes.exactMaxWith {
|
return bestCandidatesByParameterTypes.exactMaxWith { call1, call2 ->
|
||||||
call1, call2 ->
|
|
||||||
isOfNotLessSpecificShape(call1, call2) && isOfNotLessSpecificVisibilityForDebugger(call1, call2, isDebuggerContext)
|
isOfNotLessSpecificShape(call1, call2) && isOfNotLessSpecificVisibilityForDebugger(call1, call2, isDebuggerContext)
|
||||||
}?.origin
|
}?.origin
|
||||||
}
|
}
|
||||||
@@ -219,15 +216,17 @@ open class OverloadingConflictResolver<C : Any>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <C> isMostSpecific(candidate: C, candidates: Collection<C>, isNotLessSpecific: (C, C) -> Boolean): Boolean =
|
private inline fun <C> isMostSpecific(candidate: C, candidates: Collection<C>, isNotLessSpecific: (C, C) -> Boolean): Boolean =
|
||||||
candidates.all {
|
candidates.all { other ->
|
||||||
other ->
|
|
||||||
candidate === other ||
|
candidate === other ||
|
||||||
isNotLessSpecific(candidate, other)
|
isNotLessSpecific(candidate, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <C> isDefinitelyMostSpecific(candidate: C, candidates: Collection<C>, isNotLessSpecific: (C, C) -> Boolean): Boolean =
|
private inline fun <C> isDefinitelyMostSpecific(
|
||||||
candidates.all {
|
candidate: C,
|
||||||
other ->
|
candidates: Collection<C>,
|
||||||
|
isNotLessSpecific: (C, C) -> Boolean
|
||||||
|
): Boolean =
|
||||||
|
candidates.all { other ->
|
||||||
candidate === other ||
|
candidate === other ||
|
||||||
isNotLessSpecific(candidate, other) && !isNotLessSpecific(other, candidate)
|
isNotLessSpecific(candidate, other) && !isNotLessSpecific(other, candidate)
|
||||||
}
|
}
|
||||||
@@ -240,8 +239,11 @@ open class OverloadingConflictResolver<C : Any>(
|
|||||||
call2: FlatSignature<C>,
|
call2: FlatSignature<C>,
|
||||||
discriminateGenerics: Boolean
|
discriminateGenerics: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return tryCompareDescriptorsFromScripts(call1.candidateDescriptor(), call2.candidateDescriptor()) ?:
|
return tryCompareDescriptorsFromScripts(call1.candidateDescriptor(), call2.candidateDescriptor()) ?: compareCallsByUsedArguments(
|
||||||
compareCallsByUsedArguments(call1, call2, discriminateGenerics)
|
call1,
|
||||||
|
call2,
|
||||||
|
discriminateGenerics
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -266,7 +268,12 @@ open class OverloadingConflictResolver<C : Any>(
|
|||||||
if (!call1.isExpect && call2.isExpect) return true
|
if (!call1.isExpect && call2.isExpect) return true
|
||||||
if (call1.isExpect && !call2.isExpect) return false
|
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 {
|
private val SpecificityComparisonWithNumerics = object : SpecificityComparisonCallbacks {
|
||||||
@@ -352,7 +359,12 @@ open class OverloadingConflictResolver<C : Any>(
|
|||||||
|
|
||||||
val fSignature = FlatSignature.createFromCallableDescriptor(f)
|
val fSignature = FlatSignature.createFromCallableDescriptor(f)
|
||||||
val gSignature = FlatSignature.createFromCallableDescriptor(g)
|
val gSignature = FlatSignature.createFromCallableDescriptor(g)
|
||||||
if (!createEmptyConstraintSystem().isSignatureNotLessSpecific(fSignature, gSignature, SpecificityComparisonWithNumerics, specificityComparator)) {
|
if (!createEmptyConstraintSystem().isSignatureNotLessSpecific(
|
||||||
|
fSignature,
|
||||||
|
gSignature,
|
||||||
|
SpecificityComparisonWithNumerics,
|
||||||
|
specificityComparator
|
||||||
|
)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,8 +378,7 @@ open class OverloadingConflictResolver<C : Any>(
|
|||||||
|
|
||||||
private fun isNotLessSpecificCallableReference(f: CallableDescriptor, g: CallableDescriptor): Boolean =
|
private fun isNotLessSpecificCallableReference(f: CallableDescriptor, g: CallableDescriptor): Boolean =
|
||||||
// TODO should we "discriminate generic descriptors" for callable references?
|
// TODO should we "discriminate generic descriptors" for callable references?
|
||||||
tryCompareDescriptorsFromScripts(f, g) ?:
|
tryCompareDescriptorsFromScripts(f, g) ?: isNotLessSpecificCallableReferenceDescriptor(f, g)
|
||||||
isNotLessSpecificCallableReferenceDescriptor(f, g)
|
|
||||||
|
|
||||||
// Different smart casts may lead to the same candidate descriptor wrapped into different ResolvedCallImpl objects
|
// Different smart casts may lead to the same candidate descriptor wrapped into different ResolvedCallImpl objects
|
||||||
private fun uniquifyCandidatesSet(candidates: Collection<C>): Set<C> =
|
private fun uniquifyCandidatesSet(candidates: Collection<C>): Set<C> =
|
||||||
|
|||||||
+1
-2
@@ -43,8 +43,7 @@ fun createSynthesizedInvokes(functions: Collection<FunctionDescriptor>): Collect
|
|||||||
val containerClassId = (invoke.containingDeclaration as ClassDescriptor).classId
|
val containerClassId = (invoke.containingDeclaration as ClassDescriptor).classId
|
||||||
val synthesized = if (containerClassId != null && isBuiltinFunctionClass(containerClassId)) {
|
val synthesized = if (containerClassId != null && isBuiltinFunctionClass(containerClassId)) {
|
||||||
createSynthesizedFunctionWithFirstParameterAsReceiver(invoke)
|
createSynthesizedFunctionWithFirstParameterAsReceiver(invoke)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val invokeDeclaration = invoke.overriddenDescriptors.singleOrNull()
|
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 synthesizedSuperFun = createSynthesizedFunctionWithFirstParameterAsReceiver(invokeDeclaration)
|
||||||
|
|||||||
+8
-3
@@ -36,7 +36,7 @@ enum class WrongResolutionToClassifier(val message: (Name) -> String) {
|
|||||||
OBJECT_AS_FUNCTION({ "Function 'invoke()' is not found in object $it" })
|
OBJECT_AS_FUNCTION({ "Function 'invoke()' is not found in object $it" })
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class ErrorCandidate<out D: DeclarationDescriptor>(val descriptor: D) {
|
sealed class ErrorCandidate<out D : DeclarationDescriptor>(val descriptor: D) {
|
||||||
class Classifier(
|
class Classifier(
|
||||||
classifierDescriptor: ClassifierDescriptor,
|
classifierDescriptor: ClassifierDescriptor,
|
||||||
val kind: WrongResolutionToClassifier
|
val kind: WrongResolutionToClassifier
|
||||||
@@ -72,7 +72,9 @@ private class ErrorCandidateContext(
|
|||||||
) {
|
) {
|
||||||
val result = SmartList<ErrorCandidate<*>>()
|
val result = SmartList<ErrorCandidate<*>>()
|
||||||
|
|
||||||
fun add(errorCandidate: ErrorCandidate<*>) { result.add(errorCandidate) }
|
fun add(errorCandidate: ErrorCandidate<*>) {
|
||||||
|
result.add(errorCandidate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ErrorCandidateContext.asClassifierCall(asFunction: Boolean) {
|
private fun ErrorCandidateContext.asClassifierCall(asFunction: Boolean) {
|
||||||
@@ -92,7 +94,10 @@ private fun ErrorCandidateContext.asClassifierCall(asFunction: Boolean) {
|
|||||||
add(ErrorCandidate.Classifier(classifier, kind))
|
add(ErrorCandidate.Classifier(classifier, kind))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ErrorCandidateContext.getWrongResolutionToClassifier(classifier: ClassifierDescriptor, asFunction: Boolean): WrongResolutionToClassifier? =
|
private fun ErrorCandidateContext.getWrongResolutionToClassifier(
|
||||||
|
classifier: ClassifierDescriptor,
|
||||||
|
asFunction: Boolean
|
||||||
|
): WrongResolutionToClassifier? =
|
||||||
when (classifier) {
|
when (classifier) {
|
||||||
is TypeAliasDescriptor -> classifier.classDescriptor?.let { getWrongResolutionToClassifier(it, asFunction) }
|
is TypeAliasDescriptor -> classifier.classDescriptor?.let { getWrongResolutionToClassifier(it, asFunction) }
|
||||||
|
|
||||||
|
|||||||
+13
-11
@@ -64,7 +64,8 @@ interface CandidateWithBoundDispatchReceiver {
|
|||||||
val dispatchReceiver: ReceiverValueWithSmartCastInfo?
|
val dispatchReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getResultApplicability(diagnostics: Collection<KotlinCallDiagnostic>) = diagnostics.maxBy { it.candidateApplicability }?.candidateApplicability
|
fun getResultApplicability(diagnostics: Collection<KotlinCallDiagnostic>) =
|
||||||
|
diagnostics.maxBy { it.candidateApplicability }?.candidateApplicability
|
||||||
?: RESOLVED
|
?: RESOLVED
|
||||||
|
|
||||||
enum class ResolutionCandidateApplicability {
|
enum class ResolutionCandidateApplicability {
|
||||||
@@ -80,30 +81,31 @@ enum class ResolutionCandidateApplicability {
|
|||||||
HIDDEN, // removed from resolve
|
HIDDEN, // removed from resolve
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ResolutionDiagnostic(candidateApplicability: ResolutionCandidateApplicability): KotlinCallDiagnostic(candidateApplicability) {
|
abstract class ResolutionDiagnostic(candidateApplicability: ResolutionCandidateApplicability) :
|
||||||
|
KotlinCallDiagnostic(candidateApplicability) {
|
||||||
override fun report(reporter: DiagnosticReporter) {
|
override fun report(reporter: DiagnosticReporter) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo error for this access from nested class
|
// 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) {
|
override fun report(reporter: DiagnosticReporter) {
|
||||||
reporter.onCall(this)
|
reporter.onCall(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NestedClassViaInstanceReference(val classDescriptor: ClassDescriptor): ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE)
|
class NestedClassViaInstanceReference(val classDescriptor: ClassDescriptor) : ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE)
|
||||||
class InnerClassViaStaticReference(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 UnsupportedInnerClassCall(val message: String) : ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE)
|
||||||
class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType): ResolutionDiagnostic(RESOLVED)
|
class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType) : ResolutionDiagnostic(RESOLVED)
|
||||||
|
|
||||||
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED) // todo discuss and change to INAPPLICABLE
|
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED) // todo discuss and change to INAPPLICABLE
|
||||||
object LowPriorityDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
object LowPriorityDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
||||||
object DynamicDescriptorDiagnostic: ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
object DynamicDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
||||||
object UnstableSmartCastDiagnostic: ResolutionDiagnostic(MAY_THROW_RUNTIME_ERROR)
|
object UnstableSmartCastDiagnostic : ResolutionDiagnostic(MAY_THROW_RUNTIME_ERROR)
|
||||||
object HiddenExtensionRelatedToDynamicTypes: ResolutionDiagnostic(HIDDEN)
|
object HiddenExtensionRelatedToDynamicTypes : ResolutionDiagnostic(HIDDEN)
|
||||||
object HiddenDescriptor: ResolutionDiagnostic(HIDDEN)
|
object HiddenDescriptor : ResolutionDiagnostic(HIDDEN)
|
||||||
|
|
||||||
object InvokeConventionCallNoOperatorModifier : ResolutionDiagnostic(CONVENTION_ERROR)
|
object InvokeConventionCallNoOperatorModifier : ResolutionDiagnostic(CONVENTION_ERROR)
|
||||||
object InfixCallNoInfixModifier : ResolutionDiagnostic(CONVENTION_ERROR)
|
object InfixCallNoInfixModifier : ResolutionDiagnostic(CONVENTION_ERROR)
|
||||||
|
|||||||
+41
-15
@@ -38,10 +38,9 @@ abstract class AbstractInvokeTowerProcessor<C : Candidate>(
|
|||||||
private inner class VariableInvokeProcessor(
|
private inner class VariableInvokeProcessor(
|
||||||
var variableCandidate: C,
|
var variableCandidate: C,
|
||||||
val invokeProcessor: ScopeTowerProcessor<C>
|
val invokeProcessor: ScopeTowerProcessor<C>
|
||||||
): ScopeTowerProcessor<C> {
|
) : ScopeTowerProcessor<C> {
|
||||||
|
|
||||||
override fun process(data: TowerData)
|
override fun process(data: TowerData) = invokeProcessor.process(data).map { candidateGroup ->
|
||||||
= invokeProcessor.process(data).map { candidateGroup ->
|
|
||||||
candidateGroup.map { factoryProviderForInvoke.transformCandidate(variableCandidate, it) }
|
candidateGroup.map { factoryProviderForInvoke.transformCandidate(variableCandidate, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,14 +103,23 @@ class InvokeTowerProcessor<C : Candidate>(
|
|||||||
explicitReceiver: DetailedReceiver?
|
explicitReceiver: DetailedReceiver?
|
||||||
) : AbstractInvokeTowerProcessor<C>(
|
) : AbstractInvokeTowerProcessor<C>(
|
||||||
factoryProviderForInvoke,
|
factoryProviderForInvoke,
|
||||||
createVariableAndObjectProcessor(scopeTower, name, factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = false), explicitReceiver)
|
createVariableAndObjectProcessor(
|
||||||
|
scopeTower,
|
||||||
|
name,
|
||||||
|
factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = false),
|
||||||
|
explicitReceiver
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// todo filter by operator
|
// todo filter by operator
|
||||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C>? {
|
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C>? {
|
||||||
val (variableReceiver, invokeContext) = factoryProviderForInvoke.factoryForInvoke(variableCandidate, useExplicitReceiver = false)
|
val (variableReceiver, invokeContext) = factoryProviderForInvoke.factoryForInvoke(variableCandidate, useExplicitReceiver = false)
|
||||||
?: return null
|
?: return null
|
||||||
return ExplicitReceiverScopeTowerProcessor(scopeTower, invokeContext, variableReceiver) { getFunctions(OperatorNameConventions.INVOKE, it) }
|
return ExplicitReceiverScopeTowerProcessor(
|
||||||
|
scopeTower,
|
||||||
|
invokeContext,
|
||||||
|
variableReceiver
|
||||||
|
) { getFunctions(OperatorNameConventions.INVOKE, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mayDataBeApplicable(data: TowerData) =
|
override fun mayDataBeApplicable(data: TowerData) =
|
||||||
@@ -136,7 +144,12 @@ class InvokeExtensionTowerProcessor<C : Candidate>(
|
|||||||
private val explicitReceiver: ReceiverValueWithSmartCastInfo?
|
private val explicitReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
) : AbstractInvokeTowerProcessor<C>(
|
) : AbstractInvokeTowerProcessor<C>(
|
||||||
factoryProviderForInvoke,
|
factoryProviderForInvoke,
|
||||||
createVariableAndObjectProcessor(scopeTower, name, factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = true), explicitReceiver = null)
|
createVariableAndObjectProcessor(
|
||||||
|
scopeTower,
|
||||||
|
name,
|
||||||
|
factoryProviderForInvoke.factoryForVariable(stripExplicitReceiver = true),
|
||||||
|
explicitReceiver = null
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C>? {
|
override fun createInvokeProcessor(variableCandidate: C): ScopeTowerProcessor<C>? {
|
||||||
@@ -162,11 +175,23 @@ private class InvokeExtensionScopeTowerProcessor<C : Candidate>(
|
|||||||
|
|
||||||
override fun simpleProcess(data: TowerData): Collection<C> {
|
override fun simpleProcess(data: TowerData): Collection<C> {
|
||||||
if (explicitReceiver != null && data == TowerData.Empty) {
|
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) {
|
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()
|
return emptyList()
|
||||||
@@ -204,18 +229,19 @@ fun <C : Candidate> createCallTowerProcessorForExplicitInvoke(
|
|||||||
return if (invokeExtensionDescriptor == null) {
|
return if (invokeExtensionDescriptor == null) {
|
||||||
// case 1.(foo())(), where foo() isn't extension function
|
// case 1.(foo())(), where foo() isn't extension function
|
||||||
KnownResultProcessor(emptyList())
|
KnownResultProcessor(emptyList())
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
InvokeExtensionScopeTowerProcessor(functionContext, invokeExtensionDescriptor, explicitReceiver = explicitReceiver)
|
InvokeExtensionScopeTowerProcessor(functionContext, invokeExtensionDescriptor, explicitReceiver = explicitReceiver)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
val usualInvoke = ExplicitReceiverScopeTowerProcessor(
|
||||||
val usualInvoke = ExplicitReceiverScopeTowerProcessor(scopeTower, functionContext, expressionForInvoke) { getFunctions(OperatorNameConventions.INVOKE, it) } // todo operator
|
scopeTower,
|
||||||
|
functionContext,
|
||||||
|
expressionForInvoke
|
||||||
|
) { getFunctions(OperatorNameConventions.INVOKE, it) } // todo operator
|
||||||
|
|
||||||
return if (invokeExtensionDescriptor == null) {
|
return if (invokeExtensionDescriptor == null) {
|
||||||
usualInvoke
|
usualInvoke
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
PrioritizedCompositeScopeTowerProcessor(
|
PrioritizedCompositeScopeTowerProcessor(
|
||||||
usualInvoke,
|
usualInvoke,
|
||||||
InvokeExtensionScopeTowerProcessor(functionContext, invokeExtensionDescriptor, explicitReceiver = null)
|
InvokeExtensionScopeTowerProcessor(functionContext, invokeExtensionDescriptor, explicitReceiver = null)
|
||||||
|
|||||||
+57
-26
@@ -25,9 +25,8 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastI
|
|||||||
|
|
||||||
class KnownResultProcessor<out C>(
|
class KnownResultProcessor<out C>(
|
||||||
val result: Collection<C>
|
val result: Collection<C>
|
||||||
): ScopeTowerProcessor<C> {
|
) : ScopeTowerProcessor<C> {
|
||||||
override fun process(data: TowerData)
|
override fun process(data: TowerData) = if (data == TowerData.Empty) listOfNotNull(result.takeIf { it.isNotEmpty() }) else emptyList()
|
||||||
= if (data == TowerData.Empty) listOfNotNull(result.takeIf { it.isNotEmpty() }) else emptyList()
|
|
||||||
|
|
||||||
override fun recordLookups(skippedData: Collection<TowerData>, name: Name) {}
|
override fun recordLookups(skippedData: Collection<TowerData>, name: Name) {}
|
||||||
}
|
}
|
||||||
@@ -47,7 +46,7 @@ class PrioritizedCompositeScopeTowerProcessor<out C>(
|
|||||||
// use this if all processors has same priority
|
// use this if all processors has same priority
|
||||||
class SamePriorityCompositeScopeTowerProcessor<out C>(
|
class SamePriorityCompositeScopeTowerProcessor<out C>(
|
||||||
private vararg val processors: SimpleScopeTowerProcessor<C>
|
private vararg val processors: SimpleScopeTowerProcessor<C>
|
||||||
): SimpleScopeTowerProcessor<C> {
|
) : SimpleScopeTowerProcessor<C> {
|
||||||
override fun simpleProcess(data: TowerData): Collection<C> = processors.flatMap { it.simpleProcess(data) }
|
override fun simpleProcess(data: TowerData): Collection<C> = processors.flatMap { it.simpleProcess(data) }
|
||||||
override fun recordLookups(skippedData: Collection<TowerData>, name: Name) {
|
override fun recordLookups(skippedData: Collection<TowerData>, name: Name) {
|
||||||
processors.forEach { it.recordLookups(skippedData, name) }
|
processors.forEach { it.recordLookups(skippedData, name) }
|
||||||
@@ -55,19 +54,19 @@ class SamePriorityCompositeScopeTowerProcessor<out C>(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal abstract class AbstractSimpleScopeTowerProcessor<C: Candidate>(
|
internal abstract class AbstractSimpleScopeTowerProcessor<C : Candidate>(
|
||||||
val candidateFactory: CandidateFactory<C>
|
val candidateFactory: CandidateFactory<C>
|
||||||
) : SimpleScopeTowerProcessor<C>
|
) : SimpleScopeTowerProcessor<C>
|
||||||
|
|
||||||
private typealias CandidatesCollector =
|
private typealias CandidatesCollector =
|
||||||
ScopeTowerLevel.(extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection<CandidateWithBoundDispatchReceiver>
|
ScopeTowerLevel.(extensionReceiver: ReceiverValueWithSmartCastInfo?) -> Collection<CandidateWithBoundDispatchReceiver>
|
||||||
|
|
||||||
internal class ExplicitReceiverScopeTowerProcessor<C: Candidate>(
|
internal class ExplicitReceiverScopeTowerProcessor<C : Candidate>(
|
||||||
val scopeTower: ImplicitScopeTower,
|
val scopeTower: ImplicitScopeTower,
|
||||||
context: CandidateFactory<C>,
|
context: CandidateFactory<C>,
|
||||||
val explicitReceiver: ReceiverValueWithSmartCastInfo,
|
val explicitReceiver: ReceiverValueWithSmartCastInfo,
|
||||||
val collectCandidates: CandidatesCollector
|
val collectCandidates: CandidatesCollector
|
||||||
): AbstractSimpleScopeTowerProcessor<C>(context) {
|
) : AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||||
override fun simpleProcess(data: TowerData): Collection<C> {
|
override fun simpleProcess(data: TowerData): Collection<C> {
|
||||||
return when (data) {
|
return when (data) {
|
||||||
TowerData.Empty -> resolveAsMember()
|
TowerData.Empty -> resolveAsMember()
|
||||||
@@ -80,7 +79,13 @@ internal class ExplicitReceiverScopeTowerProcessor<C: Candidate>(
|
|||||||
val members = mutableListOf<C>()
|
val members = mutableListOf<C>()
|
||||||
for (memberCandidate in MemberScopeTowerLevel(scopeTower, explicitReceiver).collectCandidates(null)) {
|
for (memberCandidate in MemberScopeTowerLevel(scopeTower, explicitReceiver).collectCandidates(null)) {
|
||||||
if (!memberCandidate.requiresExtensionReceiver) {
|
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
|
return members
|
||||||
@@ -90,7 +95,13 @@ internal class ExplicitReceiverScopeTowerProcessor<C: Candidate>(
|
|||||||
val extensions = mutableListOf<C>()
|
val extensions = mutableListOf<C>()
|
||||||
for (extensionCandidate in level.collectCandidates(explicitReceiver)) {
|
for (extensionCandidate in level.collectCandidates(explicitReceiver)) {
|
||||||
if (extensionCandidate.requiresExtensionReceiver) {
|
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
|
return extensions
|
||||||
@@ -105,19 +116,25 @@ internal class ExplicitReceiverScopeTowerProcessor<C: Candidate>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class QualifierScopeTowerProcessor<C: Candidate>(
|
private class QualifierScopeTowerProcessor<C : Candidate>(
|
||||||
val scopeTower: ImplicitScopeTower,
|
val scopeTower: ImplicitScopeTower,
|
||||||
context: CandidateFactory<C>,
|
context: CandidateFactory<C>,
|
||||||
val qualifier: QualifierReceiver,
|
val qualifier: QualifierReceiver,
|
||||||
val collectCandidates: CandidatesCollector
|
val collectCandidates: CandidatesCollector
|
||||||
): AbstractSimpleScopeTowerProcessor<C>(context) {
|
) : AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||||
override fun simpleProcess(data: TowerData): Collection<C> {
|
override fun simpleProcess(data: TowerData): Collection<C> {
|
||||||
if (data != TowerData.Empty) return emptyList()
|
if (data != TowerData.Empty) return emptyList()
|
||||||
|
|
||||||
val staticMembers = mutableListOf<C>()
|
val staticMembers = mutableListOf<C>()
|
||||||
for (towerCandidate in QualifierScopeTowerLevel(scopeTower, qualifier).collectCandidates(null)) {
|
for (towerCandidate in QualifierScopeTowerLevel(scopeTower, qualifier).collectCandidates(null)) {
|
||||||
if (!towerCandidate.requiresExtensionReceiver) {
|
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
|
return staticMembers
|
||||||
@@ -127,17 +144,22 @@ private class QualifierScopeTowerProcessor<C: Candidate>(
|
|||||||
override fun recordLookups(skippedData: Collection<TowerData>, name: Name) {}
|
override fun recordLookups(skippedData: Collection<TowerData>, name: Name) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NoExplicitReceiverScopeTowerProcessor<C: Candidate>(
|
private class NoExplicitReceiverScopeTowerProcessor<C : Candidate>(
|
||||||
context: CandidateFactory<C>,
|
context: CandidateFactory<C>,
|
||||||
val collectCandidates: CandidatesCollector
|
val collectCandidates: CandidatesCollector
|
||||||
) : AbstractSimpleScopeTowerProcessor<C>(context) {
|
) : AbstractSimpleScopeTowerProcessor<C>(context) {
|
||||||
override fun simpleProcess(data: TowerData): Collection<C>
|
override fun simpleProcess(data: TowerData): Collection<C> = when (data) {
|
||||||
= when(data) {
|
|
||||||
is TowerData.TowerLevel -> {
|
is TowerData.TowerLevel -> {
|
||||||
val result = mutableListOf<C>()
|
val result = mutableListOf<C>()
|
||||||
for (towerCandidate in data.level.collectCandidates(null)) {
|
for (towerCandidate in data.level.collectCandidates(null)) {
|
||||||
if (!towerCandidate.requiresExtensionReceiver) {
|
if (!towerCandidate.requiresExtensionReceiver) {
|
||||||
result.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = null))
|
result.add(
|
||||||
|
candidateFactory.createCandidate(
|
||||||
|
towerCandidate,
|
||||||
|
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||||
|
extensionReceiver = null
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
@@ -146,7 +168,13 @@ private class NoExplicitReceiverScopeTowerProcessor<C: Candidate>(
|
|||||||
val result = mutableListOf<C>()
|
val result = mutableListOf<C>()
|
||||||
for (towerCandidate in data.level.collectCandidates(data.implicitReceiver)) {
|
for (towerCandidate in data.level.collectCandidates(data.implicitReceiver)) {
|
||||||
if (towerCandidate.requiresExtensionReceiver) {
|
if (towerCandidate.requiresExtensionReceiver) {
|
||||||
result.add(candidateFactory.createCandidate(towerCandidate, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, extensionReceiver = data.implicitReceiver))
|
result.add(
|
||||||
|
candidateFactory.createCandidate(
|
||||||
|
towerCandidate,
|
||||||
|
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER,
|
||||||
|
extensionReceiver = data.implicitReceiver
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
@@ -188,8 +216,9 @@ private fun <C : Candidate> createSimpleProcessor(
|
|||||||
explicitReceiver: DetailedReceiver?,
|
explicitReceiver: DetailedReceiver?,
|
||||||
classValueReceiver: Boolean,
|
classValueReceiver: Boolean,
|
||||||
collectCandidates: CandidatesCollector
|
collectCandidates: CandidatesCollector
|
||||||
) : ScopeTowerProcessor<C> {
|
): ScopeTowerProcessor<C> {
|
||||||
val withoutClassValueProcessor = createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver, collectCandidates)
|
val withoutClassValueProcessor =
|
||||||
|
createSimpleProcessorWithoutClassValueReceiver(scopeTower, context, explicitReceiver, collectCandidates)
|
||||||
|
|
||||||
if (classValueReceiver && explicitReceiver is QualifierReceiver) {
|
if (classValueReceiver && explicitReceiver is QualifierReceiver) {
|
||||||
val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return withoutClassValueProcessor
|
val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return withoutClassValueProcessor
|
||||||
@@ -211,23 +240,26 @@ fun <C : Candidate> createCallableReferenceProcessor(
|
|||||||
return SamePriorityCompositeScopeTowerProcessor(variable, function)
|
return SamePriorityCompositeScopeTowerProcessor(variable, function)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <C : Candidate> createVariableProcessor(scopeTower: ImplicitScopeTower, name: Name,
|
fun <C : Candidate> createVariableProcessor(
|
||||||
|
scopeTower: ImplicitScopeTower, name: Name,
|
||||||
context: CandidateFactory<C>, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
|
context: CandidateFactory<C>, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
|
||||||
) = createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getVariables(name, it) }
|
) = createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getVariables(name, it) }
|
||||||
|
|
||||||
fun <C : Candidate> createVariableAndObjectProcessor(scopeTower: ImplicitScopeTower, name: Name,
|
fun <C : Candidate> createVariableAndObjectProcessor(
|
||||||
|
scopeTower: ImplicitScopeTower, name: Name,
|
||||||
context: CandidateFactory<C>, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
|
context: CandidateFactory<C>, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
|
||||||
) = PrioritizedCompositeScopeTowerProcessor(
|
) = PrioritizedCompositeScopeTowerProcessor(
|
||||||
createVariableProcessor(scopeTower, name, context, explicitReceiver),
|
createVariableProcessor(scopeTower, name, context, explicitReceiver),
|
||||||
createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getObjects(name, it) }
|
createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getObjects(name, it) }
|
||||||
)
|
)
|
||||||
|
|
||||||
fun <C : Candidate> createSimpleFunctionProcessor(scopeTower: ImplicitScopeTower, name: Name,
|
fun <C : Candidate> createSimpleFunctionProcessor(
|
||||||
|
scopeTower: ImplicitScopeTower, name: Name,
|
||||||
context: CandidateFactory<C>, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
|
context: CandidateFactory<C>, explicitReceiver: DetailedReceiver?, classValueReceiver: Boolean = true
|
||||||
) = createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getFunctions(name, it) }
|
) = createSimpleProcessor(scopeTower, context, explicitReceiver, classValueReceiver) { getFunctions(name, it) }
|
||||||
|
|
||||||
|
|
||||||
fun <С: Candidate> createFunctionProcessor(
|
fun <С : Candidate> createFunctionProcessor(
|
||||||
scopeTower: ImplicitScopeTower,
|
scopeTower: ImplicitScopeTower,
|
||||||
name: Name,
|
name: Name,
|
||||||
simpleContext: CandidateFactory<С>,
|
simpleContext: CandidateFactory<С>,
|
||||||
@@ -250,15 +282,14 @@ fun <С: Candidate> createFunctionProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun <C: Candidate> createProcessorWithReceiverValueOrEmpty(
|
fun <C : Candidate> createProcessorWithReceiverValueOrEmpty(
|
||||||
explicitReceiver: DetailedReceiver?,
|
explicitReceiver: DetailedReceiver?,
|
||||||
create: (ReceiverValueWithSmartCastInfo?) -> ScopeTowerProcessor<C>
|
create: (ReceiverValueWithSmartCastInfo?) -> ScopeTowerProcessor<C>
|
||||||
): ScopeTowerProcessor<C> {
|
): ScopeTowerProcessor<C> {
|
||||||
return if (explicitReceiver is QualifierReceiver) {
|
return if (explicitReceiver is QualifierReceiver) {
|
||||||
explicitReceiver.classValueReceiverWithSmartCastInfo?.let(create)
|
explicitReceiver.classValueReceiverWithSmartCastInfo?.let(create)
|
||||||
?: KnownResultProcessor<C>(listOf())
|
?: KnownResultProcessor<C>(listOf())
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
create(explicitReceiver as ReceiverValueWithSmartCastInfo?)
|
create(explicitReceiver as ReceiverValueWithSmartCastInfo?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ import java.util.*
|
|||||||
|
|
||||||
internal abstract class AbstractScopeTowerLevel(
|
internal abstract class AbstractScopeTowerLevel(
|
||||||
protected val scopeTower: ImplicitScopeTower
|
protected val scopeTower: ImplicitScopeTower
|
||||||
): ScopeTowerLevel {
|
) : ScopeTowerLevel {
|
||||||
protected val location: LookupLocation get() = scopeTower.location
|
protected val location: LookupLocation get() = scopeTower.location
|
||||||
|
|
||||||
protected fun createCandidateDescriptor(
|
protected fun createCandidateDescriptor(
|
||||||
@@ -57,8 +57,7 @@ internal abstract class AbstractScopeTowerLevel(
|
|||||||
|
|
||||||
if (ErrorUtils.isError(descriptor)) {
|
if (ErrorUtils.isError(descriptor)) {
|
||||||
diagnostics.add(ErrorDescriptorDiagnostic)
|
diagnostics.add(ErrorDescriptorDiagnostic)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (descriptor.hasLowPriorityInOverloadResolution() || descriptor.isLowPriorityFromStdlibJre7Or8()) {
|
if (descriptor.hasLowPriorityInOverloadResolution() || descriptor.isLowPriorityFromStdlibJre7Or8()) {
|
||||||
diagnostics.add(LowPriorityDescriptorDiagnostic)
|
diagnostics.add(LowPriorityDescriptorDiagnostic)
|
||||||
}
|
}
|
||||||
@@ -83,7 +82,7 @@ internal abstract class AbstractScopeTowerLevel(
|
|||||||
internal class MemberScopeTowerLevel(
|
internal class MemberScopeTowerLevel(
|
||||||
scopeTower: ImplicitScopeTower,
|
scopeTower: ImplicitScopeTower,
|
||||||
val dispatchReceiver: ReceiverValueWithSmartCastInfo
|
val dispatchReceiver: ReceiverValueWithSmartCastInfo
|
||||||
): AbstractScopeTowerLevel(scopeTower) {
|
) : AbstractScopeTowerLevel(scopeTower) {
|
||||||
|
|
||||||
private val syntheticScopes = scopeTower.syntheticScopes
|
private val syntheticScopes = scopeTower.syntheticScopes
|
||||||
private val isNewInferenceEnabled = scopeTower.isNewInferenceEnabled
|
private val isNewInferenceEnabled = scopeTower.isNewInferenceEnabled
|
||||||
@@ -113,8 +112,7 @@ internal class MemberScopeTowerLevel(
|
|||||||
if (dispatchReceiver.possibleTypes.isNotEmpty()) {
|
if (dispatchReceiver.possibleTypes.isNotEmpty()) {
|
||||||
if (unstableCandidates == null) {
|
if (unstableCandidates == null) {
|
||||||
result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() })
|
result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() })
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.addAll(unstableCandidates.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() })
|
result.addAll(unstableCandidates.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,8 +140,14 @@ internal class MemberScopeTowerLevel(
|
|||||||
override fun get(key: KotlinType): TypeProjection? = null
|
override fun get(key: KotlinType): TypeProjection? = null
|
||||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = when (position) {
|
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = when (position) {
|
||||||
Variance.INVARIANT -> null
|
Variance.INVARIANT -> null
|
||||||
Variance.OUT_VARIANCE -> approximator.approximateToSuperType(topLevelType.unwrap(), TypeApproximatorConfiguration.CapturedTypesApproximation)
|
Variance.OUT_VARIANCE -> approximator.approximateToSuperType(
|
||||||
Variance.IN_VARIANCE -> approximator.approximateToSubType(topLevelType.unwrap(), TypeApproximatorConfiguration.CapturedTypesApproximation)
|
topLevelType.unwrap(),
|
||||||
|
TypeApproximatorConfiguration.CapturedTypesApproximation
|
||||||
|
)
|
||||||
|
Variance.IN_VARIANCE -> approximator.approximateToSubType(
|
||||||
|
topLevelType.unwrap(),
|
||||||
|
TypeApproximatorConfiguration.CapturedTypesApproximation
|
||||||
|
)
|
||||||
} ?: topLevelType
|
} ?: topLevelType
|
||||||
}
|
}
|
||||||
return substitute(TypeSubstitutor.create(wrappedSubstitution))
|
return substitute(TypeSubstitutor.create(wrappedSubstitution))
|
||||||
@@ -156,15 +160,24 @@ internal class MemberScopeTowerLevel(
|
|||||||
return ReceiverValueWithSmartCastInfo(newReceiverValue, possibleTypes, isStable)
|
return ReceiverValueWithSmartCastInfo(newReceiverValue, possibleTypes, isStable)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver> {
|
override fun getVariables(
|
||||||
|
name: Name,
|
||||||
|
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
|
): Collection<CandidateWithBoundDispatchReceiver> {
|
||||||
return collectMembers { getContributedVariables(name, location) }
|
return collectMembers { getContributedVariables(name, location) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver> {
|
override fun getObjects(
|
||||||
|
name: Name,
|
||||||
|
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
|
): Collection<CandidateWithBoundDispatchReceiver> {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver> {
|
override fun getFunctions(
|
||||||
|
name: Name,
|
||||||
|
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
|
): Collection<CandidateWithBoundDispatchReceiver> {
|
||||||
return collectMembers {
|
return collectMembers {
|
||||||
getContributedFunctions(name, location) + it.getInnerConstructors(name, location) +
|
getContributedFunctions(name, location) + it.getInnerConstructors(name, location) +
|
||||||
syntheticScopes.collectSyntheticMemberFunctions(listOfNotNull(it), name, location)
|
syntheticScopes.collectSyntheticMemberFunctions(listOfNotNull(it), name, location)
|
||||||
@@ -179,7 +192,8 @@ 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
|
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = qualifier.staticScope
|
||||||
.getContributedVariables(name, location).map {
|
.getContributedVariables(name, location).map {
|
||||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||||
@@ -191,10 +205,12 @@ internal class QualifierScopeTowerLevel(scopeTower: ImplicitScopeTower, val qual
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = qualifier.staticScope
|
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) = qualifier.staticScope
|
||||||
.getContributedFunctionsAndConstructors(name,
|
.getContributedFunctionsAndConstructors(
|
||||||
|
name,
|
||||||
location,
|
location,
|
||||||
scopeTower.syntheticScopes,
|
scopeTower.syntheticScopes,
|
||||||
qualifier.staticScope).map {
|
qualifier.staticScope
|
||||||
|
).map {
|
||||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,21 +225,29 @@ internal open class ScopeBasedTowerLevel protected constructor(
|
|||||||
|
|
||||||
internal constructor(scopeTower: ImplicitScopeTower, lexicalScope: LexicalScope) : this(scopeTower, lexicalScope as ResolutionScope)
|
internal constructor(scopeTower: ImplicitScopeTower, lexicalScope: LexicalScope) : this(scopeTower, lexicalScope as ResolutionScope)
|
||||||
|
|
||||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver>
|
override fun getVariables(
|
||||||
= resolutionScope.getContributedVariables(name, location).map {
|
name: Name,
|
||||||
|
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
|
): Collection<CandidateWithBoundDispatchReceiver> = resolutionScope.getContributedVariables(name, location).map {
|
||||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver>
|
override fun getObjects(
|
||||||
= resolutionScope.getContributedObjectVariables(name, location).map {
|
name: Name,
|
||||||
|
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
|
): Collection<CandidateWithBoundDispatchReceiver> = resolutionScope.getContributedObjectVariables(name, location).map {
|
||||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver>
|
override fun getFunctions(
|
||||||
= resolutionScope.getContributedFunctionsAndConstructors(name,
|
name: Name,
|
||||||
|
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
|
): Collection<CandidateWithBoundDispatchReceiver> = resolutionScope.getContributedFunctionsAndConstructors(
|
||||||
|
name,
|
||||||
location,
|
location,
|
||||||
scopeTower.syntheticScopes,
|
scopeTower.syntheticScopes,
|
||||||
resolutionScope).map {
|
resolutionScope
|
||||||
|
).map {
|
||||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,19 +255,23 @@ internal open class ScopeBasedTowerLevel protected constructor(
|
|||||||
resolutionScope.recordLookup(name, location)
|
resolutionScope.recordLookup(name, location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ImportingScopeBasedTowerLevel(
|
internal class ImportingScopeBasedTowerLevel(
|
||||||
scopeTower: ImplicitScopeTower,
|
scopeTower: ImplicitScopeTower,
|
||||||
importingScope: ImportingScope
|
importingScope: ImportingScope
|
||||||
): ScopeBasedTowerLevel(scopeTower, importingScope)
|
) : ScopeBasedTowerLevel(scopeTower, importingScope)
|
||||||
|
|
||||||
internal class SyntheticScopeBasedTowerLevel(
|
internal class SyntheticScopeBasedTowerLevel(
|
||||||
scopeTower: ImplicitScopeTower,
|
scopeTower: ImplicitScopeTower,
|
||||||
private val syntheticScopes: SyntheticScopes
|
private val syntheticScopes: SyntheticScopes
|
||||||
): AbstractScopeTowerLevel(scopeTower) {
|
) : AbstractScopeTowerLevel(scopeTower) {
|
||||||
private val ReceiverValueWithSmartCastInfo.allTypes: Set<KotlinType>
|
private val ReceiverValueWithSmartCastInfo.allTypes: Set<KotlinType>
|
||||||
get() = possibleTypes + receiverValue.type
|
get() = possibleTypes + receiverValue.type
|
||||||
|
|
||||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?): Collection<CandidateWithBoundDispatchReceiver> {
|
override fun getVariables(
|
||||||
|
name: Name,
|
||||||
|
extensionReceiver: ReceiverValueWithSmartCastInfo?
|
||||||
|
): Collection<CandidateWithBoundDispatchReceiver> {
|
||||||
if (extensionReceiver == null) return emptyList()
|
if (extensionReceiver == null) return emptyList()
|
||||||
|
|
||||||
return syntheticScopes.collectSyntheticExtensionProperties(extensionReceiver.allTypes, name, location).map {
|
return syntheticScopes.collectSyntheticExtensionProperties(extensionReceiver.allTypes, name, location).map {
|
||||||
@@ -267,15 +295,15 @@ internal class SyntheticScopeBasedTowerLevel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class HidesMembersTowerLevel(scopeTower: ImplicitScopeTower): AbstractScopeTowerLevel(scopeTower) {
|
internal class HidesMembersTowerLevel(scopeTower: ImplicitScopeTower) : AbstractScopeTowerLevel(scopeTower) {
|
||||||
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?)
|
override fun getVariables(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) =
|
||||||
= getCandidates(name, extensionReceiver, LexicalScope::collectVariables)
|
getCandidates(name, extensionReceiver, LexicalScope::collectVariables)
|
||||||
|
|
||||||
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?)
|
override fun getObjects(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) =
|
||||||
= emptyList<CandidateWithBoundDispatchReceiver>()
|
emptyList<CandidateWithBoundDispatchReceiver>()
|
||||||
|
|
||||||
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?)
|
override fun getFunctions(name: Name, extensionReceiver: ReceiverValueWithSmartCastInfo?) =
|
||||||
= getCandidates(name, extensionReceiver, LexicalScope::collectFunctions)
|
getCandidates(name, extensionReceiver, LexicalScope::collectFunctions)
|
||||||
|
|
||||||
private fun getCandidates(
|
private fun getCandidates(
|
||||||
name: Name,
|
name: Name,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ interface Candidate {
|
|||||||
val resultingApplicability: ResolutionCandidateApplicability
|
val resultingApplicability: ResolutionCandidateApplicability
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CandidateFactory<out C: Candidate> {
|
interface CandidateFactory<out C : Candidate> {
|
||||||
fun createCandidate(
|
fun createCandidate(
|
||||||
towerCandidate: CandidateWithBoundDispatchReceiver,
|
towerCandidate: CandidateWithBoundDispatchReceiver,
|
||||||
explicitReceiverKind: ExplicitReceiverKind,
|
explicitReceiverKind: ExplicitReceiverKind,
|
||||||
@@ -59,7 +59,7 @@ interface CandidateFactoryProviderForInvoke<C : Candidate> {
|
|||||||
|
|
||||||
sealed class TowerData {
|
sealed class TowerData {
|
||||||
object Empty : TowerData()
|
object Empty : TowerData()
|
||||||
class OnlyImplicitReceiver(val implicitReceiver: ReceiverValueWithSmartCastInfo): TowerData()
|
class OnlyImplicitReceiver(val implicitReceiver: ReceiverValueWithSmartCastInfo) : TowerData()
|
||||||
class TowerLevel(val level: ScopeTowerLevel) : TowerData()
|
class TowerLevel(val level: ScopeTowerLevel) : TowerData()
|
||||||
class BothTowerLevelAndImplicitReceiver(val level: ScopeTowerLevel, val implicitReceiver: ReceiverValueWithSmartCastInfo) : 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
|
// Has the same meaning as BothTowerLevelAndImplicitReceiver, but it's only used for names lookup, so it doesn't need implicit receiver
|
||||||
@@ -81,19 +81,18 @@ interface SimpleScopeTowerProcessor<out C> : ScopeTowerProcessor<C> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TowerResolver {
|
class TowerResolver {
|
||||||
fun <C: Candidate> runResolve(
|
fun <C : Candidate> runResolve(
|
||||||
scopeTower: ImplicitScopeTower,
|
scopeTower: ImplicitScopeTower,
|
||||||
processor: ScopeTowerProcessor<C>,
|
processor: ScopeTowerProcessor<C>,
|
||||||
useOrder: Boolean,
|
useOrder: Boolean,
|
||||||
name: Name
|
name: Name
|
||||||
): Collection<C> = scopeTower.run(processor, SuccessfulResultCollector(), useOrder, name)
|
): Collection<C> = scopeTower.run(processor, SuccessfulResultCollector(), useOrder, name)
|
||||||
|
|
||||||
fun <C: Candidate> collectAllCandidates(
|
fun <C : Candidate> collectAllCandidates(
|
||||||
scopeTower: ImplicitScopeTower,
|
scopeTower: ImplicitScopeTower,
|
||||||
processor: ScopeTowerProcessor<C>,
|
processor: ScopeTowerProcessor<C>,
|
||||||
name: Name
|
name: Name
|
||||||
): Collection<C>
|
): Collection<C> = scopeTower.run(processor, AllCandidatesCollector(), false, name)
|
||||||
= scopeTower.run(processor, AllCandidatesCollector(), false, name)
|
|
||||||
|
|
||||||
fun <C : Candidate> ImplicitScopeTower.run(
|
fun <C : Candidate> ImplicitScopeTower.run(
|
||||||
processor: ScopeTowerProcessor<C>,
|
processor: ScopeTowerProcessor<C>,
|
||||||
@@ -113,9 +112,9 @@ class TowerResolver {
|
|||||||
private val skippedDataForLookup = mutableListOf<TowerData>()
|
private val skippedDataForLookup = mutableListOf<TowerData>()
|
||||||
|
|
||||||
private val localLevels: Collection<ScopeTowerLevel> by lazy(LazyThreadSafetyMode.NONE) {
|
private val localLevels: Collection<ScopeTowerLevel> by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
implicitScopeTower.lexicalScope.parentsWithSelf.
|
implicitScopeTower.lexicalScope.parentsWithSelf.filterIsInstance<LexicalScope>()
|
||||||
filterIsInstance<LexicalScope>().filter { it.kind.withLocalDescriptors && it.mayFitForName(name) }.
|
.filter { it.kind.withLocalDescriptors && it.mayFitForName(name) }.map { ScopeBasedTowerLevel(implicitScopeTower, it) }
|
||||||
map { ScopeBasedTowerLevel(implicitScopeTower, it) }.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val nonLocalLevels: Collection<ScopeTowerLevel> by lazy(LazyThreadSafetyMode.NONE) {
|
private val nonLocalLevels: Collection<ScopeTowerLevel> by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
@@ -131,8 +130,7 @@ class TowerResolver {
|
|||||||
fun addLevel(scopeTowerLevel: ScopeTowerLevel, mayFitForName: Boolean) {
|
fun addLevel(scopeTowerLevel: ScopeTowerLevel, mayFitForName: Boolean) {
|
||||||
if (mayFitForName) {
|
if (mayFitForName) {
|
||||||
mainResult.add(scopeTowerLevel)
|
mainResult.add(scopeTowerLevel)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
skippedDataForLookup.add(TowerData.ForLookupForNoExplicitReceiver(scopeTowerLevel))
|
skippedDataForLookup.add(TowerData.ForLookupForNoExplicitReceiver(scopeTowerLevel))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,8 +150,7 @@ class TowerResolver {
|
|||||||
it.mayFitForName(name)
|
it.mayFitForName(name)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
addLevel(
|
addLevel(
|
||||||
ImportingScopeBasedTowerLevel(this@createNonLocalLevels, scope as ImportingScope),
|
ImportingScopeBasedTowerLevel(this@createNonLocalLevels, scope as ImportingScope),
|
||||||
scope.mayFitForName(name)
|
scope.mayFitForName(name)
|
||||||
@@ -203,8 +200,7 @@ class TowerResolver {
|
|||||||
implicitScopeTower.getImplicitReceiver(scope)
|
implicitScopeTower.getImplicitReceiver(scope)
|
||||||
?.let(this::processImplicitReceiver)
|
?.let(this::processImplicitReceiver)
|
||||||
?.let { return it }
|
?.let { return it }
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
TowerData.TowerLevel(ImportingScopeBasedTowerLevel(implicitScopeTower, scope as ImportingScope))
|
TowerData.TowerLevel(ImportingScopeBasedTowerLevel(implicitScopeTower, scope as ImportingScope))
|
||||||
.process(scope.mayFitForName(name))?.let { return it }
|
.process(scope.mayFitForName(name))?.let { return it }
|
||||||
}
|
}
|
||||||
@@ -279,8 +275,7 @@ class TowerResolver {
|
|||||||
|
|
||||||
val candidatesGroups = if (useOrder) {
|
val candidatesGroups = if (useOrder) {
|
||||||
processor.process(towerData)
|
processor.process(towerData)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
listOf(processor.process(towerData).flatMap { it })
|
listOf(processor.process(towerData).flatMap { it })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +296,7 @@ class TowerResolver {
|
|||||||
abstract fun pushCandidates(candidates: Collection<C>)
|
abstract fun pushCandidates(candidates: Collection<C>)
|
||||||
}
|
}
|
||||||
|
|
||||||
class AllCandidatesCollector<C : Candidate>: ResultCollector<C>() {
|
class AllCandidatesCollector<C : Candidate> : ResultCollector<C>() {
|
||||||
private val allCandidates = ArrayList<C>()
|
private val allCandidates = ArrayList<C>()
|
||||||
|
|
||||||
override fun getSuccessfulCandidates(): Collection<C>? = null
|
override fun getSuccessfulCandidates(): Collection<C>? = null
|
||||||
@@ -352,7 +347,8 @@ class TowerResolver {
|
|||||||
return moreSuitableGroup.filter { it.resultingApplicability == groupApplicability }
|
return moreSuitableGroup.filter { it.resultingApplicability == groupApplicability }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val Collection<C>.groupApplicability get() =
|
private val Collection<C>.groupApplicability
|
||||||
|
get() =
|
||||||
minBy { it.resultingApplicability }?.resultingApplicability ?: ResolutionCandidateApplicability.HIDDEN
|
minBy { it.resultingApplicability }?.resultingApplicability ?: ResolutionCandidateApplicability.HIDDEN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastI
|
|||||||
private val INAPPLICABLE_STATUSES = setOf(
|
private val INAPPLICABLE_STATUSES = setOf(
|
||||||
ResolutionCandidateApplicability.INAPPLICABLE,
|
ResolutionCandidateApplicability.INAPPLICABLE,
|
||||||
ResolutionCandidateApplicability.INAPPLICABLE_ARGUMENTS_MAPPING_ERROR,
|
ResolutionCandidateApplicability.INAPPLICABLE_ARGUMENTS_MAPPING_ERROR,
|
||||||
ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER)
|
ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||||
|
)
|
||||||
|
|
||||||
val ResolutionCandidateApplicability.isSuccess: Boolean
|
val ResolutionCandidateApplicability.isSuccess: Boolean
|
||||||
get() = this <= ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY
|
get() = this <= ResolutionCandidateApplicability.RESOLVED_LOW_PRIORITY
|
||||||
|
|||||||
+1
-2
@@ -21,8 +21,7 @@ import org.jetbrains.kotlin.descriptors.impl.DescriptorDerivedFromTypeAlias
|
|||||||
|
|
||||||
class FakeCallableDescriptorForTypeAliasObject(override val typeAliasDescriptor: TypeAliasDescriptor) :
|
class FakeCallableDescriptorForTypeAliasObject(override val typeAliasDescriptor: TypeAliasDescriptor) :
|
||||||
FakeCallableDescriptorForObject(typeAliasDescriptor.classDescriptor!!),
|
FakeCallableDescriptorForObject(typeAliasDescriptor.classDescriptor!!),
|
||||||
DescriptorDerivedFromTypeAlias
|
DescriptorDerivedFromTypeAlias {
|
||||||
{
|
|
||||||
override fun getReferencedDescriptor() =
|
override fun getReferencedDescriptor() =
|
||||||
typeAliasDescriptor
|
typeAliasDescriptor
|
||||||
|
|
||||||
|
|||||||
@@ -34,23 +34,28 @@ class LexicalChainedScope @JvmOverloads constructor(
|
|||||||
private val memberScopes: List<MemberScope>,
|
private val memberScopes: List<MemberScope>,
|
||||||
@Deprecated("This value is temporary hack for resolve -- don't use it!")
|
@Deprecated("This value is temporary hack for resolve -- don't use it!")
|
||||||
val isStaticScope: Boolean = false
|
val isStaticScope: Boolean = false
|
||||||
): LexicalScope {
|
) : LexicalScope {
|
||||||
override val parent = parent.takeSnapshot()
|
override val parent = parent.takeSnapshot()
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
|
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) =
|
||||||
= getFromAllScopes(memberScopes) { it.getContributedDescriptors() }
|
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 toString(): String = kind.toString()
|
||||||
|
|
||||||
override fun printStructure(p: Printer) {
|
override fun printStructure(p: Printer) {
|
||||||
p.println(this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name,
|
p.println(
|
||||||
" with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {")
|
this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name,
|
||||||
|
" with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {"
|
||||||
|
)
|
||||||
p.pushIndent()
|
p.pushIndent()
|
||||||
|
|
||||||
for (scope in memberScopes) {
|
for (scope in memberScopes) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class LexicalScopeImpl @JvmOverloads constructor(
|
|||||||
override val kind: LexicalScopeKind,
|
override val kind: LexicalScopeKind,
|
||||||
redeclarationChecker: LocalRedeclarationChecker = LocalRedeclarationChecker.DO_NOTHING,
|
redeclarationChecker: LocalRedeclarationChecker = LocalRedeclarationChecker.DO_NOTHING,
|
||||||
initialize: LexicalScopeImpl.InitializeHandler.() -> Unit = {}
|
initialize: LexicalScopeImpl.InitializeHandler.() -> Unit = {}
|
||||||
): LexicalScope, LexicalScopeStorage(parent, redeclarationChecker) {
|
) : LexicalScope, LexicalScopeStorage(parent, redeclarationChecker) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
InitializeHandler().initialize()
|
InitializeHandler().initialize()
|
||||||
@@ -36,8 +36,10 @@ class LexicalScopeImpl @JvmOverloads constructor(
|
|||||||
override fun toString(): String = kind.toString()
|
override fun toString(): String = kind.toString()
|
||||||
|
|
||||||
override fun printStructure(p: Printer) {
|
override fun printStructure(p: Printer) {
|
||||||
p.println(this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name,
|
p.println(
|
||||||
" with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {")
|
this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name,
|
||||||
|
" with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {"
|
||||||
|
)
|
||||||
p.pushIndent()
|
p.pushIndent()
|
||||||
|
|
||||||
p.print("parent = ")
|
p.print("parent = ")
|
||||||
@@ -49,14 +51,14 @@ class LexicalScopeImpl @JvmOverloads constructor(
|
|||||||
|
|
||||||
inner class InitializeHandler() {
|
inner class InitializeHandler() {
|
||||||
|
|
||||||
fun addVariableDescriptor(variableDescriptor: VariableDescriptor): Unit
|
fun addVariableDescriptor(variableDescriptor: VariableDescriptor): Unit =
|
||||||
= this@LexicalScopeImpl.addVariableOrClassDescriptor(variableDescriptor)
|
this@LexicalScopeImpl.addVariableOrClassDescriptor(variableDescriptor)
|
||||||
|
|
||||||
fun addFunctionDescriptor(functionDescriptor: FunctionDescriptor): Unit
|
fun addFunctionDescriptor(functionDescriptor: FunctionDescriptor): Unit =
|
||||||
= this@LexicalScopeImpl.addFunctionDescriptorInternal(functionDescriptor)
|
this@LexicalScopeImpl.addFunctionDescriptorInternal(functionDescriptor)
|
||||||
|
|
||||||
fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor): Unit
|
fun addClassifierDescriptor(classifierDescriptor: ClassifierDescriptor): Unit =
|
||||||
= this@LexicalScopeImpl.addVariableOrClassDescriptor(classifierDescriptor)
|
this@LexicalScopeImpl.addVariableOrClassDescriptor(classifierDescriptor)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ interface LocalRedeclarationChecker {
|
|||||||
abstract class LexicalScopeStorage(
|
abstract class LexicalScopeStorage(
|
||||||
parent: HierarchicalScope,
|
parent: HierarchicalScope,
|
||||||
val redeclarationChecker: LocalRedeclarationChecker
|
val redeclarationChecker: LocalRedeclarationChecker
|
||||||
): LexicalScope {
|
) : LexicalScope {
|
||||||
override val parent = parent.takeSnapshot()
|
override val parent = parent.takeSnapshot()
|
||||||
|
|
||||||
protected val addedDescriptors: MutableList<DeclarationDescriptor> = SmartList()
|
protected val addedDescriptors: MutableList<DeclarationDescriptor> = SmartList()
|
||||||
@@ -45,13 +45,15 @@ abstract class LexicalScopeStorage(
|
|||||||
private var functionsByName: MutableMap<Name, IntList>? = null
|
private var functionsByName: MutableMap<Name, IntList>? = null
|
||||||
private var variablesAndClassifiersByName: MutableMap<Name, IntList>? = null
|
private var variablesAndClassifiersByName: MutableMap<Name, IntList>? = null
|
||||||
|
|
||||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = variableOrClassDescriptorByName(name) as? ClassifierDescriptor
|
override fun getContributedClassifier(name: Name, location: LookupLocation) =
|
||||||
override fun getContributedVariables(name: Name, location: LookupLocation) = listOfNotNull(variableOrClassDescriptorByName(name) as? VariableDescriptor)
|
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 getContributedFunctions(name: Name, location: LookupLocation) = functionsByName(name)
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
|
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = addedDescriptors
|
||||||
= addedDescriptors
|
|
||||||
|
|
||||||
protected fun addVariableOrClassDescriptor(descriptor: DeclarationDescriptor) {
|
protected fun addVariableOrClassDescriptor(descriptor: DeclarationDescriptor) {
|
||||||
val name = descriptor.name
|
val name = descriptor.name
|
||||||
@@ -115,7 +117,7 @@ abstract class LexicalScopeStorage(
|
|||||||
|
|
||||||
private operator fun IntList?.plus(value: Int) = IntList(value, this)
|
private operator fun IntList?.plus(value: Int) = IntList(value, this)
|
||||||
|
|
||||||
private fun <TDescriptor: DeclarationDescriptor> IntList.toDescriptors(): List<TDescriptor> {
|
private fun <TDescriptor : DeclarationDescriptor> IntList.toDescriptors(): List<TDescriptor> {
|
||||||
val result = ArrayList<TDescriptor>(1)
|
val result = ArrayList<TDescriptor>(1)
|
||||||
var rest: IntList? = this
|
var rest: IntList? = this
|
||||||
do {
|
do {
|
||||||
|
|||||||
+11
-6
@@ -68,11 +68,14 @@ class LexicalWritableScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inner class Snapshot(val descriptorLimit: Int) : LexicalScope by this {
|
private inner class Snapshot(val descriptorLimit: Int) : LexicalScope by this {
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean)
|
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) =
|
||||||
= addedDescriptors.subList(0, descriptorLimit)
|
addedDescriptors.subList(0, descriptorLimit)
|
||||||
|
|
||||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = variableOrClassDescriptorByName(name, descriptorLimit) as? ClassifierDescriptor
|
override fun getContributedClassifier(name: Name, location: LookupLocation) =
|
||||||
override fun getContributedVariables(name: Name, location: LookupLocation) = listOfNotNull(variableOrClassDescriptorByName(name, descriptorLimit) as? VariableDescriptor)
|
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)
|
override fun getContributedFunctions(name: Name, location: LookupLocation) = functionsByName(name, descriptorLimit)
|
||||||
|
|
||||||
@@ -88,8 +91,10 @@ class LexicalWritableScope(
|
|||||||
override fun toString(): String = kind.toString()
|
override fun toString(): String = kind.toString()
|
||||||
|
|
||||||
override fun printStructure(p: Printer) {
|
override fun printStructure(p: Printer) {
|
||||||
p.println(this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name,
|
p.println(
|
||||||
" with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {")
|
this::class.java.simpleName, ": ", kind, "; for descriptor: ", ownerDescriptor.name,
|
||||||
|
" with implicitReceiver: ", implicitReceiver?.value ?: "NONE", " {"
|
||||||
|
)
|
||||||
p.pushIndent()
|
p.pushIndent()
|
||||||
|
|
||||||
p.print("parent = ")
|
p.print("parent = ")
|
||||||
|
|||||||
@@ -117,7 +117,10 @@ interface ImportingScope : HierarchicalScope {
|
|||||||
changeNamesForAliased: Boolean
|
changeNamesForAliased: Boolean
|
||||||
): Collection<DeclarationDescriptor>
|
): Collection<DeclarationDescriptor>
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
|
override fun getContributedDescriptors(
|
||||||
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean
|
||||||
|
): Collection<DeclarationDescriptor> {
|
||||||
return getContributedDescriptors(kindFilter, nameFilter, changeNamesForAliased = false)
|
return getContributedDescriptors(kindFilter, nameFilter, changeNamesForAliased = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +138,10 @@ interface ImportingScope : HierarchicalScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class BaseHierarchicalScope(override val parent: HierarchicalScope?) : HierarchicalScope {
|
abstract class BaseHierarchicalScope(override val parent: HierarchicalScope?) : HierarchicalScope {
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> = emptyList()
|
override fun getContributedDescriptors(
|
||||||
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean
|
||||||
|
): Collection<DeclarationDescriptor> = emptyList()
|
||||||
|
|
||||||
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null
|
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 getContributedPackage(name: Name): PackageViewDescriptor? = null
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
|
override fun getContributedDescriptors(
|
||||||
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean
|
||||||
|
): Collection<DeclarationDescriptor> {
|
||||||
return getContributedDescriptors(kindFilter, nameFilter, changeNamesForAliased = false)
|
return getContributedDescriptors(kindFilter, nameFilter, changeNamesForAliased = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, changeNamesForAliased: Boolean): Collection<DeclarationDescriptor>
|
override fun getContributedDescriptors(
|
||||||
= emptyList()
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean,
|
||||||
|
changeNamesForAliased: Boolean
|
||||||
|
): Collection<DeclarationDescriptor> = emptyList()
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-3
@@ -42,11 +42,18 @@ class SubpackagesImportingScope(
|
|||||||
//TODO: kept old behavior, but it seems very strange (super call seems more applicable)
|
//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 getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = null
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> =
|
override fun getContributedDescriptors(
|
||||||
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean
|
||||||
|
): Collection<DeclarationDescriptor> =
|
||||||
emptyList()
|
emptyList()
|
||||||
|
|
||||||
//TODO: kept old behavior, but it seems very strange (super call seems more applicable)
|
//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<DeclarationDescriptor>
|
override fun getContributedDescriptors(
|
||||||
= emptyList()
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean,
|
||||||
|
changeNamesForAliased: Boolean
|
||||||
|
): Collection<DeclarationDescriptor> = emptyList()
|
||||||
|
|
||||||
override fun computeImportedNames() = emptySet<Name>()
|
override fun computeImportedNames() = emptySet<Name>()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ class ReceiverValueWithSmartCastInfo(
|
|||||||
val receiverValue: ReceiverValue,
|
val receiverValue: ReceiverValue,
|
||||||
val possibleTypes: Set<KotlinType>, // doesn't include receiver.type
|
val possibleTypes: Set<KotlinType>, // doesn't include receiver.type
|
||||||
val isStable: Boolean
|
val isStable: Boolean
|
||||||
): DetailedReceiver {
|
) : DetailedReceiver {
|
||||||
override fun toString() = receiverValue.toString()
|
override fun toString() = receiverValue.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,7 @@ fun LexicalScope.getImplicitReceiversHierarchy(): List<ReceiverParameterDescript
|
|||||||
fun LexicalScope.getDeclarationsByLabel(labelName: Name): Collection<DeclarationDescriptor> = collectAllFromMeAndParent {
|
fun LexicalScope.getDeclarationsByLabel(labelName: Name): Collection<DeclarationDescriptor> = collectAllFromMeAndParent {
|
||||||
if (it is LexicalScope && it.isOwnerDescriptorAccessibleByLabel && it.ownerDescriptor.name == labelName) {
|
if (it is LexicalScope && it.isOwnerDescriptorAccessibleByLabel && it.ownerDescriptor.name == labelName) {
|
||||||
listOf(it.ownerDescriptor)
|
listOf(it.ownerDescriptor)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
listOf()
|
listOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,38 +62,49 @@ fun HierarchicalScope.collectDescriptorsFiltered(
|
|||||||
}.filter { kindFilter.accepts(it) && nameFilter(it.name) }
|
}.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 {
|
return findFirstFromMeAndParent {
|
||||||
when {
|
when {
|
||||||
it is LexicalScopeWrapper -> it.delegate.findLocalVariable(name)
|
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
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun HierarchicalScope.findClassifier(name: Name, location: LookupLocation): ClassifierDescriptor?
|
fun HierarchicalScope.findClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? =
|
||||||
= findFirstFromMeAndParent { it.getContributedClassifier(name, location) }
|
findFirstFromMeAndParent { it.getContributedClassifier(name, location) }
|
||||||
|
|
||||||
fun HierarchicalScope.findPackage(name: Name): PackageViewDescriptor?
|
fun HierarchicalScope.findPackage(name: Name): PackageViewDescriptor? = findFirstFromImportingScopes { it.getContributedPackage(name) }
|
||||||
= findFirstFromImportingScopes { it.getContributedPackage(name) }
|
|
||||||
|
|
||||||
fun HierarchicalScope.collectVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor>
|
fun HierarchicalScope.collectVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor> =
|
||||||
= collectAllFromMeAndParent { it.getContributedVariables(name, location) }
|
collectAllFromMeAndParent { it.getContributedVariables(name, location) }
|
||||||
|
|
||||||
fun HierarchicalScope.collectFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor>
|
fun HierarchicalScope.collectFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> =
|
||||||
= collectAllFromMeAndParent { it.getContributedFunctions(name, location) }
|
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 {
|
processForMeAndParent {
|
||||||
it.getContributedVariables(name, location).firstOrNull(predicate)?.let { return it }
|
it.getContributedVariables(name, location).firstOrNull(predicate)?.let { return it }
|
||||||
}
|
}
|
||||||
return null
|
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 {
|
processForMeAndParent {
|
||||||
it.getContributedFunctions(name, location).firstOrNull(predicate)?.let { return it }
|
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
|
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 {
|
private class MemberScopeToImportingScopeAdapter(override val parent: ImportingScope?, val memberScope: MemberScope) : ImportingScope {
|
||||||
override fun getContributedPackage(name: Name): PackageViewDescriptor? = null
|
override fun getContributedPackage(name: Name): PackageViewDescriptor? = null
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, changeNamesForAliased: Boolean)
|
override fun getContributedDescriptors(
|
||||||
= memberScope.getContributedDescriptors(kindFilter, nameFilter)
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean,
|
||||||
|
changeNamesForAliased: Boolean
|
||||||
|
) = memberScope.getContributedDescriptors(kindFilter, nameFilter)
|
||||||
|
|
||||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = memberScope.getContributedClassifier(name, location)
|
override fun getContributedClassifier(name: Name, location: LookupLocation) = memberScope.getContributedClassifier(name, location)
|
||||||
|
|
||||||
@@ -144,7 +159,7 @@ inline fun HierarchicalScope.processForMeAndParent(process: (HierarchicalScope)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <T: Any> HierarchicalScope.collectFromMeAndParent(
|
private inline fun <T : Any> HierarchicalScope.collectFromMeAndParent(
|
||||||
collect: (HierarchicalScope) -> T?
|
collect: (HierarchicalScope) -> T?
|
||||||
): List<T> {
|
): List<T> {
|
||||||
var result: MutableList<T>? = null
|
var result: MutableList<T>? = null
|
||||||
@@ -160,7 +175,7 @@ private inline fun <T: Any> HierarchicalScope.collectFromMeAndParent(
|
|||||||
return result ?: emptyList()
|
return result ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T: Any> HierarchicalScope.collectAllFromMeAndParent(
|
inline fun <T : Any> HierarchicalScope.collectAllFromMeAndParent(
|
||||||
collect: (HierarchicalScope) -> Collection<T>
|
collect: (HierarchicalScope) -> Collection<T>
|
||||||
): Collection<T> {
|
): Collection<T> {
|
||||||
var result: Collection<T>? = null
|
var result: Collection<T>? = null
|
||||||
@@ -168,18 +183,18 @@ inline fun <T: Any> HierarchicalScope.collectAllFromMeAndParent(
|
|||||||
return result ?: emptySet()
|
return result ?: emptySet()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T: Any> HierarchicalScope.findFirstFromMeAndParent(fetch: (HierarchicalScope) -> T?): T? {
|
inline fun <T : Any> HierarchicalScope.findFirstFromMeAndParent(fetch: (HierarchicalScope) -> T?): T? {
|
||||||
processForMeAndParent { fetch(it)?.let { return it } }
|
processForMeAndParent { fetch(it)?.let { return it } }
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T: Any> HierarchicalScope.collectAllFromImportingScopes(
|
inline fun <T : Any> HierarchicalScope.collectAllFromImportingScopes(
|
||||||
collect: (ImportingScope) -> Collection<T>
|
collect: (ImportingScope) -> Collection<T>
|
||||||
): Collection<T> {
|
): Collection<T> {
|
||||||
return collectAllFromMeAndParent { if (it is ImportingScope) collect(it) else emptyList() }
|
return collectAllFromMeAndParent { if (it is ImportingScope) collect(it) else emptyList() }
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T: Any> HierarchicalScope.findFirstFromImportingScopes(fetch: (ImportingScope) -> T?): T? {
|
inline fun <T : Any> HierarchicalScope.findFirstFromImportingScopes(fetch: (ImportingScope) -> T?): T? {
|
||||||
return findFirstFromMeAndParent { if (it is ImportingScope) fetch(it) else null }
|
return findFirstFromMeAndParent { if (it is ImportingScope) fetch(it) else null }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,11 +205,10 @@ fun LexicalScope.addImportingScopes(importScopes: List<ImportingScope>): Lexical
|
|||||||
return replaceImportingScopes(newFirstImporting)
|
return replaceImportingScopes(newFirstImporting)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun LexicalScope.addImportingScope(importScope: ImportingScope): LexicalScope
|
fun LexicalScope.addImportingScope(importScope: ImportingScope): LexicalScope = addImportingScopes(listOf(importScope))
|
||||||
= addImportingScopes(listOf(importScope))
|
|
||||||
|
|
||||||
fun ImportingScope.withParent(newParent: ImportingScope?): ImportingScope {
|
fun ImportingScope.withParent(newParent: ImportingScope?): ImportingScope {
|
||||||
return object: ImportingScope by this {
|
return object : ImportingScope by this {
|
||||||
override val parent: ImportingScope?
|
override val parent: ImportingScope?
|
||||||
get() = newParent
|
get() = newParent
|
||||||
}
|
}
|
||||||
@@ -216,7 +230,7 @@ fun LexicalScope.createScopeForDestructuring(newReceiver: ReceiverParameterDescr
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
init {
|
||||||
assert(delegate !is LexicalScopeWrapper) {
|
assert(delegate !is LexicalScopeWrapper) {
|
||||||
"Do not wrap again to avoid performance issues"
|
"Do not wrap again to avoid performance issues"
|
||||||
@@ -229,8 +243,7 @@ private class LexicalScopeWrapper(val delegate: LexicalScope, val newImportingSc
|
|||||||
val parent = delegate.parent
|
val parent = delegate.parent
|
||||||
if (parent is LexicalScope) {
|
if (parent is LexicalScope) {
|
||||||
parent.replaceImportingScopes(newImportingScopeChain)
|
parent.replaceImportingScopes(newImportingScopeChain)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
newImportingScopeChain
|
newImportingScopeChain
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -260,7 +273,10 @@ class ErrorLexicalScope : LexicalScope {
|
|||||||
|
|
||||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> = emptySet()
|
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> = emptySet()
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> = emptySet()
|
override fun getContributedDescriptors(
|
||||||
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean
|
||||||
|
): Collection<DeclarationDescriptor> = emptySet()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun printStructure(p: Printer) {
|
override fun printStructure(p: Printer) {
|
||||||
@@ -278,5 +294,8 @@ class ErrorLexicalScope : LexicalScope {
|
|||||||
|
|
||||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> = emptySet()
|
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> = emptySet()
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> = emptySet()
|
override fun getContributedDescriptors(
|
||||||
|
kindFilter: DescriptorKindFilter,
|
||||||
|
nameFilter: (Name) -> Boolean
|
||||||
|
): Collection<DeclarationDescriptor> = emptySet()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,9 +66,8 @@ private fun DeclarationDescriptor.getOwnSinceKotlinVersion(): ApiVersion? {
|
|||||||
val ctorClass = (this as? ConstructorDescriptor)?.containingDeclaration?.loadAnnotationValue()
|
val ctorClass = (this as? ConstructorDescriptor)?.containingDeclaration?.loadAnnotationValue()
|
||||||
val property = (this as? PropertyAccessorDescriptor)?.correspondingProperty?.loadAnnotationValue()
|
val property = (this as? PropertyAccessorDescriptor)?.correspondingProperty?.loadAnnotationValue()
|
||||||
|
|
||||||
val typeAliasDescriptor = (this as? TypeAliasDescriptor) ?:
|
val typeAliasDescriptor = (this as? TypeAliasDescriptor) ?: (this as? TypeAliasConstructorDescriptor)?.typeAliasDescriptor
|
||||||
(this as? TypeAliasConstructorDescriptor)?.typeAliasDescriptor ?:
|
?: (this as? FakeCallableDescriptorForTypeAliasObject)?.typeAliasDescriptor
|
||||||
(this as? FakeCallableDescriptorForTypeAliasObject)?.typeAliasDescriptor
|
|
||||||
|
|
||||||
val typeAlias = typeAliasDescriptor?.loadAnnotationValue()
|
val typeAlias = typeAliasDescriptor?.loadAnnotationValue()
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ open class TypeApproximatorConfiguration {
|
|||||||
TO_FIRST,
|
TO_FIRST,
|
||||||
TO_COMMON_SUPERTYPE
|
TO_COMMON_SUPERTYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
open val flexible get() = false // simple flexible types (FlexibleTypeImpl)
|
open val flexible get() = false // simple flexible types (FlexibleTypeImpl)
|
||||||
open val dynamic get() = false // DynamicType
|
open val dynamic get() = false // DynamicType
|
||||||
open val rawType get() = false // RawTypeImpl
|
open val rawType get() = false // RawTypeImpl
|
||||||
@@ -65,7 +66,8 @@ open class TypeApproximatorConfiguration {
|
|||||||
override val definitelyNotNullType get() = false
|
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 allFlexible get() = true
|
||||||
override val errorType get() = true
|
override val errorType get() = true
|
||||||
|
|
||||||
@@ -94,22 +96,26 @@ class TypeApproximator {
|
|||||||
// null means that this input type is the result, i.e. input type not contains not-allowed kind of types
|
// null means that this input type is the result, i.e. input type not contains not-allowed kind of types
|
||||||
// type <: resultType
|
// type <: resultType
|
||||||
fun approximateToSuperType(type: UnwrappedType, conf: TypeApproximatorConfiguration): UnwrappedType? =
|
fun approximateToSuperType(type: UnwrappedType, conf: TypeApproximatorConfiguration): UnwrappedType? =
|
||||||
approximateToSuperType(type, conf, - type.typeDepth())
|
approximateToSuperType(type, conf, -type.typeDepth())
|
||||||
|
|
||||||
// resultType <: type
|
// resultType <: type
|
||||||
fun approximateToSubType(type: UnwrappedType, conf: TypeApproximatorConfiguration): UnwrappedType? =
|
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? {
|
private fun approximateToSuperType(type: UnwrappedType, conf: TypeApproximatorConfiguration, depth: Int): UnwrappedType? {
|
||||||
if (type is TypeUtils.SpecialType) return null
|
if (type is TypeUtils.SpecialType) return null
|
||||||
return approximateTo(NewKotlinTypeChecker.transformToNewType(type), conf, FlexibleType::upperBound,
|
return approximateTo(
|
||||||
referenceApproximateToSuperType, depth)
|
NewKotlinTypeChecker.transformToNewType(type), conf, FlexibleType::upperBound,
|
||||||
|
referenceApproximateToSuperType, depth
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun approximateToSubType(type: UnwrappedType, conf: TypeApproximatorConfiguration, depth: Int): UnwrappedType? {
|
private fun approximateToSubType(type: UnwrappedType, conf: TypeApproximatorConfiguration, depth: Int): UnwrappedType? {
|
||||||
if (type is TypeUtils.SpecialType) return null
|
if (type is TypeUtils.SpecialType) return null
|
||||||
return approximateTo(NewKotlinTypeChecker.transformToNewType(type), conf, FlexibleType::lowerBound,
|
return approximateTo(
|
||||||
referenceApproximateToSubType, depth)
|
NewKotlinTypeChecker.transformToNewType(type), conf, FlexibleType::lowerBound,
|
||||||
|
referenceApproximateToSubType, depth
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// comments for case bound = upperBound, approximateTo = toSuperType
|
// comments for case bound = upperBound, approximateTo = toSuperType
|
||||||
@@ -125,8 +131,7 @@ class TypeApproximator {
|
|||||||
is FlexibleType -> {
|
is FlexibleType -> {
|
||||||
if (type is DynamicType) {
|
if (type is DynamicType) {
|
||||||
return if (conf.dynamic) null else type.bound()
|
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()
|
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.
|
* 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,
|
return KotlinTypeFactory.flexibleType(
|
||||||
upperResult?.upperIfFlexible() ?: type.upperBound)
|
lowerResult?.lowerIfFlexible() ?: type.lowerBound,
|
||||||
}
|
upperResult?.upperIfFlexible() ?: type.upperBound
|
||||||
else {
|
)
|
||||||
|
} else {
|
||||||
return type.bound().let { approximateTo(it, conf, depth) ?: it }
|
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
|
val typeConstructor = type.constructor
|
||||||
assert(typeConstructor is IntersectionTypeConstructor) {
|
assert(typeConstructor is IntersectionTypeConstructor) {
|
||||||
"Should be intersection type: $type, typeConstructor class: ${typeConstructor::class.java.canonicalName}"
|
"Should be intersection type: $type, typeConstructor class: ${typeConstructor::class.java.canonicalName}"
|
||||||
@@ -195,13 +206,20 @@ class TypeApproximator {
|
|||||||
ALLOWED -> if (!thereIsApproximation) return null else intersectTypes(newTypes)
|
ALLOWED -> if (!thereIsApproximation) return null else intersectTypes(newTypes)
|
||||||
TO_FIRST -> if (toSuper) newTypes.first() else return type.defaultResult(toSuper = false)
|
TO_FIRST -> if (toSuper) newTypes.first() else return type.defaultResult(toSuper = false)
|
||||||
// commonSupertypeCalculator should handle flexible types correctly
|
// commonSupertypeCalculator should handle flexible types correctly
|
||||||
TO_COMMON_SUPERTYPE -> if (toSuper) NewCommonSuperTypeCalculator.commonSuperType(newTypes) else return type.defaultResult(toSuper = false)
|
TO_COMMON_SUPERTYPE -> if (toSuper) NewCommonSuperTypeCalculator.commonSuperType(newTypes) else return type.defaultResult(
|
||||||
|
toSuper = false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (type.isMarkedNullable) baseResult.makeNullableAsSpecified(true) else baseResult
|
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 supertypes = type.constructor.supertypes
|
||||||
val baseSuperType = when (supertypes.size) {
|
val baseSuperType = when (supertypes.size) {
|
||||||
0 -> type.builtIns.nullableAnyType // Let C = in Int, then superType for C and C? is Any?
|
0 -> type.builtIns.nullableAnyType // Let C = in Int, then superType for C and C? is Any?
|
||||||
@@ -241,7 +259,11 @@ class TypeApproximator {
|
|||||||
return null
|
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 = in Int, Int <: C => Int? <: C?
|
||||||
// C = out Number, C <: Number => C? <: Number?
|
// C = out Number, C <: Number => C? <: Number?
|
||||||
@@ -250,6 +272,7 @@ class TypeApproximator {
|
|||||||
|
|
||||||
private fun approximateSimpleToSuperType(type: SimpleType, conf: TypeApproximatorConfiguration, depth: Int) =
|
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) =
|
private fun approximateSimpleToSubType(type: SimpleType, conf: TypeApproximatorConfiguration, depth: Int) =
|
||||||
approximateTo(type, conf, toSuper = false, depth = depth)
|
approximateTo(type, conf, toSuper = false, depth = depth)
|
||||||
|
|
||||||
@@ -272,7 +295,8 @@ class TypeApproximator {
|
|||||||
val typeConstructor = type.constructor
|
val typeConstructor = type.constructor
|
||||||
|
|
||||||
if (typeConstructor is NewCapturedTypeConstructor) {
|
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 " +
|
"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"
|
||||||
}
|
}
|
||||||
@@ -299,8 +323,7 @@ class TypeApproximator {
|
|||||||
val approximatedOriginalType = approximateTo(type.original, conf, toSuper, depth)
|
val approximatedOriginalType = approximateTo(type.original, conf, toSuper, depth)
|
||||||
return if (conf.definitelyNotNullType) {
|
return if (conf.definitelyNotNullType) {
|
||||||
approximatedOriginalType?.makeDefinitelyNotNullOrNotNull()
|
approximatedOriginalType?.makeDefinitelyNotNullOrNotNull()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (toSuper)
|
if (toSuper)
|
||||||
(approximatedOriginalType ?: type.original).makeNullableAsSpecified(false)
|
(approximatedOriginalType ?: type.original).makeNullableAsSpecified(false)
|
||||||
else
|
else
|
||||||
@@ -315,14 +338,18 @@ class TypeApproximator {
|
|||||||
Variance.INVARIANT -> throw AssertionError("Incorrect variance $effectiveVariance")
|
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 parameters = type.constructor.parameters
|
||||||
val arguments = type.arguments
|
val arguments = type.arguments
|
||||||
if (parameters.size != arguments.size) {
|
if (parameters.size != arguments.size) {
|
||||||
return if (conf.errorType) {
|
return if (conf.errorType) {
|
||||||
ErrorUtils.createErrorType("Inconsistent type: $type (parameters.size = ${parameters.size}, arguments.size = ${arguments.size})")
|
ErrorUtils.createErrorType("Inconsistent type: $type (parameters.size = ${parameters.size}, arguments.size = ${arguments.size})")
|
||||||
}
|
} else type.defaultResult(toSuper)
|
||||||
else type.defaultResult(toSuper)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val newArguments = arrayOfNulls<TypeProjection?>(arguments.size)
|
val newArguments = arrayOfNulls<TypeProjection?>(arguments.size)
|
||||||
@@ -338,8 +365,10 @@ class TypeApproximator {
|
|||||||
when (effectiveVariance) {
|
when (effectiveVariance) {
|
||||||
null -> {
|
null -> {
|
||||||
return if (conf.errorType) {
|
return if (conf.errorType) {
|
||||||
ErrorUtils.createErrorType("Inconsistent type: $type ($index parameter has declared variance: ${parameter.variance}, " +
|
ErrorUtils.createErrorType(
|
||||||
"but argument variance is ${argument.projectionKind})")
|
"Inconsistent type: $type ($index parameter has declared variance: ${parameter.variance}, " +
|
||||||
|
"but argument variance is ${argument.projectionKind})"
|
||||||
|
)
|
||||||
} else type.defaultResult(toSuper)
|
} else type.defaultResult(toSuper)
|
||||||
}
|
}
|
||||||
Variance.OUT_VARIANCE, Variance.IN_VARIANCE -> {
|
Variance.OUT_VARIANCE, Variance.IN_VARIANCE -> {
|
||||||
@@ -353,8 +382,7 @@ class TypeApproximator {
|
|||||||
val approximatedArgument = argumentType.let {
|
val approximatedArgument = argumentType.let {
|
||||||
if (isApproximateDirectionToSuper(effectiveVariance, toSuper)) {
|
if (isApproximateDirectionToSuper(effectiveVariance, toSuper)) {
|
||||||
approximateToSuperType(it, conf, depth)
|
approximateToSuperType(it, conf, depth)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
approximateToSubType(it, conf, depth)
|
approximateToSubType(it, conf, depth)
|
||||||
}
|
}
|
||||||
} ?: continue@loop
|
} ?: 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()) {
|
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()) {
|
if (!approximatedSubType.isTrivialSub()) {
|
||||||
newArguments[index] = TypeProjectionImpl(Variance.IN_VARIANCE, approximatedSubType)
|
newArguments[index] = TypeProjectionImpl(Variance.IN_VARIANCE, approximatedSubType)
|
||||||
continue@loop
|
continue@loop
|
||||||
@@ -408,8 +438,7 @@ class TypeApproximator {
|
|||||||
|
|
||||||
if (NewKotlinTypeChecker.equalTypes(argumentType, approximatedSuperType)) {
|
if (NewKotlinTypeChecker.equalTypes(argumentType, approximatedSuperType)) {
|
||||||
newArguments[index] = approximatedSuperType.asTypeProjection()
|
newArguments[index] = approximatedSuperType.asTypeProjection()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
newArguments[index] = TypeProjectionImpl(Variance.OUT_VARIANCE, approximatedSuperType)
|
newArguments[index] = TypeProjectionImpl(Variance.OUT_VARIANCE, approximatedSuperType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user