support @receiver KDoc tag; somewhat more precise tag name completion

This commit is contained in:
Dmitry Jemerov
2016-04-28 17:02:43 +02:00
parent 3b57b78ddc
commit 94c241443b
9 changed files with 80 additions and 1 deletions
@@ -23,6 +23,7 @@ enum class KDocKnownTag private constructor(val isReferenceRequired: Boolean, va
THROWS(true, false),
EXCEPTION(true, false),
PARAM(true, false),
RECEIVER(false, false),
RETURN(false, false),
SEE(true, false),
SINCE(false, false),
@@ -32,8 +32,13 @@ 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.parser.KDocKnownTag
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink
import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
@@ -134,9 +139,19 @@ object KDocTagCompletionProvider: CompletionProvider<CompletionParameters>() {
if (prefix.length > 0 && !prefix.startsWith('@')) {
return
}
val kdocOwner = parameters.position.getNonStrictParentOfType<KDoc>()?.getOwner()
val resultWithPrefix = result.withPrefixMatcher(prefix)
KDocKnownTag.values().forEach {
resultWithPrefix.addElement(LookupElementBuilder.create("@" + it.name.toLowerCase()))
if (kdocOwner == null || it.isApplicable(kdocOwner)) {
resultWithPrefix.addElement(LookupElementBuilder.create("@" + it.name.toLowerCase()))
}
}
}
private fun KDocKnownTag.isApplicable(declaration: KtDeclaration) = when(this) {
KDocKnownTag.CONSTRUCTOR, KDocKnownTag.PROPERTY -> declaration is KtClassOrObject
KDocKnownTag.RETURN -> declaration is KtNamedFunction
KDocKnownTag.RECEIVER -> declaration is KtNamedFunction && declaration.receiverTypeReference != null
else -> true
}
}
+1
View File
@@ -7,3 +7,4 @@ fun f(x: Int): Int {
// EXIST: @param
// EXIST: @return
// EXIST: @suppress
// ABSENT: @receiver
+12
View File
@@ -0,0 +1,12 @@
/**
* <caret>
*/
class C<T> {
}
// EXIST: @param
// EXIST: @suppress
// EXIST: @constructor
// EXIST: @property
// ABSENT: @return
// ABSENT: @receiver
@@ -0,0 +1,12 @@
/**
* <caret>
*/
fun Int.f(): Int {
}
// EXIST: @param
// EXIST: @return
// EXIST: @suppress
// EXIST: @receiver
// ABSENT: @constructor
// ABSENT: @property
@@ -77,6 +77,18 @@ public class KDocCompletionTestGenerated extends AbstractJvmBasicCompletionTest
doTest(fileName);
}
@TestMetadata("TagNameInClass.kt")
public void testTagNameInClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/kdoc/TagNameInClass.kt");
doTest(fileName);
}
@TestMetadata("TagNameInExtensionFunction.kt")
public void testTagNameInExtensionFunction() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/kdoc/TagNameInExtensionFunction.kt");
doTest(fileName);
}
@TestMetadata("TagNameMiddle.kt")
public void testTagNameMiddle() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/kdoc/TagNameMiddle.kt");
@@ -33,6 +33,7 @@ object KDocRenderer {
result.append(markdownToHtml(content, allowSingleParagraph = true))
if (docComment is KDocSection) {
result.append("\n")
renderTag(docComment.findTagByName("receiver"), "Receiver", result)
val paramTags = docComment.findTagsByName("param").filter { it.getSubjectName() != null }
renderTagList(paramTags, "Parameters", result)
@@ -0,0 +1,19 @@
/**
Some documentation
* @receiver Some int
* @param b String
* @return Return [a] and nothing else
*/
fun Int.testMethod(b: String) {
}
fun test() {
1.<caret>testMethod("value")
}
//INFO: <b>public</b> <b>fun</b> Int.testMethod(b: String): Unit <i>defined in</i> root package<p>Some documentation</p>
//INFO: <dl><dt><b>Receiver:</b></dt><dd>Some int</dd></dl>
//INFO: <dl><dt><b>Parameters:</b></dt><dd><code>b</code> - String</dd></dl>
//INFO: <dl><dt><b>Returns:</b></dt><dd>Return <a href="psi_element://a">a</a> and nothing else</dd></dl>
@@ -143,6 +143,12 @@ public class QuickDocProviderTestGenerated extends AbstractQuickDocProviderTest
doTest(fileName);
}
@TestMetadata("OnMethodUsageWithReceiver.kt")
public void testOnMethodUsageWithReceiver() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/editor/quickDoc/OnMethodUsageWithReceiver.kt");
doTest(fileName);
}
@TestMetadata("OnMethodUsageWithReturnAndLink.kt")
public void testOnMethodUsageWithReturnAndLink() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/editor/quickDoc/OnMethodUsageWithReturnAndLink.kt");