Smart completion after "by" works for generic properties too

This commit is contained in:
Valentin Kipyatkov
2016-03-31 20:47:06 +03:00
parent 20ac76fe3a
commit 4dde458e84
5 changed files with 39 additions and 10 deletions
@@ -0,0 +1,10 @@
import kotlin.reflect.KProperty
class X {
operator fun getValue(thisRef: List<String>, property: KProperty<*>): String = ""
}
val <T> List<T>.property: T by <caret>
// EXIST: lazy
// EXIST: X
@@ -0,0 +1,10 @@
import kotlin.reflect.KProperty
class X {
operator fun getValue(thisRef: List<String>, property: KProperty<*>): String = ""
operator fun setValue(thisRef: List<String>, property: KProperty<*>, value: String){}
}
var <T> List<T>.property: T by <caret>
// EXIST: X
@@ -1510,6 +1510,18 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
doTest(fileName);
}
@TestMetadata("GenericVal.kt")
public void testGenericVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/GenericVal.kt");
doTest(fileName);
}
@TestMetadata("GenericVar.kt")
public void testGenericVar() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/GenericVar.kt");
doTest(fileName);
}
@TestMetadata("Order.kt")
public void testOrder() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/Order.kt");
@@ -612,11 +612,11 @@ class ExpectedInfos(
val property = resolutionFacade.resolveToDescriptor(propertyDeclaration) as? PropertyDescriptor ?: return null
val scope = expressionWithType.getResolutionScope(bindingContext, resolutionFacade)
val propertyOwnerType = property.extensionReceiverParameter?.type
?: property.dispatchReceiverParameter?.type
val propertyOwnerType = property.fuzzyExtensionReceiverType()
?: property.dispatchReceiverParameter?.type?.let { FuzzyType(it, emptyList()) }
?: return null
val explicitPropertyType = property.returnType?.check { propertyDeclaration.typeReference != null }
val explicitPropertyType = property.fuzzyReturnType()?.check { propertyDeclaration.typeReference != null }
val typesWithGetDetector = TypesWithGetValueDetector(scope, indicesHelper, propertyOwnerType, explicitPropertyType)
val typesWithSetDetector = if (property.isVar) TypesWithSetValueDetector(scope, indicesHelper, propertyOwnerType) else null
@@ -629,10 +629,7 @@ class ExpectedInfos(
val substitutedType = FuzzyType(getOperatorSubstitutor.substitute(descriptorType.type, Variance.INVARIANT)!!, descriptorType.freeParameters)
val (setValueOperator, setOperatorSubstitutor) = typesWithSetDetector.findOperator(substitutedType) ?: return null
val propertyType = if (explicitPropertyType != null)
FuzzyType(explicitPropertyType, emptyList())
else
getValueOperator.fuzzyReturnType()!!
val propertyType = explicitPropertyType ?: getValueOperator.fuzzyReturnType()!!
val setParamType = FuzzyType(setValueOperator.valueParameters.last().type, setValueOperator.typeParameters)
val setParamTypeSubstitutor = setParamType.checkIsSuperTypeOf(propertyType) ?: return null
return TypeSubstitutor.createChainedSubstitutor(getOperatorSubstitutor.substitution,
@@ -119,8 +119,8 @@ class TypesWithContainsDetector(
class TypesWithGetValueDetector(
scope: LexicalScope,
indicesHelper: KotlinIndicesHelper?,
private val propertyOwnerType: KotlinType,
private val propertyType: KotlinType?
private val propertyOwnerType: FuzzyType,
private val propertyType: FuzzyType?
) : TypesWithOperatorDetector(OperatorNameConventions.GET_VALUE, scope, indicesHelper) {
override fun checkIsSuitableByType(operator: FunctionDescriptor, freeTypeParams: Collection<TypeParameterDescriptor>): TypeSubstitutor? {
@@ -138,7 +138,7 @@ class TypesWithGetValueDetector(
class TypesWithSetValueDetector(
scope: LexicalScope,
indicesHelper: KotlinIndicesHelper?,
private val propertyOwnerType: KotlinType
private val propertyOwnerType: FuzzyType
) : TypesWithOperatorDetector(OperatorNameConventions.SET_VALUE, scope, indicesHelper) {
override fun checkIsSuitableByType(operator: FunctionDescriptor, freeTypeParams: Collection<TypeParameterDescriptor>): TypeSubstitutor? {