diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/CallableDescriptor.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/CallableDescriptor.java index 74ee3ea9e02..2c37a77d427 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/CallableDescriptor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/CallableDescriptor.java @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.descriptors; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.ReadOnly; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.TypeSubstitutor; @@ -32,6 +33,7 @@ public interface CallableDescriptor extends DeclarationDescriptorWithVisibility, ReceiverParameterDescriptor getDispatchReceiverParameter(); @NotNull + @ReadOnly List getTypeParameters(); /** diff --git a/idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass1.kt b/idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass1.kt new file mode 100644 index 00000000000..aaf06219ddc --- /dev/null +++ b/idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass1.kt @@ -0,0 +1,12 @@ +import kotlin.reflect.KProperty + +class X(t: T) { + operator fun getValue(thisRef: C, property: KProperty<*>): T = throw Exception() +} + +class C { + val property by +} + +// EXIST: lazy +// EXIST: { itemText: "X", tailText: "(t: T) ()" } diff --git a/idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass2.kt b/idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass2.kt new file mode 100644 index 00000000000..4dcdfe2967a --- /dev/null +++ b/idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass2.kt @@ -0,0 +1,12 @@ +import kotlin.reflect.KProperty + +class X(t: T) { + operator fun getValue(thisRef: C, property: KProperty<*>): T = throw Exception() +} + +class C { + val property: T by +} + +// EXIST: lazy +// EXIST: { itemText: "X", tailText: "(t: T) ()" } diff --git a/idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass3.kt b/idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass3.kt new file mode 100644 index 00000000000..376570c687d --- /dev/null +++ b/idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass3.kt @@ -0,0 +1,12 @@ +import kotlin.reflect.KProperty + +class X(t: T) { + operator fun getValue(thisRef: C, property: KProperty<*>): T = throw Exception() +} + +class C { + val property: T2 by +} + +// EXIST: lazy +// ABSENT: X diff --git a/idea/idea-completion/testData/smart/propertyDelegate/VarInGenericClass.kt b/idea/idea-completion/testData/smart/propertyDelegate/VarInGenericClass.kt new file mode 100644 index 00000000000..0f962e1bf67 --- /dev/null +++ b/idea/idea-completion/testData/smart/propertyDelegate/VarInGenericClass.kt @@ -0,0 +1,12 @@ +import kotlin.reflect.KProperty + +class X(t: T) { + operator fun getValue(thisRef: C, property: KProperty<*>): T = throw Exception() + operator fun setValue(thisRef: C, property: KProperty<*>, t: T) {} +} + +class C { + var property by +} + +// EXIST: { itemText: "X", tailText: "(t: T) ()" } diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java index ea8dff0ff80..ec4391d838c 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java @@ -1534,11 +1534,35 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest(fileName); } + @TestMetadata("ValInGenericClass1.kt") + public void testValInGenericClass1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass1.kt"); + doTest(fileName); + } + + @TestMetadata("ValInGenericClass2.kt") + public void testValInGenericClass2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass2.kt"); + doTest(fileName); + } + + @TestMetadata("ValInGenericClass3.kt") + public void testValInGenericClass3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/ValInGenericClass3.kt"); + doTest(fileName); + } + @TestMetadata("VarInClass.kt") public void testVarInClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/VarInClass.kt"); doTest(fileName); } + + @TestMetadata("VarInGenericClass.kt") + public void testVarInGenericClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/propertyDelegate/VarInGenericClass.kt"); + doTest(fileName); + } } @TestMetadata("idea/idea-completion/testData/smart/smartCasts") diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/TypesWithOperatorDetector.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/TypesWithOperatorDetector.kt index 669ddb696c5..2020d41d091 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/TypesWithOperatorDetector.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/TypesWithOperatorDetector.kt @@ -64,7 +64,14 @@ abstract class TypesWithOperatorDetector( private fun MutableCollection.addSuitableOperators(functions: Collection): MutableCollection { for (function in functions) { if (!function.isValidOperator()) continue - val substitutor = checkIsSuitableByType(function, function.typeParameters) ?: continue + + var freeParameters = function.typeParameters + val containingClass = function.containingDeclaration as? ClassDescriptor + if (containingClass != null) { + freeParameters += containingClass.typeConstructor.parameters + } + + val substitutor = checkIsSuitableByType(function, freeParameters) ?: continue add(function.substitute(substitutor)) } return this