IDEA-141852 Quick documentation doesn't support @value tag without hash preceding variable reference

This commit is contained in:
Dmitry Batrak
2015-08-14 15:52:10 +03:00
parent 232d795f68
commit decd330820
13 changed files with 162 additions and 15 deletions
@@ -1415,6 +1415,9 @@ public class JavaDocInfoGenerator {
if (myElement instanceof PsiField) valueField = (PsiField) myElement;
}
else {
if (text.indexOf('#') == -1) {
text = "#" + text;
}
PsiElement target = JavaDocUtil.findReferenceTarget(PsiManager.getInstance(myProject), text, myElement);
if (target instanceof PsiField) {
valueField = (PsiField) target;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -137,11 +137,11 @@ public class JavadocParser {
else if (TAG_VALUES_SET.contains(tokenType)) {
if (SEE_TAG.equals(tagName) && !isInline ||
LINK_TAG.equals(tagName) && isInline) {
parseSeeTagValue(builder);
parseSeeTagValue(builder, false);
}
else {
if (JavaParserUtil.getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_4) && LINK_PLAIN_TAG.equals(tagName) && isInline) {
parseSeeTagValue(builder);
parseSeeTagValue(builder, false);
}
else if (!isInline && (THROWS_TAG.equals(tagName) || EXCEPTION_TAG.equals(tagName))) {
final PsiBuilder.Marker tagValue = builder.mark();
@@ -154,7 +154,7 @@ public class JavadocParser {
}
else {
if (JavaParserUtil.getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_5) && VALUE_TAG.equals(tagName) && isInline) {
parseSeeTagValue(builder);
parseSeeTagValue(builder, true);
}
else {
parseSimpleTagValue(builder, false);
@@ -167,7 +167,7 @@ public class JavadocParser {
}
}
private static void parseSeeTagValue(@NotNull final PsiBuilder builder) {
private static void parseSeeTagValue(@NotNull final PsiBuilder builder, boolean allowBareFieldReference) {
final IElementType tokenType = getTokenType(builder);
if (tokenType == JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN) {
parseMethodRef(builder, builder.mark());
@@ -180,6 +180,11 @@ public class JavadocParser {
if (getTokenType(builder) == JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN) {
parseMethodRef(builder, refStart);
}
else if (allowBareFieldReference) {
refStart.rollbackTo();
builder.remapCurrentToken(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
parseMethodRef(builder, builder.mark());
}
else {
refStart.drop();
}
@@ -192,8 +197,9 @@ public class JavadocParser {
}
private static void parseMethodRef(@NotNull final PsiBuilder builder, @NotNull final PsiBuilder.Marker refStart) {
builder.advanceLexer();
if (getTokenType(builder) == JavaDocTokenType.DOC_TAG_VALUE_SHARP_TOKEN) {
builder.advanceLexer();
}
if (getTokenType(builder) != JavaDocTokenType.DOC_TAG_VALUE_TOKEN) {
refStart.done(JavaDocElementType.DOC_METHOD_OR_FIELD_REF);
return;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -155,8 +155,8 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
@Nullable
public PsiElement getNameElement() {
final ASTNode sharp = findChildByType(DOC_TAG_VALUE_SHARP_TOKEN);
return sharp != null ? SourceTreeToPsiMap.treeToPsiNotNull(sharp).getNextSibling() : null;
final ASTNode name = findChildByType(DOC_TAG_VALUE_TOKEN);
return name != null ? SourceTreeToPsiMap.treeToPsiNotNull(name) : null;
}
@Nullable
@@ -174,11 +174,9 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
if (child.getNode().getElementType() == DOC_TYPE_HOLDER) {
final String[] typeStrings = child.getText().split("[, ]"); //avoid param types list parsing hmm method(paramType1, paramType2, ...) -> typeElement1, identifier2, ...
if (typeStrings != null) {
for (String type : typeStrings) {
if (!type.isEmpty()) {
types.add(type);
}
for (String type : typeStrings) {
if (!type.isEmpty()) {
types.add(type);
}
}
}
@@ -0,0 +1 @@
<html><head><base href="placeholder"> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } p { margin: 5px 0; } </style></head><body><small><b><a href="psi_element://A"><code>A</code></a></b></small><PRE>public static&nbsp;void&nbsp;<b>JAVADOC_ME</b>()</PRE> The value of A is 23.</body></html>
@@ -0,0 +1,6 @@
class A {
public static int A = 23;
/** The value of A is {@value A}. */
public static void JAVADOC_ME() { }
}
@@ -0,0 +1,4 @@
/**
* {@value some.class#FIELD}
*/
class Test {}
@@ -0,0 +1,46 @@
PsiJavaFile:ValueQualified.java
PsiImportList
<empty list>
PsiClass:Test
PsiDocComment
PsiDocToken:DOC_COMMENT_START('/**')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('*')
PsiDocToken:DOC_COMMENT_DATA(' ')
PsiInlineDocTag:@value
PsiDocToken:DOC_INLINE_TAG_START('{')
PsiDocToken:DOC_TAG_NAME('@value')
PsiWhiteSpace(' ')
PsiElement(DOC_METHOD_OR_FIELD_REF)
PsiElement(DOC_REFERENCE_HOLDER)
PsiJavaCodeReferenceElement:some.
PsiJavaCodeReferenceElement:some
PsiIdentifier:some('some')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiErrorElement:Identifier expected
<empty list>
PsiReferenceParameterList
<empty list>
PsiKeyword:class('class')
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('FIELD')
PsiDocToken:DOC_INLINE_TAG_END('}')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_END('*/')
PsiWhiteSpace('\n')
PsiModifierList:
<empty list>
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Test('Test')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -0,0 +1,4 @@
/**
* {@value #FIELD}
*/
class Test {}
@@ -0,0 +1,34 @@
PsiJavaFile:ValueUnqualifiedWithHash.java
PsiImportList
<empty list>
PsiClass:Test
PsiDocComment
PsiDocToken:DOC_COMMENT_START('/**')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('*')
PsiDocToken:DOC_COMMENT_DATA(' ')
PsiInlineDocTag:@value
PsiDocToken:DOC_INLINE_TAG_START('{')
PsiDocToken:DOC_TAG_NAME('@value')
PsiWhiteSpace(' ')
PsiElement(DOC_METHOD_OR_FIELD_REF)
PsiDocToken:DOC_TAG_VALUE_SHARP_TOKEN('#')
PsiDocToken:DOC_TAG_VALUE_TOKEN('FIELD')
PsiDocToken:DOC_INLINE_TAG_END('}')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_END('*/')
PsiWhiteSpace('\n')
PsiModifierList:
<empty list>
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Test('Test')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -0,0 +1,4 @@
/**
* {@value FIELD}
*/
class Test {}
@@ -0,0 +1,33 @@
PsiJavaFile:ValueUnqualifiedWithoutHash.java
PsiImportList
<empty list>
PsiClass:Test
PsiDocComment
PsiDocToken:DOC_COMMENT_START('/**')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('*')
PsiDocToken:DOC_COMMENT_DATA(' ')
PsiInlineDocTag:@value
PsiDocToken:DOC_INLINE_TAG_START('{')
PsiDocToken:DOC_TAG_NAME('@value')
PsiWhiteSpace(' ')
PsiElement(DOC_METHOD_OR_FIELD_REF)
PsiDocToken:DOC_TAG_VALUE_TOKEN('FIELD')
PsiDocToken:DOC_INLINE_TAG_END('}')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_END('*/')
PsiWhiteSpace('\n')
PsiModifierList:
<empty list>
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Test('Test')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -48,6 +48,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
doTestMethod();
}
public void testValueInMethodNoHash() throws Exception {
doTestMethod();
}
public void testIdeadev2326() throws Exception {
doTestMethod();
}
@@ -87,4 +87,8 @@ public class JavadocParsingTest extends JavaParsingTestCase {
public void testLiteralTag() { doTest(true); }
public void testIDEADEV_41403() { doTest(true); }
public void testValueQualified() { doTest(true); }
public void testValueUnqualifiedWithHash() { doTest(true); }
public void testValueUnqualifiedWithoutHash() { doTest(true); }
}