diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocReference.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocReference.kt index 06b451447f5..3d6b04ee15e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocReference.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocReference.kt @@ -20,12 +20,13 @@ import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.resolve.KotlinCacheService +import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade +import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.references.JetMultiReference import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink import org.jetbrains.kotlin.kdoc.psi.impl.KDocName import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.BindingContext @@ -33,12 +34,9 @@ import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.source.PsiSourceElement -import org.jetbrains.kotlin.utils.Printer public class KDocReference(element: KDocName): JetMultiReference(element) { override fun getTargetDescriptors(context: BindingContext): Collection { - val cacheService = KotlinCacheService.getInstance(getElement().getProject()) - val session = cacheService.getLazyResolveSession(getElement()) val declaration = getElement().getContainingDoc().getOwner() if (declaration == null) { return arrayListOf() @@ -48,7 +46,10 @@ public class KDocReference(element: KDocName): JetMultiReference(eleme return arrayListOf() } val kdocLink = getElement().getStrictParentOfType()!! - return resolveKDocLink(session, declarationDescriptor, kdocLink.getTagIfSubject(), getElement().getQualifiedName()) + return resolveKDocLink(getElement().getResolutionFacade(), + declarationDescriptor, + kdocLink.getTagIfSubject(), + getElement().getQualifiedName()) } override fun getRangeInElement(): TextRange = getElement().getNameTextRange() @@ -65,7 +66,7 @@ public class KDocReference(element: KDocName): JetMultiReference(eleme override fun getCanonicalText(): String = getElement().getNameText() } -public fun resolveKDocLink(session: KotlinCodeAnalyzer, +public fun resolveKDocLink(resolutionFacade: ResolutionFacade, fromDescriptor: DeclarationDescriptor, fromSubjectOfTag: KDocTag?, qualifiedName: List): Collection { @@ -75,7 +76,7 @@ public fun resolveKDocLink(session: KotlinCodeAnalyzer, // Try to find a matching local descriptor (parameter or type parameter) first. if (qualifiedName.size() == 1) { - val localResult = resolveInLocalScope(fromDescriptor, qualifiedName.single(), session) + val localResult = resolveInLocalScope(fromDescriptor, qualifiedName.single(), resolutionFacade) if (!localResult.isEmpty()) { return localResult } @@ -84,7 +85,7 @@ public fun resolveKDocLink(session: KotlinCodeAnalyzer, var result: Collection = listOf(fromDescriptor) qualifiedName.forEach { nameComponent -> if (result.size() != 1) return listOf() - val scope = getResolutionScope(session, result.first()) + val scope = getResolutionScope(resolutionFacade, result.first()) result = scope.getDescriptors().filter { it.getName().asString() == nameComponent } } @@ -93,8 +94,8 @@ public fun resolveKDocLink(session: KotlinCodeAnalyzer, private fun resolveInLocalScope(fromDescriptor: DeclarationDescriptor, name: String, - session: KotlinCodeAnalyzer): List { - val scope = getResolutionScope(session, fromDescriptor) + resolutionFacade: ResolutionFacade): List { + val scope = getResolutionScope(resolutionFacade, fromDescriptor) return scope.getDescriptors().filter { it.getName().asString() == name && it.getContainingDeclaration() == fromDescriptor } @@ -148,7 +149,7 @@ private fun getClassInnerScope(outerScope: JetScope, descriptor: ClassDescriptor return classScope } -public fun getResolutionScope(session: KotlinCodeAnalyzer, descriptor: DeclarationDescriptor): JetScope { +public fun getResolutionScope(resolutionFacade: ResolutionFacade, descriptor: DeclarationDescriptor): JetScope { return when (descriptor) { is PackageFragmentDescriptor -> getPackageInnerScope(descriptor) @@ -157,31 +158,31 @@ public fun getResolutionScope(session: KotlinCodeAnalyzer, descriptor: Declarati descriptor.getMemberScope() is ClassDescriptor -> - getClassInnerScope(getOuterScope(descriptor, session), descriptor) + getClassInnerScope(getOuterScope(descriptor, resolutionFacade), descriptor) is FunctionDescriptor -> - FunctionDescriptorUtil.getFunctionInnerScope(getOuterScope(descriptor, session), + FunctionDescriptorUtil.getFunctionInnerScope(getOuterScope(descriptor, resolutionFacade), descriptor, RedeclarationHandler.DO_NOTHING) is PropertyDescriptor -> JetScopeUtils.getPropertyDeclarationInnerScope(descriptor, - getOuterScope(descriptor, session), + getOuterScope(descriptor, resolutionFacade), RedeclarationHandler.DO_NOTHING) is DeclarationDescriptorNonRoot -> - getOuterScope(descriptor, session) + getOuterScope(descriptor, resolutionFacade) else -> throw IllegalArgumentException("Cannot find resolution scope for root $descriptor") } } -private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, session: KotlinCodeAnalyzer): JetScope { +private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, resolutionFacade: ResolutionFacade): JetScope { val parent = descriptor.getContainingDeclaration() if (parent is PackageFragmentDescriptor) { val containingFile = (descriptor.getSource() as? PsiSourceElement)?.psi?.getContainingFile() as? JetFile if (containingFile != null) { - return session.getScopeProvider().getFileScope(containingFile) + return resolutionFacade.getFileTopLevelScope(containingFile) } } - return getResolutionScope(session, parent) + return getResolutionScope(resolutionFacade, parent) } diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KDocCompletionContributor.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KDocCompletionContributor.kt index 6c1af58d5db..4e8ba0fb4ef 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KDocCompletionContributor.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KDocCompletionContributor.kt @@ -57,46 +57,43 @@ class KDocCompletionContributor(): CompletionContributor() { object KDocNameCompletionProvider: CompletionProvider() { override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) { + KDocNameCompletionSession(parameters, result).complete() + } +} + +class KDocNameCompletionSession(parameters: CompletionParameters, + resultSet: CompletionResultSet): CompletionSessionBase(CompletionSessionConfiguration(parameters), parameters, resultSet) { + override fun doComplete() { val position = parameters.getPosition().getParentOfType(false) ?: return val declaration = position.getContainingDoc().getOwner() ?: return - val bindingContext = declaration.analyze() val kdocLink = position.getStrictParentOfType()!! val declarationDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] if (kdocLink.getTagIfSubject()?.knownTag == KDocKnownTag.PARAM) { - addParamCompletions(position, declarationDescriptor, result) + addParamCompletions(position, declarationDescriptor) } else { - val session = KotlinCacheService.getInstance(parameters.getPosition().getProject()).getLazyResolveSession(position) - addLinkCompletions(session, position, declarationDescriptor, result) + addLinkCompletions(declarationDescriptor) } } private fun addParamCompletions(position: KDocName, - declarationDescriptor: DeclarationDescriptor, - result: CompletionResultSet) { + declarationDescriptor: DeclarationDescriptor) { val section = position.getContainingSection() val documentedParameters = section.findTagsByName("param").map { it.getSubjectName() }.toSet() val descriptors = getParamDescriptors(declarationDescriptor) .filter { it.getName().asString() !in documentedParameters } - val resolutionFacade = position.getResolutionFacade() - val factory = LookupElementFactory(listOf()) descriptors.forEach { - result.addElement(factory.createLookupElement(resolutionFacade, it, false)) + resultSet.addElement(lookupElementFactory.createLookupElement(resolutionFacade, it, false)) } } - private fun addLinkCompletions(session: KotlinCodeAnalyzer, - position: KDocName, - declarationDescriptor: DeclarationDescriptor, - result: CompletionResultSet) { - val scope = getResolutionScope(session, declarationDescriptor) - val resolutionFacade = position.getResolutionFacade() - val factory = LookupElementFactory(listOf()) - scope.getAllDescriptors().forEach { - val element = factory.createLookupElement(resolutionFacade, it, false) - result.addElement(object: LookupElementDecorator(element) { + private fun addLinkCompletions(declarationDescriptor: DeclarationDescriptor) { + val scope = getResolutionScope(resolutionFacade, declarationDescriptor) + scope.getDescriptors(nameFilter = {name -> prefixMatcher.prefixMatches(name.asString())}).forEach { + val element = lookupElementFactory.createLookupElement(resolutionFacade, it, false) + resultSet.addElement(object: LookupElementDecorator(element) { override fun handleInsert(context: InsertionContext?) { - // don't insert any qualified name here + // insert only plain name here, no qualifier/parentheses/etc. } }) } diff --git a/idea/src/org/jetbrains/kotlin/idea/JetQuickDocumentationProvider.java b/idea/src/org/jetbrains/kotlin/idea/JetQuickDocumentationProvider.java index 7cd0b4c1087..46056d3e786 100644 --- a/idea/src/org/jetbrains/kotlin/idea/JetQuickDocumentationProvider.java +++ b/idea/src/org/jetbrains/kotlin/idea/JetQuickDocumentationProvider.java @@ -35,7 +35,6 @@ import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; import org.jetbrains.kotlin.idea.kdoc.KDocFinder; import org.jetbrains.kotlin.idea.kdoc.KDocRenderer; import org.jetbrains.kotlin.idea.kdoc.KdocPackage; -import org.jetbrains.kotlin.idea.project.ResolveSessionForBodies; import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag; import org.jetbrains.kotlin.psi.JetDeclaration; import org.jetbrains.kotlin.psi.JetElement; @@ -130,7 +129,6 @@ public class JetQuickDocumentationProvider extends AbstractDocumentationProvider JetElement jetElement = (JetElement) context; Project project = psiManager.getProject(); KotlinCacheService cacheService = KotlinCacheService.getInstance(project); - ResolveSessionForBodies session = cacheService.getLazyResolveSession(jetElement); ResolutionFacade facade = cacheService.getResolutionFacade(Collections.singletonList(jetElement)); BindingContext bindingContext = facade.analyze(jetElement, BodyResolveMode.PARTIAL); DeclarationDescriptor contextDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, context); @@ -138,7 +136,7 @@ public class JetQuickDocumentationProvider extends AbstractDocumentationProvider return null; } Collection descriptors = - KdocPackage.resolveKDocLink(session, contextDescriptor, null, StringUtil.split(link, ",")); + KdocPackage.resolveKDocLink(facade, contextDescriptor, null, StringUtil.split(link, ",")); if (!descriptors.isEmpty()) { DeclarationDescriptor target = descriptors.iterator().next(); if (target instanceof DeclarationDescriptorWithSource) {