some initial PSI for KDoc; changed syntax of links (Markdown style single brackets instead of Wiki style double brackets)

This commit is contained in:
Dmitry Jemerov
2015-01-19 20:54:05 +01:00
parent b40e657180
commit f3763bc2b5
21 changed files with 519 additions and 141 deletions
@@ -42,9 +42,8 @@ import java.lang.Character;
%state LINE_BEGINNING
%state CONTENTS_BEGINNING
%state TAG_BEGINNING
%state CONTENTS
%state CODE
%state CODE2
WHITE_SPACE_CHAR =[\ \t\f\n\r]
NOT_WHITE_SPACE_CHAR=[^\ \t\f\n\r]
@@ -52,8 +51,10 @@ NOT_WHITE_SPACE_CHAR=[^\ \t\f\n\r]
DIGIT=[0-9]
ALPHA=[:jletter:]
TAG_NAME={ALPHA}({ALPHA}|{DIGIT})*
MARKDOWN_EMPHASIS=[\*_]
IDENTIFIER={ALPHA}({ALPHA}|{DIGIT}|".")*
CODE_LINK_START={ALPHA}
CODE_LINK_CHAR={ALPHA}|{DIGIT}|[()\-\.<>]
CODE_LINK=\[{CODE_LINK_START}{CODE_LINK_CHAR}*\]
%%
@@ -66,9 +67,37 @@ MARKDOWN_EMPHASIS=[\*_]
<LINE_BEGINNING> "*"+ { yybegin(CONTENTS_BEGINNING);
return KDocTokens.LEADING_ASTERISK; }
<CONTENTS_BEGINNING> "@"{TAG_NAME} { yybegin(CONTENTS);
<CONTENTS_BEGINNING> "@"{TAG_NAME} { yybegin(TAG_BEGINNING);
return KDocTokens.TAG_NAME; }
<TAG_BEGINNING> {
{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; }
/* Example: @param aaa The value of aaa
^^^
*/
{IDENTIFIER} {
yybegin(CONTENTS);
return KDocTokens.TEXT_OR_LINK;
}
. {
yybegin(CONTENTS);
return KDocTokens.TEXT;
}
}
<LINE_BEGINNING, CONTENTS_BEGINNING, CONTENTS> {
{WHITE_SPACE_CHAR}+ {
if (yytextContainLineBreaks()) {
@@ -83,10 +112,11 @@ MARKDOWN_EMPHASIS=[\*_]
"\\"[\[\]] { yybegin(CONTENTS);
return KDocTokens.MARKDOWN_ESCAPED_CHAR; }
"[[" { yybegin(CONTENTS);
return KDocTokens.WIKI_LINK_OPEN; }
"]]" { yybegin(CONTENTS);
return KDocTokens.WIKI_LINK_CLOSE; }
/* We're only interested in parsing links that can become code references,
meaning they contain only identifier characters and characters that can be
used in type declarations. No brackets, backticks, asterisks or anything like that. */
{CODE_LINK} { yybegin(CONTENTS);
return KDocTokens.MARKDOWN_LINK; }
. { yybegin(CONTENTS);
return KDocTokens.TEXT; }
@@ -54,12 +54,18 @@ public interface KDocTokens {
KDocToken LEADING_ASTERISK = new KDocToken("KDOC_LEADING_ASTERISK");
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 (@author name).
* 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");
KDocToken WIKI_LINK_OPEN = new KDocToken("KDOC_WIKI_LINK_OPEN");
KDocToken WIKI_LINK_CLOSE = new KDocToken("KDOC_WIKI_LINK_CLOSE");
KDocToken MARKDOWN_LINK = new KDocToken("KDOC_MARKDOWN_LINK");
KDocToken MARKDOWN_ESCAPED_CHAR = new KDocToken("KDOC_MARKDOWN_ESCAPED_CHAR");
KDocToken MARKDOWN_ESCAPED_CHAR = new KDocToken("KDOC_MARKDOWN_ESCAPED_CHAR");
TokenSet KDOC_HIGHLIGHT_TOKENS = TokenSet.create(START, END, LEADING_ASTERISK, TEXT, WIKI_LINK_OPEN, WIKI_LINK_CLOSE, MARKDOWN_ESCAPED_CHAR);
TokenSet CONTENT_TOKENS = TokenSet.create(TEXT, TAG_NAME, WIKI_LINK_OPEN, WIKI_LINK_CLOSE, MARKDOWN_ESCAPED_CHAR);
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);
}
@@ -14,7 +14,7 @@
* limitations under the License.
*/
/* The following code was generated by JFlex 1.4.3 on 1/10/15 1:43 PM */
/* The following code was generated by JFlex 1.4.3 on 1/19/15 8:28 PM */
package org.jetbrains.kotlin.kdoc.lexer;
@@ -28,20 +28,19 @@ import java.lang.Character;
/**
* This class is a scanner generated by
* <a href="http://www.jflex.de/">JFlex</a> 1.4.3
* on 1/10/15 1:43 PM from the specification file
* <tt>/Users/udalov/kotlin/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex</tt>
* on 1/19/15 8:28 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 {
/** initial size of the lookahead buffer */
private static final int ZZ_BUFFERSIZE = 16384;
/** lexical states */
public static final int CODE = 8;
public static final int CONTENTS_BEGINNING = 4;
public static final int CODE2 = 10;
public static final int LINE_BEGINNING = 2;
public static final int CONTENTS = 6;
public static final int CONTENTS = 8;
public static final int YYINITIAL = 0;
public static final int TAG_BEGINNING = 6;
/**
* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
@@ -50,74 +49,74 @@ 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, 4, 4
0, 0, 1, 1, 2, 2, 3, 3, 4, 4
};
/**
* Translates characters to character classes
*/
private static final String ZZ_CMAP_PACKED =
"\11\0\1\1\1\12\1\0\2\1\22\0\1\1\3\0\1\3\5\0"+
"\1\4\4\0\1\5\12\2\6\0\1\6\32\3\1\11\1\7\1\10"+
"\1\0\1\3\1\0\32\3\47\0\4\3\4\0\1\3\12\0\1\3"+
"\4\0\1\3\5\0\27\3\1\0\37\3\1\0\u013f\3\31\0\162\3"+
"\4\0\14\3\16\0\5\3\11\0\1\3\213\0\1\3\13\0\1\3"+
"\1\0\3\3\1\0\1\3\1\0\24\3\1\0\54\3\1\0\46\3"+
"\1\0\5\3\4\0\202\3\10\0\105\3\1\0\46\3\2\0\2\3"+
"\6\0\20\3\41\0\46\3\2\0\1\3\7\0\47\3\110\0\33\3"+
"\5\0\3\3\56\0\32\3\5\0\13\3\43\0\2\3\1\0\143\3"+
"\1\0\1\3\17\0\2\3\7\0\2\3\12\0\3\3\2\0\1\3"+
"\20\0\1\3\1\0\36\3\35\0\3\3\60\0\46\3\13\0\1\3"+
"\u0152\0\66\3\3\0\1\3\22\0\1\3\7\0\12\3\43\0\10\3"+
"\2\0\2\3\2\0\26\3\1\0\7\3\1\0\1\3\3\0\4\3"+
"\3\0\1\3\36\0\2\3\1\0\3\3\16\0\4\3\21\0\6\3"+
"\4\0\2\3\2\0\26\3\1\0\7\3\1\0\2\3\1\0\2\3"+
"\1\0\2\3\37\0\4\3\1\0\1\3\23\0\3\3\20\0\11\3"+
"\1\0\3\3\1\0\26\3\1\0\7\3\1\0\2\3\1\0\5\3"+
"\3\0\1\3\22\0\1\3\17\0\2\3\17\0\1\3\23\0\10\3"+
"\2\0\2\3\2\0\26\3\1\0\7\3\1\0\2\3\1\0\5\3"+
"\3\0\1\3\36\0\2\3\1\0\3\3\17\0\1\3\21\0\1\3"+
"\1\0\6\3\3\0\3\3\1\0\4\3\3\0\2\3\1\0\1\3"+
"\1\0\2\3\3\0\2\3\3\0\3\3\3\0\10\3\1\0\3\3"+
"\77\0\1\3\13\0\10\3\1\0\3\3\1\0\27\3\1\0\12\3"+
"\1\0\5\3\46\0\2\3\43\0\10\3\1\0\3\3\1\0\27\3"+
"\1\0\12\3\1\0\5\3\3\0\1\3\40\0\1\3\1\0\2\3"+
"\43\0\10\3\1\0\3\3\1\0\27\3\1\0\20\3\46\0\2\3"+
"\43\0\22\3\3\0\30\3\1\0\11\3\1\0\1\3\2\0\7\3"+
"\72\0\60\3\1\0\2\3\13\0\10\3\72\0\2\3\1\0\1\3"+
"\2\0\2\3\1\0\1\3\2\0\1\3\6\0\4\3\1\0\7\3"+
"\1\0\3\3\1\0\1\3\1\0\1\3\2\0\2\3\1\0\4\3"+
"\1\0\2\3\11\0\1\3\2\0\5\3\1\0\1\3\25\0\2\3"+
"\42\0\1\3\77\0\10\3\1\0\42\3\35\0\4\3\164\0\42\3"+
"\1\0\5\3\1\0\2\3\45\0\6\3\112\0\46\3\12\0\51\3"+
"\7\0\132\3\5\0\104\3\5\0\122\3\6\0\7\3\1\0\77\3"+
"\1\0\1\3\1\0\4\3\2\0\7\3\1\0\1\3\1\0\4\3"+
"\2\0\47\3\1\0\1\3\1\0\4\3\2\0\37\3\1\0\1\3"+
"\1\0\4\3\2\0\7\3\1\0\1\3\1\0\4\3\2\0\7\3"+
"\1\0\7\3\1\0\27\3\1\0\37\3\1\0\1\3\1\0\4\3"+
"\2\0\7\3\1\0\47\3\1\0\23\3\105\0\125\3\14\0\u026c\3"+
"\2\0\10\3\12\0\32\3\5\0\113\3\3\0\3\3\17\0\15\3"+
"\1\0\4\3\16\0\22\3\16\0\22\3\16\0\15\3\1\0\3\3"+
"\17\0\64\3\43\0\1\3\3\0\2\3\103\0\130\3\10\0\51\3"+
"\127\0\35\3\63\0\36\3\2\0\5\3\u038b\0\154\3\224\0\234\3"+
"\4\0\132\3\6\0\26\3\2\0\6\3\2\0\46\3\2\0\6\3"+
"\2\0\10\3\1\0\1\3\1\0\1\3\1\0\1\3\1\0\37\3"+
"\2\0\65\3\1\0\7\3\1\0\1\3\3\0\3\3\1\0\7\3"+
"\3\0\4\3\2\0\6\3\4\0\15\3\5\0\3\3\1\0\7\3"+
"\102\0\2\3\23\0\1\3\34\0\1\3\15\0\1\3\40\0\22\3"+
"\120\0\1\3\4\0\1\3\2\0\12\3\1\0\1\3\3\0\5\3"+
"\6\0\1\3\1\0\1\3\1\0\1\3\1\0\4\3\1\0\3\3"+
"\1\0\7\3\3\0\3\3\5\0\5\3\26\0\44\3\u0e81\0\3\3"+
"\31\0\11\3\7\0\5\3\2\0\5\3\4\0\126\3\6\0\3\3"+
"\1\0\137\3\5\0\50\3\4\0\136\3\21\0\30\3\70\0\20\3"+
"\u0200\0\u19b6\3\112\0\u51a6\3\132\0\u048d\3\u0773\0\u2ba4\3\u215c\0\u012e\3"+
"\2\0\73\3\225\0\7\3\14\0\5\3\5\0\1\3\1\0\12\3"+
"\1\0\15\3\1\0\5\3\1\0\1\3\1\0\2\3\1\0\2\3"+
"\1\0\154\3\41\0\u016b\3\22\0\100\3\2\0\66\3\50\0\15\3"+
"\66\0\2\3\30\0\3\3\31\0\1\3\6\0\5\3\1\0\207\3"+
"\7\0\1\3\34\0\32\3\4\0\1\3\1\0\32\3\12\0\132\3"+
"\3\0\6\3\2\0\6\3\2\0\6\3\2\0\3\3\3\0\2\3"+
"\3\0\2\3\31\0";
"\11\0\1\1\1\13\1\0\2\1\22\0\1\1\3\0\1\3\3\0"+
"\2\5\1\11\2\0\1\5\1\4\1\10\12\2\2\0\1\5\1\0"+
"\1\5\1\0\1\12\32\3\1\6\1\14\1\7\1\0\1\3\1\0"+
"\32\3\47\0\4\3\4\0\1\3\12\0\1\3\4\0\1\3\5\0"+
"\27\3\1\0\37\3\1\0\u013f\3\31\0\162\3\4\0\14\3\16\0"+
"\5\3\11\0\1\3\213\0\1\3\13\0\1\3\1\0\3\3\1\0"+
"\1\3\1\0\24\3\1\0\54\3\1\0\46\3\1\0\5\3\4\0"+
"\202\3\10\0\105\3\1\0\46\3\2\0\2\3\6\0\20\3\41\0"+
"\46\3\2\0\1\3\7\0\47\3\110\0\33\3\5\0\3\3\56\0"+
"\32\3\5\0\13\3\43\0\2\3\1\0\143\3\1\0\1\3\17\0"+
"\2\3\7\0\2\3\12\0\3\3\2\0\1\3\20\0\1\3\1\0"+
"\36\3\35\0\3\3\60\0\46\3\13\0\1\3\u0152\0\66\3\3\0"+
"\1\3\22\0\1\3\7\0\12\3\43\0\10\3\2\0\2\3\2\0"+
"\26\3\1\0\7\3\1\0\1\3\3\0\4\3\3\0\1\3\36\0"+
"\2\3\1\0\3\3\16\0\4\3\21\0\6\3\4\0\2\3\2\0"+
"\26\3\1\0\7\3\1\0\2\3\1\0\2\3\1\0\2\3\37\0"+
"\4\3\1\0\1\3\23\0\3\3\20\0\11\3\1\0\3\3\1\0"+
"\26\3\1\0\7\3\1\0\2\3\1\0\5\3\3\0\1\3\22\0"+
"\1\3\17\0\2\3\17\0\1\3\23\0\10\3\2\0\2\3\2\0"+
"\26\3\1\0\7\3\1\0\2\3\1\0\5\3\3\0\1\3\36\0"+
"\2\3\1\0\3\3\17\0\1\3\21\0\1\3\1\0\6\3\3\0"+
"\3\3\1\0\4\3\3\0\2\3\1\0\1\3\1\0\2\3\3\0"+
"\2\3\3\0\3\3\3\0\10\3\1\0\3\3\77\0\1\3\13\0"+
"\10\3\1\0\3\3\1\0\27\3\1\0\12\3\1\0\5\3\46\0"+
"\2\3\43\0\10\3\1\0\3\3\1\0\27\3\1\0\12\3\1\0"+
"\5\3\3\0\1\3\40\0\1\3\1\0\2\3\43\0\10\3\1\0"+
"\3\3\1\0\27\3\1\0\20\3\46\0\2\3\43\0\22\3\3\0"+
"\30\3\1\0\11\3\1\0\1\3\2\0\7\3\72\0\60\3\1\0"+
"\2\3\13\0\10\3\72\0\2\3\1\0\1\3\2\0\2\3\1\0"+
"\1\3\2\0\1\3\6\0\4\3\1\0\7\3\1\0\3\3\1\0"+
"\1\3\1\0\1\3\2\0\2\3\1\0\4\3\1\0\2\3\11\0"+
"\1\3\2\0\5\3\1\0\1\3\25\0\2\3\42\0\1\3\77\0"+
"\10\3\1\0\42\3\35\0\4\3\164\0\42\3\1\0\5\3\1\0"+
"\2\3\45\0\6\3\112\0\46\3\12\0\51\3\7\0\132\3\5\0"+
"\104\3\5\0\122\3\6\0\7\3\1\0\77\3\1\0\1\3\1\0"+
"\4\3\2\0\7\3\1\0\1\3\1\0\4\3\2\0\47\3\1\0"+
"\1\3\1\0\4\3\2\0\37\3\1\0\1\3\1\0\4\3\2\0"+
"\7\3\1\0\1\3\1\0\4\3\2\0\7\3\1\0\7\3\1\0"+
"\27\3\1\0\37\3\1\0\1\3\1\0\4\3\2\0\7\3\1\0"+
"\47\3\1\0\23\3\105\0\125\3\14\0\u026c\3\2\0\10\3\12\0"+
"\32\3\5\0\113\3\3\0\3\3\17\0\15\3\1\0\4\3\16\0"+
"\22\3\16\0\22\3\16\0\15\3\1\0\3\3\17\0\64\3\43\0"+
"\1\3\3\0\2\3\103\0\130\3\10\0\51\3\127\0\35\3\63\0"+
"\36\3\2\0\5\3\u038b\0\154\3\224\0\234\3\4\0\132\3\6\0"+
"\26\3\2\0\6\3\2\0\46\3\2\0\6\3\2\0\10\3\1\0"+
"\1\3\1\0\1\3\1\0\1\3\1\0\37\3\2\0\65\3\1\0"+
"\7\3\1\0\1\3\3\0\3\3\1\0\7\3\3\0\4\3\2\0"+
"\6\3\4\0\15\3\5\0\3\3\1\0\7\3\102\0\2\3\23\0"+
"\1\3\34\0\1\3\15\0\1\3\40\0\22\3\120\0\1\3\4\0"+
"\1\3\2\0\12\3\1\0\1\3\3\0\5\3\6\0\1\3\1\0"+
"\1\3\1\0\1\3\1\0\4\3\1\0\3\3\1\0\7\3\3\0"+
"\3\3\5\0\5\3\26\0\44\3\u0e81\0\3\3\31\0\11\3\7\0"+
"\5\3\2\0\5\3\4\0\126\3\6\0\3\3\1\0\137\3\5\0"+
"\50\3\4\0\136\3\21\0\30\3\70\0\20\3\u0200\0\u19b6\3\112\0"+
"\u51a6\3\132\0\u048d\3\u0773\0\u2ba4\3\u215c\0\u012e\3\2\0\73\3\225\0"+
"\7\3\14\0\5\3\5\0\1\3\1\0\12\3\1\0\15\3\1\0"+
"\5\3\1\0\1\3\1\0\2\3\1\0\2\3\1\0\154\3\41\0"+
"\u016b\3\22\0\100\3\2\0\66\3\50\0\15\3\66\0\2\3\30\0"+
"\3\3\31\0\1\3\6\0\5\3\1\0\207\3\7\0\1\3\34\0"+
"\32\3\4\0\1\3\1\0\32\3\12\0\132\3\3\0\6\3\2\0"+
"\6\3\2\0\6\3\2\0\3\3\3\0\2\3\3\0\2\3\31\0";
/**
* Translates characters to character classes
@@ -130,11 +129,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\4\5\2\1\0\1\5"+
"\1\0\1\6\1\7\1\10\1\11\1\12";
"\5\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\13\1\14";
private static int [] zzUnpackAction() {
int [] result = new int[24];
int [] result = new int[28];
int offset = 0;
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
return result;
@@ -159,12 +159,13 @@ class _KDocLexer implements FlexLexer {
private static final int [] ZZ_ROWMAP = zzUnpackRowMap();
private static final String ZZ_ROWMAP_PACKED_0 =
"\0\0\0\13\0\26\0\41\0\54\0\67\0\102\0\115"+
"\0\67\0\130\0\143\0\156\0\171\0\204\0\102\0\217"+
"\0\102\0\67\0\232\0\67\0\67\0\67\0\245\0\67";
"\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\165\0\133\0\303\0\101\0\133\0\320"+
"\0\101\0\335\0\101\0\101";
private static int [] zzUnpackRowMap() {
int [] result = new int[24];
int [] result = new int[28];
int offset = 0;
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
return result;
@@ -187,17 +188,19 @@ class _KDocLexer implements FlexLexer {
private static final int [] ZZ_TRANS = zzUnpackTrans();
private static final String ZZ_TRANS_PACKED_0 =
"\4\6\1\7\1\10\4\6\1\0\1\11\1\12\2\11"+
"\1\13\2\11\1\14\1\15\1\16\1\12\1\11\1\12"+
"\2\11\1\17\1\11\1\20\1\14\1\15\1\16\1\12"+
"\1\11\1\12\2\11\1\17\2\11\1\14\1\15\1\16"+
"\1\12\4\6\1\7\5\6\20\0\1\21\1\22\11\0"+
"\1\23\7\0\1\12\10\0\1\12\4\0\1\13\1\22"+
"\15\0\2\24\11\0\1\25\13\0\1\26\4\0\1\27"+
"\13\0\1\30\10\0\2\27\7\0";
"\10\6\1\7\1\10\1\6\1\0\1\6\1\11\1\12"+
"\4\11\1\13\2\11\1\14\1\11\1\12\1\15\1\11"+
"\1\12\4\11\1\13\2\11\1\16\1\17\1\12\1\15"+
"\1\20\1\21\1\20\1\22\2\20\1\23\2\20\1\24"+
"\1\20\1\21\1\20\1\11\1\12\4\11\1\13\2\11"+
"\1\16\1\11\1\12\1\15\26\0\1\25\13\0\1\26"+
"\1\27\4\0\1\12\11\0\1\12\4\0\1\30\21\0"+
"\1\26\1\14\11\0\2\31\10\0\1\32\12\0\1\21"+
"\11\0\1\21\3\0\3\22\21\0\1\33\5\0\4\30"+
"\1\0\1\34\7\0\2\32\11\0";
private static int [] zzUnpackTrans() {
int [] result = new int[176];
int [] result = new int[234];
int offset = 0;
offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
return result;
@@ -238,11 +241,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\7\1\1\0\1\11\1\0"+
"\3\11\1\1\1\11";
"\5\0\1\11\2\1\1\11\6\1\1\11\4\1\1\0"+
"\1\11\2\0\1\11\1\1\2\11";
private static int [] zzUnpackAttribute() {
int [] result = new int[24];
int [] result = new int[28];
int offset = 0;
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
return result;
@@ -346,7 +349,7 @@ class _KDocLexer implements FlexLexer {
char [] map = new char[0x10000];
int i = 0; /* index in packed string */
int j = 0; /* index in unpacked array */
while (i < 1206) {
while (i < 1220) {
int count = packed.charAt(i++);
char value = packed.charAt(i++);
do map[j++] = value; while (--count > 0);
@@ -578,51 +581,63 @@ class _KDocLexer implements FlexLexer {
return KDocTokens.TEXT; // internal white space
}
}
case 11: break;
case 5:
{ if (isLastToken()) return KDocTokens.END;
else return KDocTokens.TEXT;
}
case 12: break;
case 9:
{ yybegin(CONTENTS);
return KDocTokens.TAG_NAME;
}
case 13: break;
case 7:
{ yybegin(CONTENTS);
return KDocTokens.WIKI_LINK_CLOSE;
return KDocTokens.TEXT_OR_LINK;
}
case 14: break;
case 8:
{ yybegin(CONTENTS);
return KDocTokens.WIKI_LINK_OPEN;
{ if (isLastToken()) return KDocTokens.END;
else return KDocTokens.TEXT;
}
case 15: break;
case 10:
case 5:
{ yybegin(CONTENTS);
return KDocTokens.TEXT;
}
case 16: break;
case 6:
{ if (yytextContainLineBreaks()) {
yybegin(LINE_BEGINNING);
}
return TokenType.WHITE_SPACE;
}
case 17: break;
case 12:
{ yybegin(CONTENTS);
return KDocTokens.MARKDOWN_LINK;
}
case 18: break;
case 11:
{ yybegin(CONTENTS);
return KDocTokens.START;
}
case 16: break;
case 19: break;
case 10:
{ yybegin(TAG_BEGINNING);
return KDocTokens.TAG_NAME;
}
case 20: break;
case 1:
{ return TokenType.BAD_CHARACTER;
}
case 17: break;
case 6:
case 21: break;
case 9:
{ yybegin(CONTENTS);
return KDocTokens.MARKDOWN_ESCAPED_CHAR;
}
case 18: break;
case 22: break;
case 2:
{ yybegin(CONTENTS);
return KDocTokens.TEXT;
}
case 19: break;
case 23: break;
case 4:
{ yybegin(CONTENTS_BEGINNING);
return KDocTokens.LEADING_ASTERISK;
}
case 20: break;
case 24: break;
default:
if (zzInput == YYEOF && zzStartRead == zzCurrentPos) {
zzAtEOF = true;
@@ -0,0 +1,47 @@
/*
* 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.
*/
package org.jetbrains.kotlin.kdoc.parser;
import com.intellij.lang.ASTNode;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.kotlin.idea.JetLanguage;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocElementImpl;
import java.lang.reflect.Constructor;
public class KDocElementType extends IElementType {
private final Constructor<? extends KDocElementImpl> myPsiFactory;
public KDocElementType(String debugName, Class<? extends KDocElementImpl> psiClass) {
super(debugName, JetLanguage.INSTANCE);
try {
myPsiFactory = psiClass != null ? psiClass.getConstructor(ASTNode.class) : null;
} catch (NoSuchMethodException e) {
throw new RuntimeException("Must have a constructor with ASTNode");
}
}
public KDocElementImpl createPsi(ASTNode node) {
assert node.getElementType() == this;
try {
return myPsiFactory.newInstance(node);
} catch (Exception e) {
throw new RuntimeException("Error creating psi element for node", e);
}
}
}
@@ -0,0 +1,25 @@
/*
* 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.
*/
package org.jetbrains.kotlin.kdoc.parser;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink;
import org.jetbrains.kotlin.kdoc.psi.impl.KDocTag;
public class KDocElementTypes {
public static final KDocElementType KDOC_TAG = new KDocElementType("KDOC_TAG", KDocTag.class);
public static final KDocElementType KDOC_LINK = new KDocElementType("KDOC_LINK", KDocLink.class);
}
@@ -0,0 +1,48 @@
/*
* 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.
*/
package org.jetbrains.kotlin.kdoc.parser;
public enum KDocKnownTag {
AUTHOR(false),
THROWS(true),
EXCEPTION(true),
PARAM(true),
RETURN(false),
SEE(false),
SINCE(false);
private final boolean takesReference;
KDocKnownTag(boolean takesReference) {
this.takesReference = takesReference;
}
public boolean isReferenceRequired() {
return takesReference;
}
public static KDocKnownTag findByTagName(String tagName) {
if (tagName.startsWith("@")) {
try {
return valueOf(tagName.substring(1).toUpperCase());
}
catch (IllegalArgumentException ignored) {
}
}
return null;
}
}
@@ -21,6 +21,7 @@ import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
public class KDocParser implements PsiParser {
@Override
@@ -30,10 +31,61 @@ public class KDocParser implements PsiParser {
// todo: parse KDoc tags, markdown, etc...
while (!builder.eof()) {
builder.advanceLexer();
if (builder.getTokenType() == KDocTokens.TAG_NAME) {
parseTag(builder);
}
else if (builder.getTokenType() == KDocTokens.MARKDOWN_LINK) {
PsiBuilder.Marker linkStart = builder.mark();
builder.advanceLexer();
linkStart.done(KDocElementTypes.KDOC_LINK);
}
else {
builder.advanceLexer();
}
}
rootMarker.done(root);
return builder.getTreeBuilt();
}
private static void parseTag(PsiBuilder builder) {
PsiBuilder.Marker tagStart = builder.mark();
String tagName = builder.getTokenText();
KDocKnownTag knownTag = KDocKnownTag.findByTagName(tagName);
builder.advanceLexer();
if (knownTag != null && knownTag.isReferenceRequired() && builder.getTokenType() == KDocTokens.TEXT_OR_LINK) {
PsiBuilder.Marker referenceMarker = builder.mark();
builder.advanceLexer();
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();
}
}
tagStart.done(KDocElementTypes.KDOC_TAG);
}
private static boolean isAtEndOfTag(PsiBuilder builder) {
if (builder.getTokenType() == KDocTokens.END) {
return true;
}
if (builder.getTokenType() == KDocTokens.LEADING_ASTERISK) {
int lookAheadCount = 1;
if (builder.lookAhead(1) == KDocTokens.TEXT) {
lookAheadCount++;
}
if (builder.lookAhead(lookAheadCount) == KDocTokens.TAG_NAME) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,26 @@
/*
* 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.
*/
package org.jetbrains.kotlin.kdoc.psi.impl;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
public class KDocLink extends KDocElementImpl {
public KDocLink(@NotNull ASTNode node) {
super(node);
}
}
@@ -0,0 +1,27 @@
/*
* 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.
*/
package org.jetbrains.kotlin.kdoc.psi.impl;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
public class KDocTag extends KDocElementImpl {
public KDocTag(@NotNull ASTNode node) {
super(node);
}
}
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.JetNodeType;
import org.jetbrains.kotlin.JetNodeTypes;
import org.jetbrains.kotlin.idea.JetLanguage;
import org.jetbrains.kotlin.kdoc.parser.KDocElementType;
import org.jetbrains.kotlin.lexer.JetLexer;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.psi.JetFile;
@@ -102,6 +103,9 @@ public class JetParserDefinition implements ParserDefinition {
elementType == JetNodeTypes.BLOCK_CODE_FRAGMENT) {
return new ASTWrapperPsiElement(astNode);
}
else if (elementType instanceof KDocElementType) {
return ((KDocElementType) elementType).createPsi(astNode);
}
else {
return ((JetNodeType) elementType).createPsi(astNode);
}
+8 -7
View File
@@ -6,12 +6,13 @@ JetFile: AtTags.kt
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
PsiElement(KDOC_TAG_NAME)('@tag')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' text @notATag')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' @')
KDOC_TAG
PsiElement(KDOC_TAG_NAME)('@tag')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' text @notATag')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' @')
PsiWhiteSpace('\n ')
PsiElement(KDOC_END)('*/')
+4 -2
View File
@@ -1,4 +1,6 @@
/**
* [[WikiLink]]
* Just \[[ and \]]
* [WikiLink]
* \[NotALink]
* [[DoubleQuotedLink]]
* Just \[ and \]
*/
+14 -5
View File
@@ -6,15 +6,24 @@ JetFile: Markdown.kt
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
PsiElement(KDOC_WIKI_LINK_OPEN)('[[')
PsiElement(KDOC_TEXT)('WikiLink')
PsiElement(KDOC_WIKI_LINK_CLOSE)(']]')
KDOC_LINK
PsiElement(KDOC_MARKDOWN_LINK)('[WikiLink]')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
PsiElement(KDOC_MARKDOWN_ESCAPED_CHAR)('\[')
PsiElement(KDOC_TEXT)('NotALink]')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' [')
KDOC_LINK
PsiElement(KDOC_MARKDOWN_LINK)('[DoubleQuotedLink]')
PsiElement(KDOC_TEXT)(']')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' Just ')
PsiElement(KDOC_MARKDOWN_ESCAPED_CHAR)('\[')
PsiElement(KDOC_TEXT)('[ and ')
PsiElement(KDOC_TEXT)(' and ')
PsiElement(KDOC_MARKDOWN_ESCAPED_CHAR)('\]')
PsiElement(KDOC_TEXT)(']')
PsiWhiteSpace('\n ')
PsiElement(KDOC_END)('*/')
+3
View File
@@ -0,0 +1,3 @@
/**
* @param a The description of a.
*/
+16
View File
@@ -0,0 +1,16 @@
JetFile: ParamTag.kt
PACKAGE_DIRECTIVE
<empty list>
KDoc
PsiElement(KDOC_START)('/**')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
KDOC_TAG
PsiElement(KDOC_TAG_NAME)('@param')
PsiWhiteSpace(' ')
KDOC_LINK
PsiElement(KDOC_TEXT_OR_LINK)('a')
PsiElement(KDOC_TEXT)(' The description of a.')
PsiWhiteSpace('\n ')
PsiElement(KDOC_END)('*/')
@@ -0,0 +1,4 @@
/**
* @return This is not a reference
* @return[x] This is a reference
*/
@@ -0,0 +1,23 @@
JetFile: ReturnWithBrackets.kt
PACKAGE_DIRECTIVE
<empty list>
KDoc
PsiElement(KDOC_START)('/**')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
KDOC_TAG
PsiElement(KDOC_TAG_NAME)('@return')
PsiWhiteSpace(' ')
PsiElement(KDOC_TEXT_OR_LINK)('This')
PsiElement(KDOC_TEXT)(' is not a reference')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
KDOC_TAG
PsiElement(KDOC_TAG_NAME)('@return')
KDOC_LINK
PsiElement(KDOC_MARKDOWN_LINK)('[x]')
PsiElement(KDOC_TEXT)(' This is a reference')
PsiWhiteSpace('\n ')
PsiElement(KDOC_END)('*/')
+4
View File
@@ -0,0 +1,4 @@
/**
* @author Dmitry Jemerov
* @since M12
*/
+22
View File
@@ -0,0 +1,22 @@
JetFile: TwoTags.kt
PACKAGE_DIRECTIVE
<empty list>
KDoc
PsiElement(KDOC_START)('/**')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
KDOC_TAG
PsiElement(KDOC_TAG_NAME)('@author')
PsiWhiteSpace(' ')
PsiElement(KDOC_TEXT_OR_LINK)('Dmitry')
PsiElement(KDOC_TEXT)(' Jemerov')
PsiWhiteSpace('\n ')
PsiElement(KDOC_LEADING_ASTERISK)('*')
PsiElement(KDOC_TEXT)(' ')
KDOC_TAG
PsiElement(KDOC_TAG_NAME)('@since')
PsiWhiteSpace(' ')
PsiElement(KDOC_TEXT_OR_LINK)('M12')
PsiWhiteSpace('\n ')
PsiElement(KDOC_END)('*/')
@@ -1085,6 +1085,18 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
doParsingTest(fileName);
}
@TestMetadata("ParamTag.kt")
public void testParamTag() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/kdoc/ParamTag.kt");
doParsingTest(fileName);
}
@TestMetadata("ReturnWithBrackets.kt")
public void testReturnWithBrackets() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/kdoc/ReturnWithBrackets.kt");
doParsingTest(fileName);
}
@TestMetadata("Simple.kt")
public void testSimple() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/kdoc/Simple.kt");
@@ -1096,6 +1108,12 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/kdoc/TextRightAfterLeadAsterisks.kt");
doParsingTest(fileName);
}
@TestMetadata("TwoTags.kt")
public void testTwoTags() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/kdoc/TwoTags.kt");
doParsingTest(fileName);
}
}
@TestMetadata("compiler/testData/psi/platformTypesRecovery")
@@ -22,7 +22,6 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.kdoc.lexer.KDocTokens;
import org.jetbrains.kotlin.lexer.JetTokens;
public class JetPairMatcher implements PairedBraceMatcher {
@@ -31,7 +30,6 @@ public class JetPairMatcher implements PairedBraceMatcher {
new BracePair(JetTokens.LONG_TEMPLATE_ENTRY_START, JetTokens.LONG_TEMPLATE_ENTRY_END, false),
new BracePair(JetTokens.LBRACE, JetTokens.RBRACE, true),
new BracePair(JetTokens.LBRACKET, JetTokens.RBRACKET, false),
new BracePair(KDocTokens.WIKI_LINK_OPEN, KDocTokens.WIKI_LINK_CLOSE, false)
};
@Override
@@ -46,8 +44,6 @@ public class JetPairMatcher implements PairedBraceMatcher {
return false;
}
if (lbraceType == KDocTokens.WIKI_LINK_OPEN) return false;
return JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(contextType)
|| contextType == JetTokens.SEMICOLON
|| contextType == JetTokens.COMMA