Checking for conflicting substitutors in completion after "by"
This commit is contained in:
@@ -184,3 +184,18 @@ class FuzzyType(
|
|||||||
return TypeSubstitutor.create(TypeConstructorSubstitution.createByConstructorsMap(substitution))
|
return TypeSubstitutor.create(TypeConstructorSubstitution.createByConstructorsMap(substitution))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun TypeSubstitution.hasConflictWith(other: TypeSubstitution, freeParameters: Collection<TypeParameterDescriptor>): Boolean {
|
||||||
|
return freeParameters.any { parameter ->
|
||||||
|
val type = parameter.defaultType
|
||||||
|
val substituted1 = this[type] ?: return@any false
|
||||||
|
val substituted2 = other[type] ?: return@any false
|
||||||
|
!KotlinTypeChecker.FLEXIBLE_UNEQUAL_TO_INFLEXIBLE.equalTypes(substituted1.type, substituted2.type) || substituted1.projectionKind != substituted2.projectionKind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun TypeSubstitutor.combineIfNoConflicts(other: TypeSubstitutor, freeParameters: Collection<TypeParameterDescriptor>): TypeSubstitutor? {
|
||||||
|
if (this.substitution.hasConflictWith(other.substitution, freeParameters)) return null
|
||||||
|
return TypeSubstitutor.createChainedSubstitutor(this.substitution, other.substitution)
|
||||||
|
}
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
class X<T> {
|
||||||
|
operator fun getValue(thisRef: T, property: KProperty<*>): T = throw Exception()
|
||||||
|
}
|
||||||
|
|
||||||
|
class C<T> {
|
||||||
|
val property: Int by <caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABSENT: X
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
class X<T>(t: T) {
|
||||||
|
operator fun getValue(thisRef: T, property: KProperty<*>): T = throw Exception()
|
||||||
|
}
|
||||||
|
|
||||||
|
class C<T> {
|
||||||
|
val property: C<T> by <caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: { itemText: "X", tailText: "(t: C<T>) (<root>)" }
|
||||||
+12
@@ -1450,6 +1450,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/smart/propertyDelegate"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/smart/propertyDelegate"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ConflictingSubstitutors.kt")
|
||||||
|
public void testConflictingSubstitutors() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/ConflictingSubstitutors.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("DelegatesDot.kt")
|
@TestMetadata("DelegatesDot.kt")
|
||||||
public void testDelegatesDot() throws Exception {
|
public void testDelegatesDot() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/DelegatesDot.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/DelegatesDot.kt");
|
||||||
@@ -1522,6 +1528,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("NonConflictingSubstitutors.kt")
|
||||||
|
public void testNonConflictingSubstitutors() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/NonConflictingSubstitutors.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("Order.kt")
|
@TestMetadata("Order.kt")
|
||||||
public void testOrder() throws Exception {
|
public void testOrder() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/Order.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/Order.kt");
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.builtins.isFunctionType
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.resolve.ideService
|
import org.jetbrains.kotlin.idea.resolve.ideService
|
||||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
import org.jetbrains.kotlin.idea.util.*
|
||||||
import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
|
|
||||||
import org.jetbrains.kotlin.idea.util.fuzzyReturnType
|
|
||||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -632,9 +629,9 @@ class ExpectedInfos(
|
|||||||
val propertyType = explicitPropertyType ?: getValueOperator.fuzzyReturnType()!!
|
val propertyType = explicitPropertyType ?: getValueOperator.fuzzyReturnType()!!
|
||||||
val setParamType = FuzzyType(setValueOperator.valueParameters.last().type, setValueOperator.typeParameters)
|
val setParamType = FuzzyType(setValueOperator.valueParameters.last().type, setValueOperator.typeParameters)
|
||||||
val setParamTypeSubstitutor = setParamType.checkIsSuperTypeOf(propertyType) ?: return null
|
val setParamTypeSubstitutor = setParamType.checkIsSuperTypeOf(propertyType) ?: return null
|
||||||
return TypeSubstitutor.createChainedSubstitutor(getOperatorSubstitutor.substitution,
|
return getOperatorSubstitutor
|
||||||
TypeSubstitutor.createChainedSubstitutor(setOperatorSubstitutor.substitution,
|
.combineIfNoConflicts(setOperatorSubstitutor, descriptorType.freeParameters)
|
||||||
setParamTypeSubstitutor.substitution).substitution)
|
?.combineIfNoConflicts(setParamTypeSubstitutor, descriptorType.freeParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val multipleFuzzyTypes: Collection<FuzzyType> by lazy {
|
override val multipleFuzzyTypes: Collection<FuzzyType> by lazy {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||||
|
import org.jetbrains.kotlin.idea.util.combineIfNoConflicts
|
||||||
import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
|
import org.jetbrains.kotlin.idea.util.fuzzyExtensionReceiverType
|
||||||
import org.jetbrains.kotlin.idea.util.nullability
|
import org.jetbrains.kotlin.idea.util.nullability
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
@@ -138,7 +139,7 @@ class TypesWithGetValueDetector(
|
|||||||
|
|
||||||
val fuzzyReturnType = FuzzyType(operator.returnType ?: return null, freeTypeParams)
|
val fuzzyReturnType = FuzzyType(operator.returnType ?: return null, freeTypeParams)
|
||||||
val substitutorFromPropertyType = fuzzyReturnType.checkIsSubtypeOf(propertyType) ?: return null
|
val substitutorFromPropertyType = fuzzyReturnType.checkIsSubtypeOf(propertyType) ?: return null
|
||||||
return TypeSubstitutor.createChainedSubstitutor(substitutor.substitution, substitutorFromPropertyType.substitution)
|
return substitutor.combineIfNoConflicts(substitutorFromPropertyType, freeTypeParams)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user