don't highlight multi-resolved references in KDoc as unresolved

#KT-9413 Fixed
This commit is contained in:
Dmitry Jemerov
2015-11-13 20:48:41 +01:00
parent 742830f815
commit bfca85db52
3 changed files with 43 additions and 29 deletions
@@ -38,33 +38,30 @@ import org.jetbrains.kotlin.resolve.source.PsiSourceElement
public class KDocReference(element: KDocName): KtMultiReference<KDocName>(element) { public class KDocReference(element: KDocName): KtMultiReference<KDocName>(element) {
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> { override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
val declaration = getElement().getContainingDoc().getOwner() val declaration = element.getContainingDoc().getOwner() ?: return arrayListOf()
if (declaration == null) { val declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] ?: return arrayListOf()
return arrayListOf()
} val kdocLink = element.getStrictParentOfType<KDocLink>()!!
val declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] return resolveKDocLink(element.getResolutionFacade(),
if (declarationDescriptor == null) {
return arrayListOf()
}
val kdocLink = getElement().getStrictParentOfType<KDocLink>()!!
return resolveKDocLink(getElement().getResolutionFacade(),
declarationDescriptor, declarationDescriptor,
kdocLink.getTagIfSubject(), kdocLink.getTagIfSubject(),
getElement().getQualifiedName()) element.getQualifiedName())
} }
override fun getRangeInElement(): TextRange = getElement().getNameTextRange() override fun getRangeInElement(): TextRange = element.getNameTextRange()
override fun canRename(): Boolean = true override fun canRename(): Boolean = true
override fun resolve(): PsiElement? = multiResolve(false).firstOrNull()?.element
override fun handleElementRename(newElementName: String?): PsiElement? { override fun handleElementRename(newElementName: String?): PsiElement? {
val textRange = getElement().getNameTextRange() val textRange = element.getNameTextRange()
val newText = textRange.replace(getElement().getText(), newElementName!!) val newText = textRange.replace(element.text, newElementName!!)
val newLink = KDocElementFactory(getElement().getProject()).createNameFromText(newText) val newLink = KDocElementFactory(element.project).createNameFromText(newText)
return getElement().replace(newLink) return element.replace(newLink)
} }
override fun getCanonicalText(): String = getElement().getNameText() override fun getCanonicalText(): String = element.getNameText()
} }
public fun resolveKDocLink(resolutionFacade: ResolutionFacade, public fun resolveKDocLink(resolutionFacade: ResolutionFacade,
@@ -76,7 +73,7 @@ public fun resolveKDocLink(resolutionFacade: ResolutionFacade,
} }
// Try to find a matching local descriptor (parameter or type parameter) first. // Try to find a matching local descriptor (parameter or type parameter) first.
if (qualifiedName.size() == 1) { if (qualifiedName.size == 1) {
val localResult = resolveInLocalScope(fromDescriptor, qualifiedName.single(), resolutionFacade) val localResult = resolveInLocalScope(fromDescriptor, qualifiedName.single(), resolutionFacade)
if (!localResult.isEmpty()) { if (!localResult.isEmpty()) {
return localResult return localResult
@@ -105,13 +102,13 @@ public fun getParamDescriptors(fromDescriptor: DeclarationDescriptor): List<Decl
// TODO resolve parameters of functions passed as parameters // TODO resolve parameters of functions passed as parameters
when (fromDescriptor) { when (fromDescriptor) {
is CallableDescriptor -> is CallableDescriptor ->
return fromDescriptor.getValueParameters() return fromDescriptor.valueParameters
is ClassifierDescriptor -> { is ClassifierDescriptor -> {
val typeParams = fromDescriptor.getTypeConstructor().getParameters() val typeParams = fromDescriptor.typeConstructor.parameters
if (fromDescriptor is ClassDescriptor) { if (fromDescriptor is ClassDescriptor) {
val constructorDescriptor = fromDescriptor.getUnsubstitutedPrimaryConstructor() val constructorDescriptor = fromDescriptor.unsubstitutedPrimaryConstructor
if (constructorDescriptor != null) { if (constructorDescriptor != null) {
return typeParams + constructorDescriptor.getValueParameters() return typeParams + constructorDescriptor.valueParameters
} }
} }
return typeParams return typeParams
@@ -123,27 +120,27 @@ public fun getParamDescriptors(fromDescriptor: DeclarationDescriptor): List<Decl
private fun resolveParamLink(fromDescriptor: DeclarationDescriptor, qualifiedName: List<String>): List<DeclarationDescriptor> { private fun resolveParamLink(fromDescriptor: DeclarationDescriptor, qualifiedName: List<String>): List<DeclarationDescriptor> {
val name = qualifiedName.singleOrNull() ?: return listOf() val name = qualifiedName.singleOrNull() ?: return listOf()
return getParamDescriptors(fromDescriptor).filter { it.getName().asString() == name } return getParamDescriptors(fromDescriptor).filter { it.name.asString() == name }
} }
private fun getPackageInnerScope(descriptor: PackageFragmentDescriptor): MemberScope { private fun getPackageInnerScope(descriptor: PackageFragmentDescriptor): MemberScope {
return descriptor.getContainingDeclaration().getPackage(descriptor.fqName).memberScope return descriptor.containingDeclaration.getPackage(descriptor.fqName).memberScope
} }
private fun getClassInnerScope(outerScope: LexicalScope, descriptor: ClassDescriptor): LexicalScope { private fun getClassInnerScope(outerScope: LexicalScope, descriptor: ClassDescriptor): LexicalScope {
val headerScope = LexicalScopeImpl(outerScope, descriptor, false, descriptor.thisAsReceiverParameter, val headerScope = LexicalScopeImpl(outerScope, descriptor, false, descriptor.thisAsReceiverParameter,
"Class ${descriptor.getName()} header scope") { "Class ${descriptor.name} header scope") {
for (typeParameter in descriptor.declaredTypeParameters) { for (typeParameter in descriptor.declaredTypeParameters) {
addClassifierDescriptor(typeParameter) addClassifierDescriptor(typeParameter)
} }
for (constructor in descriptor.getConstructors()) { for (constructor in descriptor.constructors) {
addFunctionDescriptor(constructor) addFunctionDescriptor(constructor)
} }
} }
return LexicalChainedScope(headerScope, descriptor, false, null, return LexicalChainedScope(headerScope, descriptor, false, null,
"Class ${descriptor.name} scope", "Class ${descriptor.name} scope",
descriptor.defaultType.getMemberScope(), descriptor.defaultType.memberScope,
descriptor.staticScope) descriptor.staticScope)
} }
@@ -175,9 +172,9 @@ public fun getResolutionScope(resolutionFacade: ResolutionFacade, descriptor: De
} }
private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, resolutionFacade: ResolutionFacade): LexicalScope { private fun getOuterScope(descriptor: DeclarationDescriptorWithSource, resolutionFacade: ResolutionFacade): LexicalScope {
val parent = descriptor.getContainingDeclaration() val parent = descriptor.containingDeclaration
if (parent is PackageFragmentDescriptor) { if (parent is PackageFragmentDescriptor) {
val containingFile = (descriptor.getSource() as? PsiSourceElement)?.psi?.getContainingFile() as? KtFile val containingFile = (descriptor.source as? PsiSourceElement)?.psi?.containingFile as? KtFile
if (containingFile != null) { if (containingFile != null) {
return resolutionFacade.getFileResolutionScope(containingFile) return resolutionFacade.getFileResolutionScope(containingFile)
} }
+11
View File
@@ -0,0 +1,11 @@
/**
* @see ContainingClass.classOv<caret>erload
*/
class DocReferrer
class ContainingClass {
fun classOverload() {}
fun classOverload(p: String) {}
}
// REF: (in ContainingClass).classOverload()
@@ -72,6 +72,12 @@ public class KdocResolveTestGenerated extends AbstractReferenceResolveTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("Overloads.kt")
public void testOverloads() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kdoc/resolve/Overloads.kt");
doTest(fileName);
}
@TestMetadata("ParamReference.kt") @TestMetadata("ParamReference.kt")
public void testParamReference() throws Exception { public void testParamReference() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kdoc/resolve/ParamReference.kt"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kdoc/resolve/ParamReference.kt");