Completion of non-imported extensions in debugger for runtime receiver type
This commit is contained in:
+8
-2
@@ -240,9 +240,15 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
|
||||
if (completionKind != CompletionKind.KEYWORDS_ONLY) {
|
||||
completeNonImported()
|
||||
|
||||
flushToResultSet()
|
||||
|
||||
if (position.getContainingFile() is KtCodeFragment) {
|
||||
flushToResultSet()
|
||||
collector.addDescriptorElements(getRuntimeReceiverTypeReferenceVariants(), withReceiverCast = true)
|
||||
val variants = getRuntimeReceiverTypeReferenceVariants()
|
||||
if (variants != null) {
|
||||
collector.addDescriptorElements(variants.imported, withReceiverCast = true)
|
||||
collector.addDescriptorElements(variants.notImportedExtensions, withReceiverCast = true, notImported = true)
|
||||
flushToResultSet()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-10
@@ -324,18 +324,19 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
|
||||
return this
|
||||
}
|
||||
|
||||
protected fun getRuntimeReceiverTypeReferenceVariants(): Collection<DeclarationDescriptor> {
|
||||
val explicitReceiver = callTypeAndReceiver.receiver as? KtExpression ?: return emptyList()
|
||||
val type = bindingContext.getType(explicitReceiver) ?: return emptyList()
|
||||
if (!TypeUtils.canHaveSubtypes(KotlinTypeChecker.DEFAULT, type)) return emptyList()
|
||||
val evaluator = file.getCopyableUserData(KtCodeFragment.RUNTIME_TYPE_EVALUATOR) ?: return emptyList()
|
||||
protected fun getRuntimeReceiverTypeReferenceVariants(): ReferenceVariants? {
|
||||
val explicitReceiver = callTypeAndReceiver.receiver as? KtExpression ?: return null
|
||||
val type = bindingContext.getType(explicitReceiver) ?: return null
|
||||
if (!TypeUtils.canHaveSubtypes(KotlinTypeChecker.DEFAULT, type)) return null
|
||||
val evaluator = file.getCopyableUserData(KtCodeFragment.RUNTIME_TYPE_EVALUATOR) ?: return null
|
||||
val runtimeType = evaluator(explicitReceiver)
|
||||
if (runtimeType == null || runtimeType == type) return emptyList()
|
||||
if (runtimeType == null || runtimeType == type) return null
|
||||
|
||||
val (variants, notImportedExtensions/*TODO: use them*/) = collectReferenceVariants(descriptorKindFilter!!, runtimeType)
|
||||
return variants.filter { descriptor ->
|
||||
referenceVariants!!.imported.none { compareDescriptors(project, it, descriptor) }
|
||||
}
|
||||
val (variants, notImportedExtensions) = collectReferenceVariants(descriptorKindFilter!!, runtimeType)
|
||||
val normalVariants = referenceVariants!!.imported + referenceVariants!!.notImportedExtensions
|
||||
val filteredVariants = variants.filter { descriptor -> normalVariants.none { compareDescriptors(project, it, descriptor) } }
|
||||
val filteredNotImportedExtensions = notImportedExtensions.filter { descriptor -> normalVariants.none { compareDescriptors(project, it, descriptor) } }
|
||||
return ReferenceVariants(filteredVariants, filteredNotImportedExtensions)
|
||||
}
|
||||
|
||||
protected fun shouldCompleteTopLevelCallablesFromIndex(): Boolean {
|
||||
|
||||
+5
-3
@@ -85,10 +85,12 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para
|
||||
}
|
||||
|
||||
if (position.getContainingFile() is KtCodeFragment) {
|
||||
getRuntimeReceiverTypeReferenceVariants().forEach {
|
||||
collector.addElements(filter(it).map { it.withReceiverCast() })
|
||||
val variants = getRuntimeReceiverTypeReferenceVariants()
|
||||
if (variants != null) {
|
||||
variants.imported.forEach { collector.addElements(filter(it).map { it.withReceiverCast() }) }
|
||||
variants.notImportedExtensions.forEach { collector.addElements(filter(it).map { it.withReceiverCast() }, notImported = true) }
|
||||
flushToResultSet()
|
||||
}
|
||||
flushToResultSet()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fun foo(o: Any) {
|
||||
<caret>val a = 1
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// EXIST: read, write
|
||||
|
||||
// RUNTIME_TYPE: java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
o.<caret>
|
||||
@@ -0,0 +1,8 @@
|
||||
fun foo(o: Any) {
|
||||
<caret>val a = 1
|
||||
}
|
||||
|
||||
// INVOCATION_COUNT: 1
|
||||
// ELEMENT: read
|
||||
|
||||
// RUNTIME_TYPE: java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
+1
@@ -0,0 +1 @@
|
||||
(o as ReentrantReadWriteLock).read { <caret> }
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import kotlin.concurrent.read
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
+1
@@ -0,0 +1 @@
|
||||
o.<caret>
|
||||
+6
@@ -64,4 +64,10 @@ public class CodeFragmentCompletionHandlerTestGenerated extends AbstractCodeFrag
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/runtimeCast/InsertImport.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NotImportedExtension.kt")
|
||||
public void testNotImportedExtension() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/runtimeCast/NotImportedExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -115,6 +115,12 @@ public class CodeFragmentCompletionTestGenerated extends AbstractCodeFragmentCom
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notImportedExtension.kt")
|
||||
public void testNotImportedExtension() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/codeFragments/runtimeType/notImportedExtension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("runtimeCast.kt")
|
||||
public void testRuntimeCast() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/codeFragments/runtimeType/runtimeCast.kt");
|
||||
|
||||
Reference in New Issue
Block a user