Fix tests according to new PSI structure; move doc comment text calculation from JetQuickDocumentationProvider to KDocTag.getContent()
This commit is contained in:
@@ -57,7 +57,7 @@ public interface KDocTokens {
|
||||
|
||||
/**
|
||||
* First word following the tag name (@xxx). Depending on the tag name, this can be
|
||||
* either a link (@param xxx) or just a plain text word (@author name).
|
||||
* either a link (@param xxx) or just a plain text word (@since version).
|
||||
* We understand which one it is during parsing.
|
||||
*/
|
||||
KDocToken TEXT_OR_LINK = new KDocToken("KDOC_TEXT_OR_LINK");
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
package org.jetbrains.kotlin.kdoc.psi.api;
|
||||
|
||||
import com.intellij.psi.PsiComment;
|
||||
import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection;
|
||||
|
||||
// Don't implement JetElement (or it will be treated as statement)
|
||||
public interface KDoc extends PsiComment {
|
||||
KDocSection getDefaultSection();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.kdoc.psi.impl;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.psi.impl.source.tree.LazyParseablePsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.JetLanguage;
|
||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
|
||||
@@ -45,4 +46,9 @@ public class KDocImpl extends LazyParseablePsiElement implements KDoc {
|
||||
public IElementType getTokenType() {
|
||||
return JetTokens.DOC_COMMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KDocSection getDefaultSection() {
|
||||
return PsiTreeUtil.getChildOfType(this, KDocSection.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* can have sections for the class itself, its primary constructor and each of the
|
||||
* properties defined in the primary constructor.
|
||||
*/
|
||||
public class KDocSection extends KDocElementImpl {
|
||||
public class KDocSection extends KDocTag {
|
||||
public KDocSection(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@@ -17,11 +17,68 @@
|
||||
package org.jetbrains.kotlin.kdoc.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
|
||||
import org.jetbrains.kotlin.kdoc.parser.KDocElementTypes;
|
||||
|
||||
public class KDocTag extends KDocElementImpl {
|
||||
public KDocTag(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
boolean contentStarted = false;
|
||||
boolean afterAsterisk = false;
|
||||
boolean startsWithTagName = false;
|
||||
|
||||
ASTNode[] children = getNode().getChildren(null);
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
ASTNode node = children[i];
|
||||
IElementType type = node.getElementType();
|
||||
if (i == 0 && type == KDocTokens.TAG_NAME) {
|
||||
startsWithTagName = true;
|
||||
}
|
||||
if (KDocTokens.CONTENT_TOKENS.contains(type) || type == KDocElementTypes.KDOC_LINK) {
|
||||
contentStarted = true;
|
||||
builder.append(afterAsterisk ? StringUtil.trimLeading(node.getText()) : node.getText());
|
||||
afterAsterisk = false;
|
||||
}
|
||||
|
||||
if (type == KDocTokens.LEADING_ASTERISK || type == KDocTokens.START) {
|
||||
afterAsterisk = true;
|
||||
}
|
||||
|
||||
if (type == TokenType.WHITE_SPACE) {
|
||||
if (i == 1 && startsWithTagName) {
|
||||
builder.append(node.getText());
|
||||
}
|
||||
else if (contentStarted) {
|
||||
builder.append(StringUtil.repeat("\n", StringUtil.countNewLines(node.getText())));
|
||||
}
|
||||
}
|
||||
|
||||
if (type == KDocElementTypes.KDOC_TAG) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public String getContentWithTags() {
|
||||
StringBuilder content = new StringBuilder(getContent());
|
||||
KDocTag[] subTags = PsiTreeUtil.getChildrenOfType(this, KDocTag.class);
|
||||
if (subTags != null) {
|
||||
for (KDocTag tag : subTags) {
|
||||
content.append(tag.getContentWithTags()).append("\n");
|
||||
}
|
||||
}
|
||||
return content.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ public class JetCodeConformanceTest extends TestCase {
|
||||
new File("docs"),
|
||||
new File("ideaSDK"),
|
||||
new File("libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/build/tmp"),
|
||||
new File("compiler/testData/psi/kdoc"),
|
||||
new File("compiler/tests/org/jetbrains/kotlin/parsing/JetCodeConformanceTest.java"));
|
||||
public static final Pattern AUTHOR_JAVADOC_PATTERN = Pattern.compile("/\\*.+@author.+\\*/", Pattern.DOTALL);
|
||||
|
||||
|
||||
@@ -22,13 +22,11 @@ import com.intellij.lang.java.JavaDocumentationProvider;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.asJava.KotlinLightMethod;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
|
||||
import org.jetbrains.kotlin.kdoc.psi.api.KDoc;
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration;
|
||||
import org.jetbrains.kotlin.psi.JetPackageDirective;
|
||||
@@ -117,36 +115,9 @@ public class JetQuickDocumentationProvider extends AbstractDocumentationProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getKDocContent(@NotNull KDoc kDoc) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
boolean contentStarted = false;
|
||||
boolean afterAsterisk = false;
|
||||
|
||||
for (PsiElement element : kDoc.getChildren()) {
|
||||
IElementType type = element.getNode().getElementType();
|
||||
|
||||
if (KDocTokens.CONTENT_TOKENS.contains(type)) {
|
||||
contentStarted = true;
|
||||
builder.append(afterAsterisk ? StringUtil.trimLeading(element.getText()) : element.getText());
|
||||
afterAsterisk = false;
|
||||
}
|
||||
|
||||
if (type == KDocTokens.LEADING_ASTERISK || type == KDocTokens.START) {
|
||||
afterAsterisk = true;
|
||||
}
|
||||
|
||||
if (contentStarted && element instanceof PsiWhiteSpace) {
|
||||
builder.append(StringUtil.repeat("\n", StringUtil.countNewLines(element.getText())));
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static String kDocToHtml(@NotNull KDoc comment) {
|
||||
// TODO: Parse and show markdown comments as html
|
||||
String content = getKDocContent(comment);
|
||||
String content = comment.getDefaultSection().getContentWithTags();
|
||||
String htmlContent = StringUtil.replace(content, "\n", "<br/>")
|
||||
.replaceAll("(@param)\\s+(\\w+)", "@param - <i>$2</i>")
|
||||
.replaceAll("(@\\w+)", "<b>$1</b>");
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.JetNodeTypes.*
|
||||
import org.jetbrains.kotlin.psi.JetContainerNode
|
||||
import org.jetbrains.kotlin.idea.JetLanguage
|
||||
import org.jetbrains.kotlin.kdoc.parser.KDocElementTypes
|
||||
|
||||
public class KotlinWordSelectionFilter : Condition<PsiElement>{
|
||||
override fun value(e: PsiElement): Boolean {
|
||||
@@ -31,7 +32,7 @@ public class KotlinWordSelectionFilter : Condition<PsiElement>{
|
||||
if (e.getParent().getFirstChild().getNextSibling() == null && e.getParent() !is JetContainerNode) return false // skip nodes with the same range as their parent
|
||||
|
||||
return when (e.getNode().getElementType()) {
|
||||
BLOCK, LITERAL_STRING_TEMPLATE_ENTRY -> false
|
||||
BLOCK, LITERAL_STRING_TEMPLATE_ENTRY, KDocElementTypes.KDOC_SECTION -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.JetLanguage;
|
||||
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
|
||||
import org.jetbrains.kotlin.kdoc.parser.KDocElementTypes;
|
||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration;
|
||||
|
||||
@@ -65,6 +66,8 @@ public class JetBlock extends AbstractBlock {
|
||||
CLASS_BODY,
|
||||
FUNCTION_LITERAL);
|
||||
|
||||
private static final TokenSet KDOC_CONTENT = TokenSet.create(KDocTokens.KDOC, KDocElementTypes.KDOC_SECTION);
|
||||
|
||||
// private static final List<IndentWhitespaceRule>
|
||||
|
||||
public JetBlock(
|
||||
@@ -415,7 +418,7 @@ public class JetBlock extends AbstractBlock {
|
||||
.set(Indent.getContinuationWithoutFirstIndent(false)),
|
||||
|
||||
strategy("KDoc comment indent")
|
||||
.in(DOC_COMMENT)
|
||||
.in(KDOC_CONTENT)
|
||||
.forType(KDocTokens.LEADING_ASTERISK, KDocTokens.END)
|
||||
.set(Indent.getSpaceIndent(KDOC_COMMENT_INDENT)),
|
||||
|
||||
|
||||
@@ -2,4 +2,4 @@ fun test() {
|
||||
listOf(1, 2, 4).<caret>filter { it > 0 }
|
||||
}
|
||||
|
||||
// INFO: inline <b>public</b> <b>fun</b> <T> Iterable<T>.filter(predicate: (T) → Boolean): List<T><br/><p>Returns a list containing all elements matching the given *predicate*<br/></p>
|
||||
// INFO: inline <b>public</b> <b>fun</b> <T> Iterable<T>.filter(predicate: (T) → Boolean): List<T><br/><p>Returns a list containing all elements matching the given *predicate*</p>
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
*/
|
||||
class <caret>Some
|
||||
|
||||
// INFO: <b>internal</b> <b>final</b> <b>class</b> Some<br/><p>Usefull comment<br/></p>
|
||||
// INFO: <b>internal</b> <b>final</b> <b>class</b> Some<br/><p>Usefull comment</p>
|
||||
@@ -8,4 +8,4 @@ class Testing {
|
||||
}
|
||||
}
|
||||
|
||||
// INFO: <b>internal</b> <b>fun</b> foo(bar: Int): Unit<br/><p>KDoc foo<br/></p>
|
||||
// INFO: <b>internal</b> <b>fun</b> foo(bar: Int): Unit<br/><p>KDoc foo</p>
|
||||
Reference in New Issue
Block a user