diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex index 37211ff15b0..e7221fb980b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex @@ -5,6 +5,8 @@ import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import com.intellij.util.text.CharArrayUtil; import java.lang.Character; +import org.jetbrains.kotlin.lexer.JetTokens; +import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag; %% @@ -43,6 +45,7 @@ import java.lang.Character; %state LINE_BEGINNING %state CONTENTS_BEGINNING %state TAG_BEGINNING +%state TAG_TEXT_BEGINNING %state CONTENTS WHITE_SPACE_CHAR =[\ \t\f\n\r] @@ -52,9 +55,10 @@ DIGIT=[0-9] ALPHA=[:jletter:] TAG_NAME={ALPHA}({ALPHA}|{DIGIT})* IDENTIFIER={ALPHA}({ALPHA}|{DIGIT}|".")* -CODE_LINK_START={ALPHA} -CODE_LINK_CHAR={ALPHA}|{DIGIT}|[\.] -CODE_LINK=\[{CODE_LINK_START}{CODE_LINK_CHAR}*\] +QUALIFIED_NAME_START={ALPHA} +QUALIFIED_NAME_CHAR={ALPHA}|{DIGIT}|[\.] +QUALIFIED_NAME={QUALIFIED_NAME_START}{QUALIFIED_NAME_CHAR}* +CODE_LINK=\[{QUALIFIED_NAME}\] %% @@ -67,8 +71,11 @@ CODE_LINK=\[{CODE_LINK_START}{CODE_LINK_CHAR}*\] "*"+ { yybegin(CONTENTS_BEGINNING); return KDocTokens.LEADING_ASTERISK; } - "@"{TAG_NAME} { yybegin(TAG_BEGINNING); - return KDocTokens.TAG_NAME; } + "@"{TAG_NAME} { + KDocKnownTag tag = KDocKnownTag.findByTagName(zzBuffer.subSequence(zzStartRead, zzMarkedPos)); + yybegin(tag != null && tag.isReferenceRequired() ? TAG_BEGINNING : TAG_TEXT_BEGINNING); + return KDocTokens.TAG_NAME; +} { {WHITE_SPACE_CHAR}+ { @@ -87,9 +94,9 @@ CODE_LINK=\[{CODE_LINK_START}{CODE_LINK_CHAR}*\] /* Example: @param aaa The value of aaa ^^^ */ - {IDENTIFIER} { + {QUALIFIED_NAME} { yybegin(CONTENTS); - return KDocTokens.TEXT_OR_LINK; + return KDocTokens.MARKDOWN_LINK; } . { @@ -98,6 +105,26 @@ CODE_LINK=\[{CODE_LINK_START}{CODE_LINK_CHAR}*\] } } + { + {WHITE_SPACE_CHAR}+ { + if (yytextContainLineBreaks()) { + yybegin(LINE_BEGINNING); + } + return TokenType.WHITE_SPACE; + } + + /* Example: @return[x] The return value of function x + ^^^ + */ + {CODE_LINK} { yybegin(CONTENTS); + return KDocTokens.MARKDOWN_LINK; } + + . { + yybegin(CONTENTS); + return KDocTokens.TEXT; + } +} + { {WHITE_SPACE_CHAR}+ { if (yytextContainLineBreaks()) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDocTokens.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDocTokens.java index 49d9ba58ef2..a56759e7b92 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDocTokens.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDocTokens.java @@ -29,7 +29,6 @@ import org.jetbrains.kotlin.idea.JetLanguage; import org.jetbrains.kotlin.kdoc.parser.KDocLinkParser; import org.jetbrains.kotlin.kdoc.parser.KDocParser; import org.jetbrains.kotlin.kdoc.psi.impl.KDocImpl; -import org.jetbrains.kotlin.lexer.JetLexer; public interface KDocTokens { ILazyParseableElementType KDOC = new ILazyParseableElementType("KDoc", JetLanguage.INSTANCE) { @@ -57,28 +56,16 @@ public interface KDocTokens { KDocToken TEXT = new KDocToken("KDOC_TEXT"); - /** - * 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 (@since version). - * We understand which one it is during parsing. - */ - KDocToken TEXT_OR_LINK = new KDocToken("KDOC_TEXT_OR_LINK"); KDocToken TAG_NAME = new KDocToken("KDOC_TAG_NAME"); ILazyParseableElementType MARKDOWN_LINK = new ILazyParseableElementType("KDOC_MARKDOWN_LINK", JetLanguage.INSTANCE) { @Override public ASTNode parseContents(ASTNode chameleon) { - PsiElement parentElement = chameleon.getTreeParent().getPsi(); - Project project = parentElement.getProject(); - PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, new JetLexer(), getLanguage(), - chameleon.getText()); - PsiParser parser = new KDocLinkParser(); - - return parser.parse(this, builder).getFirstChildNode(); + return KDocLinkParser.OBJECT$.parseMarkdownLink(this, chameleon); } }; KDocToken MARKDOWN_ESCAPED_CHAR = new KDocToken("KDOC_MARKDOWN_ESCAPED_CHAR"); - TokenSet KDOC_HIGHLIGHT_TOKENS = TokenSet.create(START, END, LEADING_ASTERISK, TEXT, MARKDOWN_LINK, MARKDOWN_ESCAPED_CHAR, TEXT_OR_LINK); - TokenSet CONTENT_TOKENS = TokenSet.create(TEXT, TAG_NAME, MARKDOWN_LINK, MARKDOWN_ESCAPED_CHAR, TEXT_OR_LINK); + TokenSet KDOC_HIGHLIGHT_TOKENS = TokenSet.create(START, END, LEADING_ASTERISK, TEXT, MARKDOWN_LINK, MARKDOWN_ESCAPED_CHAR); + TokenSet CONTENT_TOKENS = TokenSet.create(TEXT, TAG_NAME, MARKDOWN_LINK, MARKDOWN_ESCAPED_CHAR); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java index 464e3218f6e..0772ff9bafa 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java @@ -1,20 +1,4 @@ -/* - * Copyright 2010-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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* The following code was generated by JFlex 1.4.3 on 2/4/15 7:15 PM */ +/* The following code was generated by JFlex 1.4.3 on 2/6/15 12:23 PM */ package org.jetbrains.kotlin.kdoc.lexer; @@ -23,12 +7,14 @@ import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import com.intellij.util.text.CharArrayUtil; import java.lang.Character; +import org.jetbrains.kotlin.lexer.JetTokens; +import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 2/4/15 7:15 PM from the specification file + * on 2/6/15 12:23 PM from the specification file * /Users/yole/jetbrains/kotlin/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex */ class _KDocLexer implements FlexLexer { @@ -38,8 +24,9 @@ class _KDocLexer implements FlexLexer { /** lexical states */ public static final int CONTENTS_BEGINNING = 4; public static final int LINE_BEGINNING = 2; - public static final int CONTENTS = 8; + public static final int CONTENTS = 10; public static final int YYINITIAL = 0; + public static final int TAG_TEXT_BEGINNING = 8; public static final int TAG_BEGINNING = 6; /** @@ -49,7 +36,7 @@ class _KDocLexer implements FlexLexer { * l is of the form l = 2*k, k a non negative integer */ private static final int ZZ_LEXSTATE[] = { - 0, 0, 1, 1, 2, 2, 3, 3, 4, 4 + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 }; /** @@ -129,12 +116,12 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\5\0\3\1\1\2\1\3\1\2\1\4\3\2\1\5"+ + "\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"; private static int [] zzUnpackAction() { - int [] result = new int[31]; + int [] result = new int[32]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -160,12 +147,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\101\0\150\0\165\0\202\0\217\0\133\0\234\0\101"+ - "\0\251\0\266\0\303\0\133\0\320\0\101\0\133\0\335"+ - "\0\101\0\352\0\367\0\101\0\u0104\0\101\0\101"; + "\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"; private static int [] zzUnpackRowMap() { - int [] result = new int[31]; + int [] result = new int[32]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -188,21 +175,22 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = - "\7\6\1\7\1\10\1\6\1\0\2\6\1\11\1\12"+ - "\3\11\1\13\2\11\1\14\1\11\1\12\1\15\2\11"+ - "\1\12\3\11\1\13\2\11\1\16\1\17\1\12\1\15"+ - "\1\11\1\20\1\21\1\20\1\22\1\20\1\23\2\20"+ - "\1\24\1\20\1\21\2\20\1\11\1\12\3\11\1\13"+ - "\2\11\1\16\1\11\1\12\1\15\1\11\25\0\1\25"+ - "\13\0\1\26\1\27\5\0\1\12\10\0\1\12\5\0"+ - "\1\30\20\0\1\26\1\14\11\0\2\31\11\0\1\32"+ - "\12\0\1\21\10\0\1\21\4\0\3\22\13\0\1\33"+ - "\21\0\1\34\6\0\3\30\1\0\1\35\10\0\2\32"+ - "\13\0\3\33\1\0\1\36\6\0\5\37\1\0\6\37"+ + "\7\7\1\10\1\11\1\7\1\0\2\7\1\12\1\13"+ + "\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\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"; private static int [] zzUnpackTrans() { - int [] result = new int[273]; + int [] result = new int[286]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -243,11 +231,11 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\5\0\1\11\2\1\1\11\6\1\1\11\4\1\1\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"; private static int [] zzUnpackAttribute() { - int [] result = new int[31]; + int [] result = new int[32]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -574,6 +562,12 @@ class _KDocLexer implements FlexLexer { zzMarkedPos = zzMarkedPosL; switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 10: + { KDocKnownTag tag = KDocKnownTag.findByTagName(zzBuffer.subSequence(zzStartRead, zzMarkedPos)); + yybegin(tag != null && tag.isReferenceRequired() ? TAG_BEGINNING : TAG_TEXT_BEGINNING); + return KDocTokens.TAG_NAME; + } + case 14: break; case 3: { if (yytextContainLineBreaks()) { yybegin(LINE_BEGINNING); @@ -583,16 +577,11 @@ class _KDocLexer implements FlexLexer { return KDocTokens.TEXT; // internal white space } } - case 14: break; + case 15: break; case 11: { yybegin(CONTENTS_BEGINNING); return KDocTokens.START; } - case 15: break; - case 7: - { yybegin(CONTENTS); - return KDocTokens.TEXT_OR_LINK; - } case 16: break; case 8: { if (isLastToken()) return KDocTokens.END; @@ -623,24 +612,24 @@ class _KDocLexer implements FlexLexer { return KDocTokens.MARKDOWN_LINK; } case 21: break; - case 10: - { yybegin(TAG_BEGINNING); - return KDocTokens.TAG_NAME; - } - case 22: break; case 1: { return TokenType.BAD_CHARACTER; } - case 23: break; + case 22: break; case 9: { yybegin(CONTENTS); return KDocTokens.MARKDOWN_ESCAPED_CHAR; } - case 24: break; + case 23: break; case 2: { yybegin(CONTENTS); return KDocTokens.TEXT; } + case 24: break; + case 7: + { yybegin(CONTENTS); + return KDocTokens.MARKDOWN_LINK; + } case 25: break; case 4: { yybegin(CONTENTS_BEGINNING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementTypes.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementTypes.java index 0faea9b570f..3d383700e95 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementTypes.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocElementTypes.java @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.kdoc.parser; -import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink; import org.jetbrains.kotlin.kdoc.psi.impl.KDocName; import org.jetbrains.kotlin.kdoc.psi.impl.KDocSection; import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag; @@ -24,6 +23,5 @@ import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag; public class KDocElementTypes { public static final KDocElementType KDOC_SECTION = new KDocElementType("KDOC_SECTION", KDocSection.class); public static final KDocElementType KDOC_TAG = new KDocElementType("KDOC_TAG", KDocTag.class); - public static final KDocElementType KDOC_LINK = new KDocElementType("KDOC_LINK", KDocLink.class); public static final KDocElementType KDOC_NAME = new KDocElementType("KDOC_NAME", KDocName.class); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocKnownTag.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocKnownTag.java index be5b5e9cd59..5437b3a912f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocKnownTag.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocKnownTag.java @@ -16,13 +16,15 @@ package org.jetbrains.kotlin.kdoc.parser; +import com.intellij.openapi.util.text.StringUtil; + public enum KDocKnownTag { AUTHOR(false, false), THROWS(true, false), EXCEPTION(true, false), PARAM(true, false), RETURN(false, false), - SEE(false, false), + SEE(true, false), SINCE(false, false), CONSTRUCTOR(false, true), PROPERTY(true, true); @@ -43,12 +45,12 @@ public enum KDocKnownTag { return startsSection; } - public static KDocKnownTag findByTagName(String tagName) { - if (tagName.startsWith("@")) { - tagName = tagName.substring(1); + public static KDocKnownTag findByTagName(CharSequence tagName) { + if (StringUtil.startsWith(tagName, "@")) { + tagName = tagName.subSequence(1, tagName.length()); } try { - return valueOf(tagName.toUpperCase()); + return valueOf(tagName.toString().toUpperCase()); } catch (IllegalArgumentException ignored) { } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocLinkParser.kt b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocLinkParser.kt index ee10333d226..241c94b6642 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocLinkParser.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocLinkParser.kt @@ -21,25 +21,53 @@ import com.intellij.psi.tree.IElementType import com.intellij.lang.PsiBuilder import com.intellij.lang.ASTNode import org.jetbrains.kotlin.lexer.JetTokens +import org.jetbrains.kotlin.lexer.JetLexer +import com.intellij.lang.PsiBuilderFactory /** * Parses the contents of a Markdown link in KDoc. Uses the standard Kotlin lexer. */ class KDocLinkParser(): PsiParser { + class object { + public fun parseMarkdownLink(root: IElementType, chameleon: ASTNode): ASTNode { + val parentElement = chameleon.getTreeParent().getPsi() + val project = parentElement.getProject() + val builder = PsiBuilderFactory.getInstance().createBuilder(project, + chameleon, + JetLexer(), + root.getLanguage(), + chameleon.getText()) + val parser = KDocLinkParser() + + return parser.parse(root, builder).getFirstChildNode() + } + } + override fun parse(root: IElementType, builder: PsiBuilder): ASTNode { val rootMarker = builder.mark() - if (builder.getTokenType() == JetTokens.LBRACKET) { + val hasLBracket = builder.getTokenType() == JetTokens.LBRACKET + if (hasLBracket) { builder.advanceLexer() } parseQualifiedName(builder) - if (!builder.eof() && builder.getTokenType() != JetTokens.RBRACKET) { - builder.error("Closing bracket expected") - while (!builder.eof() && builder.getTokenType() != JetTokens.RBRACKET) { + if (hasLBracket) { + if (!builder.eof() && builder.getTokenType() != JetTokens.RBRACKET) { + builder.error("Closing bracket expected") + while (!builder.eof() && builder.getTokenType() != JetTokens.RBRACKET) { + builder.advanceLexer() + } + } + if (builder.getTokenType() == JetTokens.RBRACKET) { builder.advanceLexer() } } - if (builder.getTokenType() == JetTokens.RBRACKET) { - builder.advanceLexer() + else { + if (!builder.eof()) { + builder.error("Expression expected"); + while (!builder.eof()) { + builder.advanceLexer(); + } + } } rootMarker.done(root) return builder.getTreeBuilt() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocParser.java b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocParser.java index 4a347858a4e..50935459fed 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocParser.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/parser/KDocParser.java @@ -38,11 +38,6 @@ public class KDocParser implements PsiParser { if (builder.getTokenType() == KDocTokens.TAG_NAME) { currentSectionMarker = parseTag(builder, currentSectionMarker); } - else if (builder.getTokenType() == KDocTokens.MARKDOWN_LINK) { - PsiBuilder.Marker linkStart = builder.mark(); - builder.advanceLexer(); - linkStart.done(KDocElementTypes.KDOC_LINK); - } else if (builder.getTokenType() == KDocTokens.END) { if (currentSectionMarker != null) { currentSectionMarker.done(KDocElementTypes.KDOC_SECTION); @@ -72,23 +67,8 @@ public class KDocParser implements PsiParser { PsiBuilder.Marker tagStart = builder.mark(); builder.advanceLexer(); - if (knownTag != null && knownTag.isReferenceRequired() && builder.getTokenType() == KDocTokens.TEXT_OR_LINK) { - PsiBuilder.Marker referenceMarker = builder.mark(); - PsiBuilder.Marker nameMarker = builder.mark(); - builder.advanceLexer(); - nameMarker.done(KDocElementTypes.KDOC_NAME); - referenceMarker.done(KDocElementTypes.KDOC_LINK); - } - while (!builder.eof() && !isAtEndOfTag(builder)) { - if (builder.getTokenType() == KDocTokens.MARKDOWN_LINK) { - PsiBuilder.Marker linkStart = builder.mark(); - builder.advanceLexer(); - linkStart.done(KDocElementTypes.KDOC_LINK); - } - else { - builder.advanceLexer(); - } + builder.advanceLexer(); } tagStart.done(KDocElementTypes.KDOC_TAG); return currentSectionMarker; diff --git a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocTag.kt b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocTag.kt index 5d3b897f9b5..9f1417c6d62 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocTag.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/psi/impl/KDocTag.kt @@ -62,7 +62,7 @@ public open class KDocTag(node: ASTNode) : KDocElementImpl(node) { private fun hasSubject(contentChildren: List): Boolean { if (knownTag?.isReferenceRequired() ?: false) { - return contentChildren.firstOrNull()?.getElementType() == KDocElementTypes.KDOC_LINK; + return contentChildren.firstOrNull()?.getElementType() == KDocTokens.MARKDOWN_LINK } return false } @@ -88,7 +88,7 @@ public open class KDocTag(node: ASTNode) : KDocElementImpl(node) { } for (node in children) { val type = node.getElementType() - if (KDocTokens.CONTENT_TOKENS.contains(type) || type == KDocElementTypes.KDOC_LINK) { + if (KDocTokens.CONTENT_TOKENS.contains(type)) { contentStarted = true builder.append(if (afterAsterisk) StringUtil.trimLeading(node.getText()) else node.getText()) afterAsterisk = false diff --git a/compiler/testData/psi/kdoc/Markdown.txt b/compiler/testData/psi/kdoc/Markdown.txt index 19db5898e7a..30d0ee62080 100644 --- a/compiler/testData/psi/kdoc/Markdown.txt +++ b/compiler/testData/psi/kdoc/Markdown.txt @@ -7,12 +7,11 @@ JetFile: Markdown.kt KDOC_SECTION PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') - KDOC_LINK - KDOC_MARKDOWN_LINK - PsiElement(LBRACKET)('[') - KDOC_NAME - PsiElement(IDENTIFIER)('WikiLink') - PsiElement(RBRACKET)(']') + KDOC_MARKDOWN_LINK + PsiElement(LBRACKET)('[') + KDOC_NAME + PsiElement(IDENTIFIER)('WikiLink') + PsiElement(RBRACKET)(']') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') @@ -21,12 +20,11 @@ JetFile: Markdown.kt PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' [') - KDOC_LINK - KDOC_MARKDOWN_LINK - PsiElement(LBRACKET)('[') - KDOC_NAME - PsiElement(IDENTIFIER)('DoubleQuotedLink') - PsiElement(RBRACKET)(']') + KDOC_MARKDOWN_LINK + PsiElement(LBRACKET)('[') + KDOC_NAME + PsiElement(IDENTIFIER)('DoubleQuotedLink') + PsiElement(RBRACKET)(']') PsiElement(KDOC_TEXT)(']') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') diff --git a/compiler/testData/psi/kdoc/MarkdownLinkWithError.txt b/compiler/testData/psi/kdoc/MarkdownLinkWithError.txt index d4814179f69..22ef7b9683f 100644 --- a/compiler/testData/psi/kdoc/MarkdownLinkWithError.txt +++ b/compiler/testData/psi/kdoc/MarkdownLinkWithError.txt @@ -7,51 +7,48 @@ JetFile: MarkdownLinkWithError.kt KDOC_SECTION PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') - KDOC_LINK - KDOC_MARKDOWN_LINK - PsiElement(LBRACKET)('[') + KDOC_MARKDOWN_LINK + PsiElement(LBRACKET)('[') + KDOC_NAME KDOC_NAME KDOC_NAME - KDOC_NAME - PsiElement(IDENTIFIER)('A') - PsiElement(DOT)('.') - PsiElement(IDENTIFIER)('B') + PsiElement(IDENTIFIER)('A') PsiElement(DOT)('.') - PsiElement(IDENTIFIER)('C') - PsiErrorElement:Closing bracket expected - - PsiElement(RANGE)('..') + PsiElement(IDENTIFIER)('B') PsiElement(DOT)('.') - PsiElement(RBRACKET)(']') + PsiElement(IDENTIFIER)('C') + PsiErrorElement:Closing bracket expected + + PsiElement(RANGE)('..') + PsiElement(DOT)('.') + PsiElement(RBRACKET)(']') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' [....]') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') - KDOC_LINK - KDOC_MARKDOWN_LINK - PsiElement(LBRACKET)('[') - KDOC_NAME - PsiElement(IDENTIFIER)('A') - PsiErrorElement:Closing bracket expected - - PsiElement(RANGE)('..') - PsiElement(IDENTIFIER)('B') - PsiElement(RANGE)('..') - PsiElement(IDENTIFIER)('C') - PsiElement(RBRACKET)(']') + KDOC_MARKDOWN_LINK + PsiElement(LBRACKET)('[') + KDOC_NAME + PsiElement(IDENTIFIER)('A') + PsiErrorElement:Closing bracket expected + + PsiElement(RANGE)('..') + PsiElement(IDENTIFIER)('B') + PsiElement(RANGE)('..') + PsiElement(IDENTIFIER)('C') + PsiElement(RBRACKET)(']') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') - KDOC_LINK - KDOC_MARKDOWN_LINK - PsiElement(LBRACKET)('[') - KDOC_NAME - PsiElement(IDENTIFIER)('A') - PsiElement(DOT)('.') - PsiErrorElement:Identifier expected - - PsiElement(RBRACKET)(']') + KDOC_MARKDOWN_LINK + PsiElement(LBRACKET)('[') + KDOC_NAME + PsiElement(IDENTIFIER)('A') + PsiElement(DOT)('.') + PsiErrorElement:Identifier expected + + PsiElement(RBRACKET)(']') PsiWhiteSpace('\n ') PsiElement(KDOC_END)('*/') \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/MarkdownQualifiedName.txt b/compiler/testData/psi/kdoc/MarkdownQualifiedName.txt index 058ba87e026..0e94c32193c 100644 --- a/compiler/testData/psi/kdoc/MarkdownQualifiedName.txt +++ b/compiler/testData/psi/kdoc/MarkdownQualifiedName.txt @@ -7,42 +7,39 @@ JetFile: MarkdownQualifiedName.kt KDOC_SECTION PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') - KDOC_LINK - KDOC_MARKDOWN_LINK - PsiElement(LBRACKET)('[') + KDOC_MARKDOWN_LINK + PsiElement(LBRACKET)('[') + KDOC_NAME KDOC_NAME KDOC_NAME - KDOC_NAME - PsiElement(IDENTIFIER)('A') - PsiElement(DOT)('.') - PsiElement(IDENTIFIER)('B') + PsiElement(IDENTIFIER)('A') PsiElement(DOT)('.') - PsiElement(IDENTIFIER)('C') - PsiElement(RBRACKET)(']') + PsiElement(IDENTIFIER)('B') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('C') + PsiElement(RBRACKET)(']') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' [') - KDOC_LINK - KDOC_MARKDOWN_LINK - PsiElement(LBRACKET)('[') + KDOC_MARKDOWN_LINK + PsiElement(LBRACKET)('[') + KDOC_NAME KDOC_NAME - KDOC_NAME - PsiElement(IDENTIFIER)('System') - PsiElement(DOT)('.') - PsiElement(IDENTIFIER)('out') - PsiElement(RBRACKET)(']') + PsiElement(IDENTIFIER)('System') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('out') + PsiElement(RBRACKET)(']') PsiElement(KDOC_TEXT)(']') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') - KDOC_LINK - KDOC_MARKDOWN_LINK - PsiElement(LBRACKET)('[') + KDOC_MARKDOWN_LINK + PsiElement(LBRACKET)('[') + KDOC_NAME KDOC_NAME - KDOC_NAME - PsiElement(IDENTIFIER)('System') - PsiElement(DOT)('.') - PsiElement(in)('in') - PsiElement(RBRACKET)(']') + PsiElement(IDENTIFIER)('System') + PsiElement(DOT)('.') + PsiElement(in)('in') + PsiElement(RBRACKET)(']') PsiWhiteSpace('\n ') PsiElement(KDOC_END)('*/') \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/ParamTag.txt b/compiler/testData/psi/kdoc/ParamTag.txt index ba38939f4a3..5b727c6b959 100644 --- a/compiler/testData/psi/kdoc/ParamTag.txt +++ b/compiler/testData/psi/kdoc/ParamTag.txt @@ -10,9 +10,9 @@ JetFile: ParamTag.kt KDOC_TAG PsiElement(KDOC_TAG_NAME)('@param') PsiWhiteSpace(' ') - KDOC_LINK + KDOC_MARKDOWN_LINK KDOC_NAME - PsiElement(KDOC_TEXT_OR_LINK)('a') + PsiElement(IDENTIFIER)('a') PsiElement(KDOC_TEXT)(' The description of a.') PsiWhiteSpace('\n ') PsiElement(KDOC_END)('*/') \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/ParamTagAtStart.txt b/compiler/testData/psi/kdoc/ParamTagAtStart.txt index 7ef28c97ccb..21feff72191 100644 --- a/compiler/testData/psi/kdoc/ParamTagAtStart.txt +++ b/compiler/testData/psi/kdoc/ParamTagAtStart.txt @@ -8,8 +8,8 @@ JetFile: ParamTagAtStart.kt KDOC_TAG PsiElement(KDOC_TAG_NAME)('@param') PsiWhiteSpace(' ') - KDOC_LINK + KDOC_MARKDOWN_LINK KDOC_NAME - PsiElement(KDOC_TEXT_OR_LINK)('a') + PsiElement(IDENTIFIER)('a') PsiElement(KDOC_TEXT)(' this is a ') PsiElement(KDOC_END)('*/') \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/ReturnWithBrackets.txt b/compiler/testData/psi/kdoc/ReturnWithBrackets.txt index 88a29c7d6d6..273dbcb3aad 100644 --- a/compiler/testData/psi/kdoc/ReturnWithBrackets.txt +++ b/compiler/testData/psi/kdoc/ReturnWithBrackets.txt @@ -10,19 +10,17 @@ JetFile: ReturnWithBrackets.kt KDOC_TAG PsiElement(KDOC_TAG_NAME)('@return') PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT_OR_LINK)('This') - PsiElement(KDOC_TEXT)(' is not a reference') + PsiElement(KDOC_TEXT)('This is not a reference') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') KDOC_TAG PsiElement(KDOC_TAG_NAME)('@return') - KDOC_LINK - KDOC_MARKDOWN_LINK - PsiElement(LBRACKET)('[') - KDOC_NAME - PsiElement(IDENTIFIER)('x') - PsiElement(RBRACKET)(']') + KDOC_MARKDOWN_LINK + PsiElement(LBRACKET)('[') + KDOC_NAME + PsiElement(IDENTIFIER)('x') + PsiElement(RBRACKET)(']') PsiElement(KDOC_TEXT)(' This is a reference') PsiWhiteSpace('\n ') PsiElement(KDOC_END)('*/') \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/Sections.txt b/compiler/testData/psi/kdoc/Sections.txt index fea98521a10..e9412e72e33 100644 --- a/compiler/testData/psi/kdoc/Sections.txt +++ b/compiler/testData/psi/kdoc/Sections.txt @@ -13,9 +13,9 @@ JetFile: Sections.kt KDOC_TAG PsiElement(KDOC_TAG_NAME)('@param') PsiWhiteSpace(' ') - KDOC_LINK + KDOC_MARKDOWN_LINK KDOC_NAME - PsiElement(KDOC_TEXT_OR_LINK)('T') + PsiElement(IDENTIFIER)('T') PsiElement(KDOC_TEXT)(' a type parameter.') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') @@ -24,17 +24,16 @@ JetFile: Sections.kt KDOC_TAG PsiElement(KDOC_TAG_NAME)('@constructor') PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT_OR_LINK)('This') - PsiElement(KDOC_TEXT)(' is the doc comment for the primary constructor.') + PsiElement(KDOC_TEXT)('This is the doc comment for the primary constructor.') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') KDOC_TAG PsiElement(KDOC_TAG_NAME)('@param') PsiWhiteSpace(' ') - KDOC_LINK + KDOC_MARKDOWN_LINK KDOC_NAME - PsiElement(KDOC_TEXT_OR_LINK)('a') + PsiElement(IDENTIFIER)('a') PsiElement(KDOC_TEXT)(' a constructor parameter.') PsiWhiteSpace('\n ') PsiElement(KDOC_END)('*/') \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/SeeLink.kt b/compiler/testData/psi/kdoc/SeeLink.kt new file mode 100644 index 00000000000..e29c94b373d --- /dev/null +++ b/compiler/testData/psi/kdoc/SeeLink.kt @@ -0,0 +1,3 @@ +/** + * @see Foo.bar + */ diff --git a/compiler/testData/psi/kdoc/SeeLink.txt b/compiler/testData/psi/kdoc/SeeLink.txt new file mode 100644 index 00000000000..41acd0a7c4e --- /dev/null +++ b/compiler/testData/psi/kdoc/SeeLink.txt @@ -0,0 +1,20 @@ +JetFile: SeeLink.kt + PACKAGE_DIRECTIVE + + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n ') + KDOC_SECTION + PsiElement(KDOC_LEADING_ASTERISK)('*') + PsiElement(KDOC_TEXT)(' ') + KDOC_TAG + PsiElement(KDOC_TAG_NAME)('@see') + PsiWhiteSpace(' ') + KDOC_MARKDOWN_LINK + KDOC_NAME + KDOC_NAME + PsiElement(IDENTIFIER)('Foo') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('bar') + PsiWhiteSpace('\n ') + PsiElement(KDOC_END)('*/') \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/TwoTags.txt b/compiler/testData/psi/kdoc/TwoTags.txt index 22a99dfe0b2..bb2360173e3 100644 --- a/compiler/testData/psi/kdoc/TwoTags.txt +++ b/compiler/testData/psi/kdoc/TwoTags.txt @@ -10,14 +10,13 @@ JetFile: TwoTags.kt KDOC_TAG PsiElement(KDOC_TAG_NAME)('@author') PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT_OR_LINK)('Dmitry') - PsiElement(KDOC_TEXT)(' Jemerov') + PsiElement(KDOC_TEXT)('Dmitry Jemerov') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('*') PsiElement(KDOC_TEXT)(' ') KDOC_TAG PsiElement(KDOC_TAG_NAME)('@since') PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT_OR_LINK)('M12') + PsiElement(KDOC_TEXT)('M12') PsiWhiteSpace('\n ') PsiElement(KDOC_END)('*/') \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java index d0c11650a35..899ea48d46b 100644 --- a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java @@ -1127,6 +1127,12 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest { doParsingTest(fileName); } + @TestMetadata("SeeLink.kt") + public void testSeeLink() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/kdoc/SeeLink.kt"); + doParsingTest(fileName); + } + @TestMetadata("Simple.kt") public void testSimple() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/kdoc/Simple.kt"); diff --git a/idea/testData/kdoc/resolve/SeeReference.kt b/idea/testData/kdoc/resolve/SeeReference.kt new file mode 100644 index 00000000000..d498b985be6 --- /dev/null +++ b/idea/testData/kdoc/resolve/SeeReference.kt @@ -0,0 +1,12 @@ +/** + * @see Foo.bar + */ +fun xyzzy() { +} + +class Foo { + fun bar() { + } +} + +// REF: (in Foo).bar() diff --git a/idea/tests/org/jetbrains/kotlin/idea/kdoc/KdocResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/kdoc/KdocResolveTestGenerated.java index 4b2a4043a42..ac03df9ede2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/kdoc/KdocResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/kdoc/KdocResolveTestGenerated.java @@ -17,10 +17,9 @@ package org.jetbrains.kotlin.idea.kdoc; import com.intellij.testFramework.TestDataPath; -import org.jetbrains.kotlin.test.InnerTestClasses; +import org.jetbrains.kotlin.idea.resolve.AbstractReferenceResolveTest; import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; import org.jetbrains.kotlin.test.JetTestUtils; -import org.jetbrains.kotlin.idea.resolve.AbstractReferenceResolveTest; import org.jetbrains.kotlin.test.TestMetadata; import org.junit.runner.RunWith; @@ -79,6 +78,12 @@ public class KdocResolveTestGenerated extends AbstractReferenceResolveTest { doTest(fileName); } + @TestMetadata("SeeReference.kt") + public void testSeeReference() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/resolve/SeeReference.kt"); + doTest(fileName); + } + @TestMetadata("TypeParamReference.kt") public void testTypeParamReference() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/kdoc/resolve/TypeParamReference.kt");