From 98310d3bdb364d2db1761f98994dfb3d188fbcb4 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 23 Oct 2017 05:21:37 +0300 Subject: [PATCH] KT-20884: Support receiver reference in KDoc comments #KT-20884 fixed --- .../kotlin/resolve/DescriptorToSourceUtils.kt | 15 +++++++++++++++ .../jetbrains/kotlin/idea/kdoc/resolveKDocLink.kt | 4 ++++ idea/testData/kdoc/resolve/ReceiverReference.kt | 8 ++++++++ .../idea/kdoc/KdocResolveTestGenerated.java | 6 ++++++ 4 files changed, 33 insertions(+) create mode 100644 idea/testData/kdoc/resolve/ReceiverReference.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt index 877c09ad60e..c2e4842d945 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorToSourceUtils.kt @@ -23,7 +23,9 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZE import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver import org.jetbrains.kotlin.resolve.source.getPsi import java.util.* @@ -51,7 +53,20 @@ object DescriptorToSourceUtils { return result } + // TODO Fix in descriptor + @JvmStatic private fun getSourceForExtensionReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor): PsiElement? { + // Only for extension receivers + if (descriptor.source != SourceElement.NO_SOURCE || descriptor.value !is ExtensionReceiver) return null + val containingDeclaration = descriptor.containingDeclaration as? CallableDescriptor ?: return null + val psi = containingDeclaration.source.getPsi() as? KtCallableDeclaration ?: return null + return psi.receiverTypeReference + } + @JvmStatic fun getSourceFromDescriptor(descriptor: DeclarationDescriptor): PsiElement? { + if (descriptor is ReceiverParameterDescriptor) { + getSourceForExtensionReceiverParameterDescriptor(descriptor)?.let { return it } + } + return (descriptor as? DeclarationDescriptorWithSource)?.source?.getPsi() } diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/kdoc/resolveKDocLink.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/kdoc/resolveKDocLink.kt index b66aedbaffa..013ab1316bd 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/kdoc/resolveKDocLink.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/kdoc/resolveKDocLink.kt @@ -119,6 +119,10 @@ private fun resolveDefaultKDocLink( descriptorsByName.addAll(contextScope.collectFunctions(shortName, NoLookupLocation.FROM_IDE)) descriptorsByName.addAll(contextScope.collectVariables(shortName, NoLookupLocation.FROM_IDE)) + if (fromDescriptor is FunctionDescriptor && fromDescriptor.isExtension && shortName.asString() == "this") { + return listOfNotNull(fromDescriptor.extensionReceiverParameter) + } + // Try to find a matching local descriptor (parameter or type parameter) first val localDescriptors = descriptorsByName.filter { it.containingDeclaration == fromDescriptor } if (localDescriptors.isNotEmpty()) return localDescriptors diff --git a/idea/testData/kdoc/resolve/ReceiverReference.kt b/idea/testData/kdoc/resolve/ReceiverReference.kt new file mode 100644 index 00000000000..886791aa90c --- /dev/null +++ b/idea/testData/kdoc/resolve/ReceiverReference.kt @@ -0,0 +1,8 @@ +class Foo + +/** + * [this] + */ +fun Foo.bar {} + +// REF: Foo \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/kdoc/KdocResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/kdoc/KdocResolveTestGenerated.java index 91dc288a2d2..3f70049d3ff 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/kdoc/KdocResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/kdoc/KdocResolveTestGenerated.java @@ -157,6 +157,12 @@ public class KdocResolveTestGenerated extends AbstractReferenceResolveTest { doTest(fileName); } + @TestMetadata("ReceiverReference.kt") + public void testReceiverReference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kdoc/resolve/ReceiverReference.kt"); + doTest(fileName); + } + @TestMetadata("SeeReference.kt") public void testSeeReference() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/kdoc/resolve/SeeReference.kt");