KT-36860 Collect extensions from object on first completion
- This should not affect the performance of the completion, since all object extensions are collected on the last step, when all main variants are already collected - Add more tests - Also, disable completion of extensions from objects as callable references (^KT-37395 Fixed) - ^KT-36860 Fixed
This commit is contained in:
committed by
Roman Golyshev
parent
7dc9a2fc64
commit
90750483ee
+11
-2
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode.FORCED_SHORTENING
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||
import org.jetbrains.kotlin.idea.util.CallType
|
||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
@@ -332,8 +333,14 @@ class BasicCompletionSession(
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration.staticMembers && prefix.isNotEmpty()) {
|
||||
if (!receiverTypes.isNullOrEmpty()) {
|
||||
if (!receiverTypes.isNullOrEmpty()) {
|
||||
// N.B.: callable references to member extensions are forbidden
|
||||
val shouldCompleteExtensionsFromObjects = when (callTypeAndReceiver.callType) {
|
||||
CallType.DEFAULT, CallType.DOT, CallType.SAFE, CallType.INFIX -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
if (shouldCompleteExtensionsFromObjects) {
|
||||
staticMembersCompletion.completeObjectMemberExtensionsFromIndices(
|
||||
indicesHelper(false),
|
||||
receiverTypes.map { it.type },
|
||||
@@ -341,7 +348,9 @@ class BasicCompletionSession(
|
||||
collector
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration.staticMembers && prefix.isNotEmpty()) {
|
||||
if (callTypeAndReceiver is CallTypeAndReceiver.DEFAULT) {
|
||||
staticMembersCompletion.completeFromIndices(indicesHelper(false), collector)
|
||||
}
|
||||
|
||||
-1
@@ -11,6 +11,5 @@ fun usage(t: T) {
|
||||
t.foo<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// EXIST: { lookupString: "fooExtension", itemText: "fooExtension" }
|
||||
// EXIST: { lookupString: "fooProperty", itemText: "fooProperty" }
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class T
|
||||
|
||||
class A {
|
||||
companion object {
|
||||
infix fun T.fooExtension(i: Int) {}
|
||||
}
|
||||
}
|
||||
|
||||
fun usage(t: T) {
|
||||
t foo<caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "fooExtension", itemText: "fooExtension" }
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class T
|
||||
|
||||
class A {
|
||||
companion object {
|
||||
fun T.fooExtension() {}
|
||||
val T.fooProperty get() = 10
|
||||
}
|
||||
}
|
||||
|
||||
fun usage(t: T) {
|
||||
t.<caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "fooExtension", itemText: "fooExtension" }
|
||||
// EXIST: { lookupString: "fooProperty", itemText: "fooProperty" }
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class T
|
||||
|
||||
class A {
|
||||
companion object {
|
||||
fun T.fooExtension() {}
|
||||
val T.fooProperty get() = 10
|
||||
}
|
||||
}
|
||||
|
||||
fun usage(t: T) {
|
||||
t?.foo<caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "fooExtension", itemText: "fooExtension" }
|
||||
// EXIST: { lookupString: "fooProperty", itemText: "fooProperty" }
|
||||
-1
@@ -11,6 +11,5 @@ fun T.usage() {
|
||||
foo<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// EXIST: { lookupString: "fooExtension", itemText: "fooExtension" }
|
||||
// EXIST: { lookupString: "fooProperty", itemText: "fooProperty" }
|
||||
Vendored
-1
@@ -21,7 +21,6 @@ fun usage(b: B) {
|
||||
b.foo<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// EXIST: { lookupString: "fooForAny", itemText: "fooForAny" }
|
||||
|
||||
// EXIST: { lookupString: "fooForT", itemText: "fooForT" }
|
||||
|
||||
Vendored
+1
-2
@@ -21,7 +21,6 @@ fun B.usage() {
|
||||
foo<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// EXIST: { lookupString: "fooForAny", itemText: "fooForAny" }
|
||||
|
||||
// EXIST: { lookupString: "fooForT", itemText: "fooForT" }
|
||||
@@ -30,7 +29,7 @@ fun B.usage() {
|
||||
// EXIST: { lookupString: "fooForTGeneric", itemText: "fooForTGeneric" }
|
||||
// EXIST: { lookupString: "fooForBGeneric", itemText: "fooForBGeneric" }
|
||||
|
||||
// EXIST: fooNoReceiver
|
||||
// ABSENT: fooNoReceiver
|
||||
|
||||
// ABSENT: fooForC
|
||||
// ABSENT: fooForCGeneric
|
||||
|
||||
Vendored
-1
@@ -17,7 +17,6 @@ class A {
|
||||
}
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// EXIST: { lookupString: "fooForA", itemText: "fooForA" }
|
||||
// EXIST: { lookupString: "fooForB", itemText: "fooForB" }
|
||||
// EXIST: { lookupString: "fooForT", itemText: "fooForT" }
|
||||
|
||||
Vendored
-1
@@ -9,6 +9,5 @@ fun usage(t: T) {
|
||||
t.foo<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// EXIST: { lookupString: "fooExtension", itemText: "fooExtension" }
|
||||
// EXIST: { lookupString: "fooProperty", itemText: "fooProperty" }
|
||||
Vendored
-1
@@ -9,6 +9,5 @@ fun T.usage() {
|
||||
foo<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// EXIST: { lookupString: "fooExtension", itemText: "fooExtension" }
|
||||
// EXIST: { lookupString: "fooProperty", itemText: "fooProperty" }
|
||||
Vendored
-1
@@ -14,6 +14,5 @@ fun T.usage() {
|
||||
foo<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// EXIST: { lookupString: "fooExtension", itemText: "fooExtension" }
|
||||
// EXIST: { lookupString: "fooProperty", itemText: "fooProperty" }
|
||||
-1
@@ -8,5 +8,4 @@ fun usage(t: T) {
|
||||
t.f<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -10,5 +10,4 @@ fun usage(t: T) {
|
||||
t.foo()<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -8,5 +8,4 @@ fun T.usage() {
|
||||
f<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -10,5 +10,4 @@ fun T.usage() {
|
||||
foo()<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -12,5 +12,4 @@ fun usage(t: T) {
|
||||
t.f<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -14,5 +14,4 @@ fun usage(t: T) {
|
||||
t.foo()<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -12,5 +12,4 @@ fun T.usage() {
|
||||
f<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -14,5 +14,4 @@ fun T.usage() {
|
||||
foo()<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -10,5 +10,4 @@ fun usage(t: T) {
|
||||
t.f<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -12,5 +12,4 @@ fun usage(t: T) {
|
||||
t.foo()<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -10,5 +10,4 @@ fun T.usage() {
|
||||
f<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -12,5 +12,4 @@ fun T.usage() {
|
||||
foo()<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -8,5 +8,4 @@ fun usage(t: T) {
|
||||
t.f<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -10,5 +10,4 @@ fun usage(t: T) {
|
||||
t.foo()<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -8,5 +8,4 @@ fun T.usage() {
|
||||
f<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
-1
@@ -10,5 +10,4 @@ fun T.usage() {
|
||||
foo()<caret>
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 2
|
||||
// ELEMENT: foo
|
||||
+15
@@ -1255,6 +1255,21 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectExplicitReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObjectExplicitReceiverInfixExtension.kt")
|
||||
public void testCompanionObjectExplicitReceiverInfixExtension() throws Exception {
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectExplicitReceiverInfixExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObjectExplicitReceiverNoPrefix.kt")
|
||||
public void testCompanionObjectExplicitReceiverNoPrefix() throws Exception {
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectExplicitReceiverNoPrefix.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObjectExplicitReceiverSafeAccess.kt")
|
||||
public void testCompanionObjectExplicitReceiverSafeAccess() throws Exception {
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectExplicitReceiverSafeAccess.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObjectImplicitReceiver.kt")
|
||||
public void testCompanionObjectImplicitReceiver() throws Exception {
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectImplicitReceiver.kt");
|
||||
|
||||
+15
@@ -1255,6 +1255,21 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectExplicitReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObjectExplicitReceiverInfixExtension.kt")
|
||||
public void testCompanionObjectExplicitReceiverInfixExtension() throws Exception {
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectExplicitReceiverInfixExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObjectExplicitReceiverNoPrefix.kt")
|
||||
public void testCompanionObjectExplicitReceiverNoPrefix() throws Exception {
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectExplicitReceiverNoPrefix.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObjectExplicitReceiverSafeAccess.kt")
|
||||
public void testCompanionObjectExplicitReceiverSafeAccess() throws Exception {
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectExplicitReceiverSafeAccess.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("CompanionObjectImplicitReceiver.kt")
|
||||
public void testCompanionObjectImplicitReceiver() throws Exception {
|
||||
runTest("idea/idea-completion/testData/basic/common/extensionMethodInObject/CompanionObjectImplicitReceiver.kt");
|
||||
|
||||
Reference in New Issue
Block a user