better filtering of elements in KDoc link completion
This commit is contained in:
@@ -92,8 +92,8 @@ public interface JetScope {
|
|||||||
* The same as getDescriptors(kindFilter, nameFilter) but the result is guaranteed to be filtered by kind and name.
|
* The same as getDescriptors(kindFilter, nameFilter) but the result is guaranteed to be filtered by kind and name.
|
||||||
*/
|
*/
|
||||||
public fun JetScope.getDescriptorsFiltered(
|
public fun JetScope.getDescriptorsFiltered(
|
||||||
kindFilter: DescriptorKindFilter,
|
kindFilter: DescriptorKindFilter = DescriptorKindFilter.ALL,
|
||||||
nameFilter: (Name) -> Boolean
|
nameFilter: (Name) -> Boolean = { true }
|
||||||
): Collection<DeclarationDescriptor> {
|
): Collection<DeclarationDescriptor> {
|
||||||
if (kindFilter.kindMask == 0) return listOf()
|
if (kindFilter.kindMask == 0) return listOf()
|
||||||
return getDescriptors(kindFilter, nameFilter).filter { kindFilter.accepts(it) && nameFilter(it.getName()) }
|
return getDescriptors(kindFilter, nameFilter).filter { kindFilter.accepts(it) && nameFilter(it.getName()) }
|
||||||
|
|||||||
@@ -154,6 +154,9 @@ public fun getResolutionScope(resolutionFacade: ResolutionFacade, descriptor: De
|
|||||||
is PackageViewDescriptor ->
|
is PackageViewDescriptor ->
|
||||||
descriptor.memberScope
|
descriptor.memberScope
|
||||||
|
|
||||||
|
is ClassDescriptorWithResolutionScopes ->
|
||||||
|
descriptor.getScopeForMemberDeclarationResolution()
|
||||||
|
|
||||||
is ClassDescriptor ->
|
is ClassDescriptor ->
|
||||||
getClassInnerScope(getOuterScope(descriptor, resolutionFacade), descriptor)
|
getClassInnerScope(getOuterScope(descriptor, resolutionFacade), descriptor)
|
||||||
|
|
||||||
|
|||||||
+21
-1
@@ -23,9 +23,12 @@ import com.intellij.codeInsight.lookup.LookupElementDecorator
|
|||||||
import com.intellij.patterns.PlatformPatterns.psiElement
|
import com.intellij.patterns.PlatformPatterns.psiElement
|
||||||
import com.intellij.patterns.StandardPatterns
|
import com.intellij.patterns.StandardPatterns
|
||||||
import com.intellij.util.ProcessingContext
|
import com.intellij.util.ProcessingContext
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.kdoc.getParamDescriptors
|
import org.jetbrains.kotlin.idea.kdoc.getParamDescriptors
|
||||||
import org.jetbrains.kotlin.idea.kdoc.getResolutionScope
|
import org.jetbrains.kotlin.idea.kdoc.getResolutionScope
|
||||||
|
import org.jetbrains.kotlin.idea.util.CallType
|
||||||
|
import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable
|
||||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
|
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
|
||||||
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
|
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
|
||||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
|
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
|
||||||
@@ -33,7 +36,10 @@ import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||||
|
|
||||||
class KDocCompletionContributor(): CompletionContributor() {
|
class KDocCompletionContributor(): CompletionContributor() {
|
||||||
init {
|
init {
|
||||||
@@ -86,7 +92,21 @@ class KDocNameCompletionSession(parameters: CompletionParameters,
|
|||||||
|
|
||||||
private fun addLinkCompletions(declarationDescriptor: DeclarationDescriptor) {
|
private fun addLinkCompletions(declarationDescriptor: DeclarationDescriptor) {
|
||||||
val scope = getResolutionScope(resolutionFacade, declarationDescriptor)
|
val scope = getResolutionScope(resolutionFacade, declarationDescriptor)
|
||||||
scope.getDescriptors(nameFilter = descriptorNameFilter).forEach {
|
val implicitReceivers = scope.getImplicitReceiversHierarchy().map { it.value }
|
||||||
|
|
||||||
|
fun isApplicable(descriptor: DeclarationDescriptor): Boolean {
|
||||||
|
if (descriptor is CallableDescriptor) {
|
||||||
|
val extensionReceiver = descriptor.getExtensionReceiverParameter()
|
||||||
|
if (extensionReceiver != null) {
|
||||||
|
val substituted = descriptor.substituteExtensionIfCallable(implicitReceivers, bindingContext, DataFlowInfo.EMPTY,
|
||||||
|
CallType.NORMAL, moduleDescriptor)
|
||||||
|
return !substituted.isEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.getDescriptorsFiltered(nameFilter = descriptorNameFilter).filter(::isApplicable).forEach {
|
||||||
val element = lookupElementFactory.createLookupElement(it, false)
|
val element = lookupElementFactory.createLookupElement(it, false)
|
||||||
collector.addElement(object: LookupElementDecorator<LookupElement>(element) {
|
collector.addElement(object: LookupElementDecorator<LookupElement>(element) {
|
||||||
override fun handleInsert(context: InsertionContext?) {
|
override fun handleInsert(context: InsertionContext?) {
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
class Foo {
|
||||||
|
/**
|
||||||
|
* [<caret>]
|
||||||
|
*/
|
||||||
|
fun xyzzy() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.quux() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: bar
|
||||||
|
// EXIST: quux
|
||||||
+6
@@ -41,6 +41,12 @@ public class KDocCompletionTestGenerated extends AbstractJvmBasicCompletionTest
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("MemberLink.kt")
|
||||||
|
public void testMemberLink() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/kdoc/MemberLink.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("NotTagName.kt")
|
@TestMetadata("NotTagName.kt")
|
||||||
public void testNotTagName() throws Exception {
|
public void testNotTagName() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/kdoc/NotTagName.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/kdoc/NotTagName.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user