change KDoc parsing so that space after parameter/section name is not included in tag content; support @property tag in KDocFinder
This commit is contained in:
@@ -88,14 +88,14 @@ CODE_LINK=\[{QUALIFIED_NAME}\]
|
||||
/* Example: @return[x] The return value of function x
|
||||
^^^
|
||||
*/
|
||||
{CODE_LINK} { yybegin(CONTENTS);
|
||||
{CODE_LINK} { yybegin(TAG_TEXT_BEGINNING);
|
||||
return KDocTokens.MARKDOWN_LINK; }
|
||||
|
||||
/* Example: @param aaa The value of aaa
|
||||
^^^
|
||||
*/
|
||||
{QUALIFIED_NAME} {
|
||||
yybegin(CONTENTS);
|
||||
yybegin(TAG_TEXT_BEGINNING);
|
||||
return KDocTokens.MARKDOWN_LINK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* The following code was generated by JFlex 1.4.3 on 2/6/15 12:23 PM */
|
||||
/* The following code was generated by JFlex 1.4.3 on 3/5/15 7:51 PM */
|
||||
|
||||
package org.jetbrains.kotlin.kdoc.lexer;
|
||||
|
||||
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag;
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.4.3
|
||||
* on 2/6/15 12:23 PM from the specification file
|
||||
* on 3/5/15 7:51 PM from the specification file
|
||||
* <tt>/Users/yole/jetbrains/kotlin/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex</tt>
|
||||
*/
|
||||
class _KDocLexer implements FlexLexer {
|
||||
@@ -117,11 +117,11 @@ class _KDocLexer implements FlexLexer {
|
||||
|
||||
private static final String ZZ_ACTION_PACKED_0 =
|
||||
"\6\0\3\1\1\2\1\3\1\2\1\4\3\2\1\5"+
|
||||
"\1\6\1\7\2\5\1\0\1\10\2\0\1\11\1\12"+
|
||||
"\1\0\1\13\1\0\1\14\1\15";
|
||||
"\1\6\1\7\3\5\1\0\1\10\2\0\1\11\1\12"+
|
||||
"\2\0\1\13\1\0\1\14\1\15\1\16";
|
||||
|
||||
private static int [] zzUnpackAction() {
|
||||
int [] result = new int[32];
|
||||
int [] result = new int[35];
|
||||
int offset = 0;
|
||||
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -148,11 +148,12 @@ class _KDocLexer implements FlexLexer {
|
||||
private static final String ZZ_ROWMAP_PACKED_0 =
|
||||
"\0\0\0\15\0\32\0\47\0\64\0\101\0\116\0\133"+
|
||||
"\0\150\0\116\0\165\0\202\0\217\0\234\0\150\0\251"+
|
||||
"\0\116\0\266\0\303\0\320\0\150\0\335\0\116\0\150"+
|
||||
"\0\352\0\116\0\367\0\u0104\0\116\0\u0111\0\116\0\116";
|
||||
"\0\116\0\266\0\303\0\320\0\150\0\335\0\352\0\116"+
|
||||
"\0\150\0\367\0\116\0\u0104\0\u0111\0\u011e\0\116\0\u012b"+
|
||||
"\0\116\0\116\0\116";
|
||||
|
||||
private static int [] zzUnpackRowMap() {
|
||||
int [] result = new int[32];
|
||||
int [] result = new int[35];
|
||||
int offset = 0;
|
||||
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -179,18 +180,18 @@ class _KDocLexer implements FlexLexer {
|
||||
"\3\12\1\14\2\12\1\15\1\12\1\13\1\16\2\12"+
|
||||
"\1\13\3\12\1\14\2\12\1\17\1\20\1\13\1\16"+
|
||||
"\1\12\1\21\1\22\1\21\1\23\1\21\1\24\2\21"+
|
||||
"\1\25\1\21\1\22\3\21\1\22\3\21\1\24\2\21"+
|
||||
"\1\25\1\21\1\22\3\21\1\22\3\21\1\26\2\21"+
|
||||
"\1\25\1\21\1\22\2\21\1\12\1\13\3\12\1\14"+
|
||||
"\2\12\1\17\1\12\1\13\1\16\1\12\25\0\1\26"+
|
||||
"\13\0\1\27\1\30\5\0\1\13\10\0\1\13\5\0"+
|
||||
"\1\31\20\0\1\27\1\15\11\0\2\32\11\0\1\33"+
|
||||
"\12\0\1\22\10\0\1\22\4\0\3\23\13\0\1\34"+
|
||||
"\21\0\1\35\6\0\3\31\1\0\1\36\10\0\2\33"+
|
||||
"\13\0\3\34\1\0\1\37\6\0\5\40\1\0\6\40"+
|
||||
"\1\0";
|
||||
"\2\12\1\17\1\12\1\13\1\16\1\12\25\0\1\27"+
|
||||
"\13\0\1\30\1\31\5\0\1\13\10\0\1\13\5\0"+
|
||||
"\1\32\20\0\1\30\1\15\11\0\2\33\11\0\1\34"+
|
||||
"\12\0\1\22\10\0\1\22\4\0\3\23\13\0\1\35"+
|
||||
"\14\0\1\36\21\0\1\37\6\0\3\32\1\0\1\40"+
|
||||
"\10\0\2\34\13\0\3\35\1\0\1\41\10\0\3\36"+
|
||||
"\1\0\1\42\6\0\5\43\1\0\6\43\1\0";
|
||||
|
||||
private static int [] zzUnpackTrans() {
|
||||
int [] result = new int[286];
|
||||
int [] result = new int[312];
|
||||
int offset = 0;
|
||||
offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -231,11 +232,11 @@ class _KDocLexer implements FlexLexer {
|
||||
private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute();
|
||||
|
||||
private static final String ZZ_ATTRIBUTE_PACKED_0 =
|
||||
"\6\0\1\11\2\1\1\11\6\1\1\11\4\1\1\0"+
|
||||
"\1\11\2\0\1\11\1\1\1\0\1\11\1\0\2\11";
|
||||
"\6\0\1\11\2\1\1\11\6\1\1\11\5\1\1\0"+
|
||||
"\1\11\2\0\1\11\1\1\2\0\1\11\1\0\3\11";
|
||||
|
||||
private static int [] zzUnpackAttribute() {
|
||||
int [] result = new int[32];
|
||||
int [] result = new int[35];
|
||||
int offset = 0;
|
||||
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -567,7 +568,7 @@ class _KDocLexer implements FlexLexer {
|
||||
yybegin(tag != null && tag.isReferenceRequired() ? TAG_BEGINNING : TAG_TEXT_BEGINNING);
|
||||
return KDocTokens.TAG_NAME;
|
||||
}
|
||||
case 14: break;
|
||||
case 15: break;
|
||||
case 3:
|
||||
{ if (yytextContainLineBreaks()) {
|
||||
yybegin(LINE_BEGINNING);
|
||||
@@ -577,65 +578,70 @@ class _KDocLexer implements FlexLexer {
|
||||
return KDocTokens.TEXT; // internal white space
|
||||
}
|
||||
}
|
||||
case 15: break;
|
||||
case 16: break;
|
||||
case 11:
|
||||
{ yybegin(CONTENTS_BEGINNING);
|
||||
return KDocTokens.START;
|
||||
}
|
||||
case 16: break;
|
||||
case 17: break;
|
||||
case 8:
|
||||
{ if (isLastToken()) return KDocTokens.END;
|
||||
else return KDocTokens.TEXT;
|
||||
}
|
||||
case 17: break;
|
||||
case 18: break;
|
||||
case 5:
|
||||
{ yybegin(CONTENTS);
|
||||
return KDocTokens.TEXT;
|
||||
}
|
||||
case 18: break;
|
||||
case 19: break;
|
||||
case 12:
|
||||
{ yybegin(TAG_TEXT_BEGINNING);
|
||||
return KDocTokens.MARKDOWN_LINK;
|
||||
}
|
||||
case 20: break;
|
||||
case 7:
|
||||
{ yybegin(TAG_TEXT_BEGINNING);
|
||||
return KDocTokens.MARKDOWN_LINK;
|
||||
}
|
||||
case 21: break;
|
||||
case 6:
|
||||
{ if (yytextContainLineBreaks()) {
|
||||
yybegin(LINE_BEGINNING);
|
||||
}
|
||||
return TokenType.WHITE_SPACE;
|
||||
}
|
||||
case 19: break;
|
||||
case 13:
|
||||
case 22: break;
|
||||
case 14:
|
||||
// lookahead expression with fixed lookahead length
|
||||
yypushback(1);
|
||||
{ yybegin(CONTENTS);
|
||||
return KDocTokens.MARKDOWN_LINK;
|
||||
}
|
||||
case 20: break;
|
||||
case 12:
|
||||
case 23: break;
|
||||
case 13:
|
||||
{ yybegin(CONTENTS);
|
||||
return KDocTokens.MARKDOWN_LINK;
|
||||
}
|
||||
case 21: break;
|
||||
case 24: break;
|
||||
case 1:
|
||||
{ return TokenType.BAD_CHARACTER;
|
||||
}
|
||||
case 22: break;
|
||||
case 25: break;
|
||||
case 9:
|
||||
{ yybegin(CONTENTS);
|
||||
return KDocTokens.MARKDOWN_ESCAPED_CHAR;
|
||||
}
|
||||
case 23: break;
|
||||
case 26: break;
|
||||
case 2:
|
||||
{ yybegin(CONTENTS);
|
||||
return KDocTokens.TEXT;
|
||||
}
|
||||
case 24: break;
|
||||
case 7:
|
||||
{ yybegin(CONTENTS);
|
||||
return KDocTokens.MARKDOWN_LINK;
|
||||
}
|
||||
case 25: break;
|
||||
case 27: break;
|
||||
case 4:
|
||||
{ yybegin(CONTENTS_BEGINNING);
|
||||
return KDocTokens.LEADING_ASTERISK;
|
||||
}
|
||||
case 26: break;
|
||||
case 28: break;
|
||||
default:
|
||||
if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
|
||||
zzAtEOF = true;
|
||||
|
||||
@@ -27,4 +27,5 @@ public trait KDoc : PsiComment {
|
||||
public fun getDefaultSection(): KDocSection
|
||||
public fun findSectionByName(name: String): KDocSection?
|
||||
public fun findSectionByTag(tag: KDocKnownTag): KDocSection?
|
||||
public fun findSectionByTag(tag: KDocKnownTag, subjectName: String): KDocSection?
|
||||
}
|
||||
|
||||
@@ -46,4 +46,9 @@ public class KDocImpl(buffer: CharSequence?) : LazyParseablePsiElement(KDocToken
|
||||
|
||||
override fun findSectionByTag(tag: KDocKnownTag): KDocSection? =
|
||||
findSectionByName(tag.name().toLowerCase())
|
||||
|
||||
override fun findSectionByTag(tag: KDocKnownTag, subjectName: String): KDocSection? =
|
||||
getChildrenOfType<KDocSection>().firstOrNull {
|
||||
it.getName() == tag.name().toLowerCase() && it.getSubjectName() == subjectName
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,9 @@ public class KDocSection(node: ASTNode) : KDocTag(node) {
|
||||
override fun getName(): String? =
|
||||
(getFirstChild() as? KDocTag)?.getName()
|
||||
|
||||
override fun getSubjectName(): String? =
|
||||
(getFirstChild() as? KDocTag)?.getSubjectName()
|
||||
|
||||
override fun getContent(): String =
|
||||
(getFirstChild() as? KDocTag)?.getContent() ?: super.getContent()
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public open class KDocTag(node: ASTNode) : KDocElementImpl(node) {
|
||||
* Returns the name of the entity documented by this tag (for example, the name of the parameter
|
||||
* for the @param tag), or null if this tag does not document any specific entity.
|
||||
*/
|
||||
public fun getSubjectName(): String? = getSubjectLink()?.getLinkText()
|
||||
public open fun getSubjectName(): String? = getSubjectLink()?.getLinkText()
|
||||
|
||||
public fun getSubjectLink(): KDocLink? {
|
||||
val children = childrenAfterTagName()
|
||||
|
||||
@@ -13,6 +13,7 @@ JetFile: ParamTag.kt
|
||||
KDOC_MARKDOWN_LINK
|
||||
KDOC_NAME
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(KDOC_TEXT)(' The description of a.')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(KDOC_TEXT)('The description of a.')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(KDOC_END)('*/')
|
||||
@@ -11,5 +11,6 @@ JetFile: ParamTagAtStart.kt
|
||||
KDOC_MARKDOWN_LINK
|
||||
KDOC_NAME
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(KDOC_TEXT)(' this is a ')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(KDOC_TEXT)('this is a ')
|
||||
PsiElement(KDOC_END)('*/')
|
||||
@@ -16,7 +16,8 @@ JetFile: Sections.kt
|
||||
KDOC_MARKDOWN_LINK
|
||||
KDOC_NAME
|
||||
PsiElement(IDENTIFIER)('T')
|
||||
PsiElement(KDOC_TEXT)(' a type parameter.')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(KDOC_TEXT)('a type parameter.')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(KDOC_LEADING_ASTERISK)('*')
|
||||
PsiElement(KDOC_TEXT)(' ')
|
||||
@@ -34,6 +35,7 @@ JetFile: Sections.kt
|
||||
KDOC_MARKDOWN_LINK
|
||||
KDOC_NAME
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(KDOC_TEXT)(' a constructor parameter.')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(KDOC_TEXT)('a constructor parameter.')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(KDOC_END)('*/')
|
||||
@@ -16,14 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.kdoc
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag
|
||||
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
|
||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||
|
||||
object KDocFinder {
|
||||
fun findKDoc(declaration: DeclarationDescriptor): KDocTag? {
|
||||
@@ -44,6 +43,20 @@ object KDocFinder {
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration is PropertyDescriptor) {
|
||||
val containingClassDescriptor = declaration.getContainingDeclaration() as? ClassDescriptor
|
||||
if (containingClassDescriptor != null) {
|
||||
val classKDoc = findKDoc(containingClassDescriptor)?.getParentOfType<KDoc>(false)
|
||||
if (classKDoc != null) {
|
||||
val propertySection = classKDoc.findSectionByTag(KDocKnownTag.PROPERTY,
|
||||
declaration.getName().asString())
|
||||
if (propertySection != null) {
|
||||
return propertySection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration is CallableDescriptor) {
|
||||
for (baseDescriptor in declaration.getOverriddenDescriptors()) {
|
||||
val baseKDoc = findKDoc(baseDescriptor.getOriginal())
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* @property xyzzy Doc for property xyzzy
|
||||
*/
|
||||
class Foo(val xyzzy: String)
|
||||
@@ -55,4 +55,13 @@ public class KDocFinderTest() : LightPlatformCodeInsightFixtureTestCase() {
|
||||
val doc = KDocFinder.findKDoc(overriddenFunctionDescriptor)
|
||||
Assert.assertEquals("Doc for method xyzzy", doc!!.getContent())
|
||||
}
|
||||
|
||||
public fun testProperty() {
|
||||
myFixture.configureByFile(getTestName(false) + ".kt")
|
||||
val declaration = (myFixture.getFile() as JetFile).getDeclarations().single { it.getName() == "Foo" }
|
||||
val descriptor = declaration.resolveToDescriptor() as ClassDescriptor
|
||||
val propertyDescriptor = descriptor.getDefaultType().getMemberScope().getProperties(Name.identifier("xyzzy")).single()
|
||||
val doc = KDocFinder.findKDoc(propertyDescriptor)
|
||||
Assert.assertEquals("Doc for property xyzzy", doc!!.getContent())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user