From 94770f8447b88b8d79973586e38391929a5d6c4b Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 14 Nov 2016 14:28:52 +0300 Subject: [PATCH] Fix for KT-13197 Markdown indented code blocks are not recognized by quick doc Expanded code blocks lexer test, to cover indented code blocks --- .../org/jetbrains/kotlin/kdoc/lexer/KDoc.flex | 39 ++- .../kotlin/kdoc/lexer/_KDocLexer.java | 286 +++++++++--------- .../jetbrains/kotlin/kdoc/psi/impl/KDocTag.kt | 38 ++- compiler/testData/kdoc/lexer/codeBlocks.kt | 8 +- compiler/testData/kdoc/lexer/codeBlocks.txt | 27 +- .../kotlin/idea/kdoc/KDocRenderer.kt | 4 +- .../editor/quickDoc/IndentedCodeBlock.kt | 22 ++ .../QuickDocProviderTestGenerated.java | 6 + 8 files changed, 255 insertions(+), 175 deletions(-) create mode 100644 idea/testData/editor/quickDoc/IndentedCodeBlock.kt 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 035d3caa59e..9e77cef17f8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag; return zzMarkedPos == zzBuffer.length(); } - private Boolean yytextContainLineBreaks() { + private boolean yytextContainLineBreaks() { return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos); } @@ -49,6 +49,7 @@ import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag; %state CODE_BLOCK %state CODE_BLOCK_LINE_BEGINNING %state CODE_BLOCK_CONTENTS_BEGINNING +%state INDENTED_CODE_BLOCK WHITE_SPACE_CHAR =[\ \t\f\n] NOT_WHITE_SPACE_CHAR=[^\ \t\f\n] @@ -130,18 +131,28 @@ CODE_FENCE_END=("```" | "~~~") } { + + ([\ ]{4}[\ ]*)|([\t]+) { + if(yystate() == CONTENTS_BEGINNING) { + yybegin(INDENTED_CODE_BLOCK); + return KDocTokens.CODE_BLOCK_TEXT; + } + } + {WHITE_SPACE_CHAR}+ { if (yytextContainLineBreaks()) { yybegin(LINE_BEGINNING); return TokenType.WHITE_SPACE; - } else { - yybegin(yystate() == CONTENTS_BEGINNING? CONTENTS_BEGINNING:CONTENTS); + } else { + yybegin(yystate() == CONTENTS_BEGINNING ? CONTENTS_BEGINNING : CONTENTS); return KDocTokens.TEXT; // internal white space } } - "\\"[\[\]] { yybegin(CONTENTS); - return KDocTokens.MARKDOWN_ESCAPED_CHAR; } + "\\"[\[\]] { + yybegin(CONTENTS); + return KDocTokens.MARKDOWN_ESCAPED_CHAR; + } "[" [^\[]* "](" [^)]* ")" { yybegin(CONTENTS); @@ -158,11 +169,15 @@ CODE_FENCE_END=("```" | "~~~") used in type declarations. No brackets, backticks, asterisks or anything like that. Also if a link is followed by [ or (, then its destination is a regular HTTP link and not a Kotlin identifier, so we don't need to do our parsing and resolution. */ - {CODE_LINK} / [^\(\[] { yybegin(CONTENTS); - return KDocTokens.MARKDOWN_LINK; } + {CODE_LINK} / [^\(\[] { + yybegin(CONTENTS); + return KDocTokens.MARKDOWN_LINK; + } - . { yybegin(CONTENTS); - return KDocTokens.TEXT; } + . { + yybegin(CONTENTS); + return KDocTokens.TEXT; + } } { @@ -180,17 +195,17 @@ CODE_FENCE_END=("```" | "~~~") } } - { + { {WHITE_SPACE_CHAR}+ { if (yytextContainLineBreaks()) { - yybegin(CODE_BLOCK_LINE_BEGINNING); + yybegin(yystate() == INDENTED_CODE_BLOCK ? LINE_BEGINNING : CODE_BLOCK_LINE_BEGINNING); return TokenType.WHITE_SPACE; } return KDocTokens.CODE_BLOCK_TEXT; } . { - yybegin(CODE_BLOCK); + yybegin(yystate() == INDENTED_CODE_BLOCK ? INDENTED_CODE_BLOCK : CODE_BLOCK); return KDocTokens.CODE_BLOCK_TEXT; } } 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 41e36395a73..84fab0a9e69 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/_KDocLexer.java @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.kdoc.parser.KDocKnownTag; /** * This class is a scanner generated by * JFlex 1.7.0-SNAPSHOT - * from the specification file /Users/endermz/projects/kotlin/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex + * from the specification file /home/user/Workspace/Kotlin/kotlin/compiler/frontend/src/org/jetbrains/kotlin/kdoc/lexer/KDoc.flex */ class _KDocLexer implements FlexLexer { @@ -33,6 +33,7 @@ class _KDocLexer implements FlexLexer { public static final int CODE_BLOCK = 12; public static final int CODE_BLOCK_LINE_BEGINNING = 14; public static final int CODE_BLOCK_CONTENTS_BEGINNING = 16; + public static final int INDENTED_CODE_BLOCK = 18; /** * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l @@ -42,13 +43,13 @@ class _KDocLexer implements FlexLexer { */ private static final int ZZ_LEXSTATE[] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, - 8, 8 + 8, 8, 6, 6 }; /** * Translates characters to character classes * Chosen bits are [11, 6, 4] - * Total runtime size is 12064 bytes + * Total runtime size is 9472 bytes */ public static int ZZ_CMAP(int ch) { return ZZ_CMAP_A[(ZZ_CMAP_Y[(ZZ_CMAP_Z[ch>>10]<<6)|((ch>>4)&0x3f)]<<4)|(ch&0xf)]; @@ -56,93 +57,71 @@ class _KDocLexer implements FlexLexer { /* The ZZ_CMAP_Z table has 1088 entries */ static final char ZZ_CMAP_Z[] = zzUnpackCMap( - "\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\2\11\1\12\1\13\6\14\1\15\23\14\1\16"+ - "\1\14\1\17\1\20\12\14\1\21\10\11\1\22\1\23\1\24\1\25\1\26\1\27\1\30\3\11\1"+ - "\31\1\32\2\11\1\14\1\33\14\11\1\34\21\11\1\35\10\11\1\36\12\11\51\14\1\37"+ - "\3\14\1\40\1\41\17\11\1\42\u0381\11"); + "\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\3\11\1\12\6\13\1\14\23\13\1\15\1\13"+ + "\1\16\1\11\12\13\1\17\10\11\1\20\1\21\1\22\1\23\1\24\62\11\1\25\12\11\51\13"+ + "\1\26\24\11\1\27\u0381\11"); - /* The ZZ_CMAP_Y table has 2240 entries */ + /* The ZZ_CMAP_Y table has 1536 entries */ static final char ZZ_CMAP_Y[] = zzUnpackCMap( - "\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\1\1\11\1\12\1\13\1\14\1\13\1\14\34"+ - "\13\1\15\1\16\1\17\10\1\1\20\1\21\1\13\1\22\4\13\1\23\10\13\1\24\11\13\1\25"+ - "\1\26\1\13\1\27\1\26\1\13\1\25\4\1\1\13\1\30\1\31\1\32\1\1\2\13\1\30\1\1\1"+ - "\33\1\26\5\13\1\34\1\35\1\36\1\1\1\37\1\13\1\1\1\40\5\13\1\41\1\42\1\43\1"+ - "\13\1\30\1\44\1\13\1\45\1\46\1\1\1\13\1\47\12\1\1\50\2\13\1\51\1\1\1\52\1"+ - "\16\1\53\1\54\1\55\1\56\1\57\1\60\1\61\1\16\1\62\1\63\1\55\1\56\1\64\1\1\1"+ - "\65\1\1\1\66\1\67\1\22\1\56\1\70\1\1\1\71\1\16\1\42\1\54\1\55\1\56\1\70\1"+ - "\1\1\61\1\16\1\42\1\72\1\73\1\74\1\75\1\1\1\71\1\1\1\76\1\77\1\37\1\56\1\100"+ - "\1\1\1\101\1\16\1\1\1\77\1\37\1\56\1\100\1\1\1\60\1\16\1\102\1\77\1\37\1\13"+ - "\1\103\1\60\1\1\1\16\1\43\1\104\1\105\1\13\1\106\1\107\3\1\1\26\2\13\1\110"+ - "\1\107\3\1\1\111\1\112\1\113\1\114\1\115\1\116\2\1\1\71\3\1\1\117\1\13\1\120"+ - "\1\1\1\121\7\1\2\13\1\30\1\122\1\1\1\123\1\124\1\125\1\126\1\1\2\13\1\41\2"+ - "\13\1\127\24\13\1\130\1\131\2\13\1\130\2\13\1\132\1\133\1\14\3\13\1\133\3"+ - "\13\1\30\2\1\1\13\1\1\5\13\1\134\1\26\45\13\1\135\1\13\1\26\1\30\4\13\1\136"+ - "\1\71\1\137\1\16\1\13\1\16\1\13\1\16\1\137\1\71\3\13\1\140\1\1\1\141\4\1\5"+ - "\13\1\25\2\13\1\142\4\13\1\41\1\13\1\120\3\1\1\13\1\143\1\134\2\13\1\144\1"+ - "\1\1\145\3\1\1\13\1\107\3\13\1\134\4\1\1\146\5\1\1\104\2\13\1\140\1\147\3"+ - "\1\1\150\1\13\1\151\1\1\2\13\1\41\1\1\2\13\1\140\1\1\1\40\1\43\1\13\1\143"+ - "\6\1\1\152\1\16\14\13\4\1\21\13\1\153\2\13\1\153\1\154\1\13\1\143\3\13\1\155"+ - "\1\156\1\157\1\120\1\156\2\1\1\160\1\122\1\71\1\161\1\1\1\162\1\1\1\120\1"+ - "\13\1\75\4\1\1\163\1\164\1\165\1\166\1\167\1\1\2\13\1\47\147\1\2\13\1\170"+ - "\2\13\1\170\10\13\1\171\1\1\2\13\1\41\3\13\1\172\1\1\1\13\1\107\4\173\4\1"+ - "\1\122\35\1\1\174\1\1\1\175\1\176\1\26\4\13\1\177\1\26\4\13\1\200\1\104\1"+ - "\13\1\143\1\26\4\13\1\170\1\1\1\13\1\30\3\1\1\13\40\1\133\13\1\41\4\1\134"+ - "\13\1\144\3\1\10\13\1\120\4\1\2\13\1\143\20\13\1\120\1\13\1\201\1\1\2\13\1"+ - "\170\1\122\1\13\1\25\5\13\2\1\1\202\1\203\5\13\1\204\1\16\1\75\4\1\1\43\1"+ - "\205\1\13\1\31\1\206\3\13\1\140\1\203\2\13\1\140\3\1\1\207\1\43\1\13\1\41"+ - "\1\13\1\107\1\1\1\13\1\120\1\50\2\13\1\31\1\122\3\1\2\13\1\47\1\1\1\210\1"+ - "\1\1\13\1\211\3\13\1\212\1\213\1\214\2\1\1\215\1\216\1\173\11\1\2\13\1\31"+ - "\1\1\72\13\1\140\1\13\1\217\2\13\1\144\20\1\22\13\1\143\3\13\1\143\6\13\1"+ - "\75\2\1\1\107\1\220\1\56\1\221\1\222\6\13\1\16\1\1\1\150\25\13\1\143\1\1\4"+ - "\13\1\203\2\13\1\25\2\1\1\120\3\1\1\223\1\40\1\1\1\76\1\224\7\13\1\120\1\161"+ - "\1\1\1\26\1\225\1\26\1\30\1\226\4\13\1\170\1\227\1\230\1\231\1\1\1\232\1\13"+ - "\1\14\1\233\2\143\2\1\7\13\1\30\4\1\3\13\1\134\20\1\1\13\1\120\3\13\1\71\2"+ - "\1\1\13\1\170\1\1\1\13\1\30\3\1\1\13\1\143\2\13\1\234\1\235\2\1\11\13\1\143"+ - "\66\1\1\236\2\13\1\237\1\13\1\41\12\1\1\13\1\41\1\13\1\75\14\1\1\71\1\240"+ - "\1\13\1\140\2\1\1\13\1\120\10\1\3\13\1\41\1\13\1\41\1\13\1\31\10\1\4\13\1"+ - "\47\73\1\1\150\2\13\1\25\4\1\1\150\2\13\65\1\66\13\1\170\11\1\6\13\1\31\71"+ - "\1\2\13\1\170\75\1\43\13\1\47\34\1\1\16\77\1\5\13\1\224\3\13\1\137\1\241\1"+ - "\242\1\243\3\13\1\244\1\245\1\13\1\246\1\247\1\37\24\13\1\250\1\13\1\37\1"+ - "\200\1\13\1\200\1\13\1\224\1\13\1\224\1\170\1\13\1\170\1\13\1\56\1\13\1\56"+ - "\1\13\1\210\3\1\55\13\1\107\2\1\103\13\1\134\15\13\1\143\76\1\41\13\1\143"+ - "\36\1"); + "\1\0\1\1\1\2\1\3\1\4\1\5\1\6\1\7\1\10\1\1\1\11\1\12\1\13\1\14\1\13\1\14\23"+ + "\13\1\15\1\1\7\13\1\16\1\17\1\20\10\1\1\21\1\22\1\13\1\23\1\13\1\24\2\13\1"+ + "\25\10\13\1\26\3\13\1\24\2\13\1\27\1\13\2\1\1\30\1\13\1\31\1\30\1\13\1\32"+ + "\4\1\1\13\1\33\1\34\2\1\1\30\2\33\1\1\1\35\1\30\5\13\1\36\1\37\1\40\1\1\1"+ + "\41\1\13\1\1\1\42\3\1\2\13\1\43\1\44\24\1\1\45\2\13\1\46\1\1\1\47\1\17\1\1"+ + "\1\50\1\51\1\52\1\53\1\1\1\54\1\17\1\55\1\56\1\51\1\52\1\57\1\1\1\60\1\1\1"+ + "\61\1\62\1\23\1\52\1\63\1\1\1\64\1\17\1\44\1\50\1\51\1\52\1\63\1\1\1\54\1"+ + "\17\1\44\1\65\1\66\1\67\1\70\3\1\1\71\1\72\1\41\1\52\1\73\2\1\1\17\1\1\1\72"+ + "\1\41\1\52\1\74\1\1\1\75\1\17\1\1\1\72\1\41\1\52\1\76\2\1\1\17\1\1\1\77\1"+ + "\100\1\13\1\101\1\15\3\1\1\30\2\13\1\102\1\15\3\1\1\103\1\104\1\105\1\106"+ + "\1\107\1\110\2\1\1\64\3\1\1\111\1\13\1\33\1\1\1\112\7\1\2\13\1\113\2\1\1\43"+ + "\4\1\2\13\1\43\2\13\1\114\5\13\1\115\4\13\1\116\4\13\1\76\1\14\3\13\2\117"+ + "\2\13\1\117\1\13\1\24\2\120\1\14\1\24\1\13\1\24\1\120\2\13\1\14\1\33\4\1\5"+ + "\13\1\121\1\30\45\13\1\122\1\15\1\30\1\33\4\13\1\123\1\64\1\124\1\17\1\13"+ + "\1\17\1\13\1\17\1\124\1\64\3\13\1\55\1\1\1\125\4\1\5\13\1\32\2\13\1\114\5"+ + "\1\1\13\1\126\3\1\1\13\1\127\1\121\70\1\6\13\1\130\11\1\11\13\1\130\5\13\1"+ + "\76\1\13\1\131\2\13\1\131\1\132\1\13\1\127\3\13\1\133\1\134\1\135\1\126\1"+ + "\134\2\1\1\136\1\137\1\64\1\140\1\1\1\141\2\1\1\13\1\17\4\1\1\142\1\143\1"+ + "\144\1\145\1\146\1\1\2\13\1\55\147\1\1\147\1\1\1\150\1\151\1\30\4\13\1\152"+ + "\1\30\5\13\1\77\1\13\1\126\1\30\4\13\1\24\1\1\1\13\1\32\3\1\1\13\40\1\133"+ + "\13\1\43\4\1\132\13\1\43\5\1\10\13\1\126\67\1\72\13\1\55\25\1\22\13\1\127"+ + "\3\13\1\33\11\1\1\15\1\153\1\52\1\154\1\155\6\13\1\17\1\1\1\156\25\13\1\127"+ + "\1\1\4\13\1\157\2\13\1\32\2\1\1\126\3\1\1\160\1\42\1\1\1\71\1\161\7\13\1\126"+ + "\1\140\1\1\1\30\1\162\1\30\1\33\1\77\4\13\1\24\1\163\1\164\1\165\1\1\1\166"+ + "\1\13\1\14\1\167\2\127\2\1\7\13\1\33\40\1\1\13\1\24\1\1\1\13\1\33\3\1\1\13"+ + "\1\127\6\1\11\13\1\127\66\1\1\170\2\13\1\171\74\1\5\13\1\161\3\13\1\124\1"+ + "\172\1\173\1\174\3\13\1\175\1\176\1\13\1\177\1\200\1\41\24\13\1\201\1\13\1"+ + "\41\1\202\1\13\1\202\1\13\1\161\1\13\1\161\1\24\1\13\1\24\1\13\1\52\1\13\1"+ + "\52\1\13\1\203\3\1\55\13\1\15\22\1\41\13\1\127\36\1"); - /* The ZZ_CMAP_A table has 2704 entries */ + /* The ZZ_CMAP_A table has 2112 entries */ static final char ZZ_CMAP_A[] = zzUnpackCMap( - "\11\0\1\1\1\11\1\12\1\13\1\12\22\0\1\1\3\0\1\3\3\0\1\20\1\21\1\15\3\0\1\4"+ - "\1\14\12\2\6\0\1\16\32\3\1\5\1\17\1\6\1\0\1\3\1\7\32\3\3\0\1\10\6\0\1\12\14"+ - "\0\4\3\4\0\1\3\12\0\1\3\4\0\1\3\5\0\27\3\1\0\12\3\4\0\14\3\16\0\5\3\7\0\1"+ - "\3\1\0\1\3\1\0\5\3\1\0\2\3\2\0\4\3\10\0\1\3\1\0\3\3\1\0\1\3\1\0\4\3\1\0\23"+ - "\3\1\0\13\3\10\0\16\3\11\0\26\3\2\0\1\3\6\0\13\3\5\0\3\3\30\0\1\3\22\0\6\3"+ - "\1\0\1\3\17\0\2\3\7\0\2\3\12\0\3\3\2\0\2\3\1\0\16\3\15\0\11\3\13\0\1\3\30"+ - "\0\6\3\4\0\2\3\4\0\1\3\5\0\6\3\4\0\1\3\11\0\1\3\3\0\1\3\7\0\11\3\13\0\26\3"+ - "\3\0\1\3\2\0\1\3\7\0\10\3\1\0\7\3\1\0\7\3\5\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\20\0\1\3\15\0\2\3\1\0\5\3\7\0\1\3\11\0\6\3\4\0"+ - "\2\3\1\0\2\3\1\0\2\3\1\0\2\3\17\0\4\3\1\0\1\3\3\0\3\3\20\0\11\3\1\0\2\3\1"+ - "\0\2\3\1\0\5\3\3\0\1\3\2\0\1\3\22\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\14\3\17\0\1\3\13\0\10\3\1\0\6\3\1\0\5\3"+ - "\3\0\1\3\12\0\2\3\7\0\2\3\15\0\13\3\2\0\1\3\7\0\22\3\3\0\10\3\1\0\11\3\1\0"+ - "\1\3\2\0\7\3\11\0\1\3\1\0\2\3\13\0\1\3\1\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\2\0\10\3\1\0\24\3\13\0\5\3\22\0\7\3\4\0\4\3"+ - "\3\0\1\3\3\0\2\3\7\0\3\3\4\0\15\3\14\0\1\3\1\0\13\3\1\0\1\3\3\0\11\3\1\0\4"+ - "\3\2\0\7\3\1\0\1\3\1\0\4\3\2\0\1\3\1\0\4\3\2\0\7\3\1\0\1\3\1\0\4\3\2\0\15"+ - "\3\13\0\15\3\2\0\14\3\3\0\17\3\1\0\6\3\23\0\1\3\3\0\2\3\3\0\11\3\1\0\1\3\5"+ - "\0\16\3\2\0\14\3\5\0\7\3\17\0\1\3\15\0\7\3\7\0\16\3\15\0\2\3\11\0\4\3\1\0"+ - "\10\3\2\0\6\3\2\0\10\3\1\0\1\3\1\0\1\3\1\0\1\3\1\0\6\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\14\0\2\12\12\0\1\3\14\0\1\3\15\0\1\3\2\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\13\3"+ - "\2\0\4\3\5\0\5\3\4\0\1\3\1\0\17\3\1\0\5\3\6\0\4\3\1\0\6\3\11\0\10\3\1\0\7"+ - "\3\6\0\3\3\11\0\11\3\7\0\5\3\2\0\5\3\3\0\7\3\6\0\16\3\1\0\4\3\12\0\2\3\13"+ - "\0\11\3\2\0\27\3\2\0\4\3\1\0\2\3\1\0\3\3\1\0\4\3\1\0\4\3\10\0\1\3\11\0\6\3"+ - "\3\0\1\3\4\0\3\3\1\0\10\3\4\0\7\3\3\0\1\3\6\0\1\3\3\0\2\3\2\0\5\3\2\0\1\3"+ - "\1\0\1\3\30\0\3\3\3\0\6\3\2\0\6\3\2\0\6\3\11\0\7\3\4\0\5\3\3\0\5\3\5\0\1\3"+ - "\1\0\10\3\1\0\5\3\1\0\1\3\1\0\2\3\1\0\2\3\1\0\12\3\3\0\2\3\13\0\5\3\1\0\25"+ - "\3\4\0\1\3\6\0\12\3\2\0\6\3\2\0\6\3\2\0\6\3\2\0\3\3\3\0\2\3\3\0\2\3\11\0\14"+ - "\3\1\0\16\3\1\0\2\3\1\0\5\3\4\0\10\3\1\0\5\3\12\0\6\3\2\0\1\3\1\0\14\3\1\0"+ - "\2\3\3\0\1\3\2\0\5\3\1\0\3\3\1\0\7\3\2\0\1\3\2\0\2\3\2\0\4\3\1\0\14\3\1\0"+ - "\1\3\1\0\7\3\1\0\21\3\1\0\4\3\2\0\10\3\1\0\7\3\1\0\14\3\1\0\4\3\1\0\5\3\1"+ - "\0\1\3\3\0\14\3\2\0\10\3"); + "\11\0\1\1\1\11\1\12\1\13\1\12\22\0\1\17\3\0\1\3\3\0\1\21\1\22\1\15\3\0\1\4"+ + "\1\14\12\2\6\0\1\16\32\3\1\5\1\20\1\6\1\0\1\3\1\7\32\3\3\0\1\10\6\0\1\12\14"+ + "\0\4\3\4\0\1\3\12\0\1\3\4\0\1\3\5\0\27\3\1\0\17\3\11\0\2\3\4\0\14\3\16\0\5"+ + "\3\11\0\1\3\13\0\1\3\13\0\1\3\1\0\3\3\1\0\1\3\1\0\4\3\1\0\34\3\1\0\6\3\1\0"+ + "\5\3\4\0\2\3\10\0\14\3\2\0\2\3\7\0\26\3\2\0\1\3\6\0\10\3\10\0\13\3\5\0\3\3"+ + "\33\0\6\3\1\0\1\3\17\0\2\3\7\0\2\3\12\0\3\3\2\0\2\3\1\0\16\3\15\0\11\3\13"+ + "\0\1\3\22\0\26\3\3\0\1\3\2\0\1\3\7\0\10\3\5\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\16\0\2\3\1\0\5\3\21\0\6\3\4\0\2\3\1\0\2\3\1\0\2"+ + "\3\1\0\2\3\17\0\4\3\1\0\1\3\3\0\3\3\20\0\11\3\1\0\2\3\1\0\2\3\1\0\5\3\3\0"+ + "\1\3\2\0\1\3\22\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\17\0\1\3\13\0\10\3\1\0\6\3\1\0\5\3\6\0\4\3\1"+ + "\0\5\3\3\0\1\3\20\0\1\3\1\0\12\3\13\0\22\3\3\0\10\3\1\0\11\3\1\0\1\3\2\0\1"+ + "\3\1\0\2\3\13\0\1\3\1\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\2\0\10\3\1\0\7\3\10\0\4\3\4\0\2\3\1\0\5\3\1\0\2\3\5\0\11\3\7\0"+ + "\12\3\5\0\4\3\5\0\17\3\1\0\1\3\1\0\4\3\2\0\1\3\1\0\4\3\2\0\7\3\1\0\5\3\13"+ + "\0\15\3\2\0\14\3\3\0\17\3\1\0\2\3\7\0\1\3\3\0\2\3\3\0\15\3\3\0\16\3\2\0\14"+ + "\3\4\0\6\3\2\0\6\3\2\0\10\3\1\0\1\3\1\0\1\3\1\0\1\3\1\0\6\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\14\0\2\12\25\0\1\3\4\0\1\3\14\0\1\3\15"+ + "\0\1\3\2\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\13\0\3\3\11\0\11\3\7\0\5\3\2\0\5\3"+ + "\3\0\7\3\6\0\3\3\3\0\5\3\5\0\1\3\1\0\10\3\1\0\5\3\1\0\1\3\1\0\2\3\1\0\2\3"+ + "\1\0\12\3\3\0\15\3\2\0\16\3\3\0\2\3\13\0\5\3\1\0\25\3\4\0\1\3\2\0\6\3\2\0"+ + "\6\3\2\0\6\3\2\0\3\3\3\0\2\3\3\0\2\3\11\0\14\3\1\0\16\3\1\0\2\3\1\0\7\3\2"+ + "\0\1\3\1\0\14\3\1\0\2\3\3\0\1\3\2\0\1\3\2\0\1\3\2\0\2\3\2\0\4\3\1\0\14\3\1"+ + "\0\1\3\1\0\7\3\1\0\21\3\1\0\4\3\2\0\10\3\1\0\7\3\1\0\14\3\1\0\4\3\1\0\5\3"+ + "\1\0\1\3\3\0\12\3\4\0\23\3\1\0\7\3\1\0\6\3\6\0"); /** * Translates DFA states to action switch labels. @@ -150,13 +129,14 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\11\0\3\1\1\2\1\3\3\2\1\4\3\2\1\5"+ - "\1\6\1\7\3\5\1\10\1\11\3\10\1\12\1\0"+ - "\1\13\6\0\1\14\1\15\4\0\1\16\2\0\1\17"+ - "\1\20\1\21\1\0\2\22\1\0\1\23\1\24\1\23"; + "\11\0\3\1\1\2\1\3\3\2\1\4\1\5\1\4"+ + "\3\2\1\6\1\7\2\2\1\10\1\11\3\10\1\12"+ + "\1\0\1\13\6\0\1\4\1\14\1\15\4\0\1\16"+ + "\2\0\1\17\1\4\1\20\1\21\1\0\2\22\1\0"+ + "\1\23\1\3\1\24\1\23"; private static int [] zzUnpackAction() { - int [] result = new int[60]; + int [] result = new int[63]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -181,17 +161,17 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\22\0\44\0\66\0\110\0\132\0\154\0\176"+ - "\0\220\0\242\0\264\0\306\0\242\0\330\0\352\0\374"+ - "\0\u010e\0\u0120\0\u0132\0\306\0\u0144\0\242\0\u0156\0\u0168"+ - "\0\u017a\0\306\0\u018c\0\242\0\u019e\0\306\0\u01b0\0\u01c2"+ - "\0\u01d4\0\u01e6\0\242\0\306\0\u01f8\0\u020a\0\u021c\0\u022e"+ - "\0\u0240\0\242\0\u0252\0\u0264\0\u0276\0\u0288\0\u029a\0\242"+ - "\0\u02ac\0\u02be\0\u02d0\0\242\0\242\0\u02e2\0\u01f8\0\u021c"+ - "\0\u02f4\0\u01f8\0\u0306\0\242"; + "\0\0\0\23\0\46\0\71\0\114\0\137\0\162\0\205"+ + "\0\230\0\253\0\276\0\321\0\253\0\344\0\367\0\u010a"+ + "\0\u011d\0\u0130\0\u0143\0\u0156\0\u0169\0\321\0\u017c\0\u018f"+ + "\0\u01a2\0\u01b5\0\u01c8\0\253\0\u01db\0\321\0\u01ee\0\u0201"+ + "\0\u0214\0\u0227\0\253\0\321\0\u023a\0\u024d\0\u0260\0\u0273"+ + "\0\u0286\0\u0299\0\253\0\u02ac\0\u02bf\0\u02d2\0\u02e5\0\u02f8"+ + "\0\253\0\u030b\0\u031e\0\u0331\0\u0344\0\253\0\253\0\u0357"+ + "\0\u023a\0\u0260\0\u036a\0\u023a\0\u0344\0\u037d\0\253"; private static int [] zzUnpackRowMap() { - int [] result = new int[60]; + int [] result = new int[63]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -214,37 +194,43 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = - "\11\12\3\0\1\13\1\14\4\12\1\15\1\16\3\15"+ - "\1\17\1\15\1\20\1\21\1\16\1\0\1\16\1\15"+ - "\1\22\1\15\1\23\3\15\1\16\3\15\1\17\1\15"+ - "\1\20\1\21\1\16\1\0\1\16\1\15\1\24\1\25"+ - "\1\23\2\15\1\26\1\27\1\26\1\30\1\26\1\31"+ - "\3\26\1\27\1\0\1\27\1\26\1\32\5\26\1\27"+ - "\3\26\1\33\3\26\1\27\1\0\1\27\1\26\1\32"+ - "\4\26\1\15\1\16\3\15\1\17\1\15\1\20\1\21"+ - "\1\16\1\0\1\16\1\15\1\24\1\15\1\23\2\15"+ - "\1\34\1\35\7\34\1\35\1\0\1\35\1\34\1\36"+ - "\5\34\1\35\5\34\1\37\1\40\1\35\1\0\1\35"+ - "\1\34\1\41\5\34\1\35\5\34\1\37\1\40\1\35"+ - "\1\0\1\35\1\34\1\36\4\34\37\0\1\42\20\0"+ - "\1\43\1\44\5\0\1\16\7\0\1\16\1\0\1\16"+ - "\6\0\3\45\1\46\1\45\1\0\1\47\13\45\7\0"+ - "\1\50\22\0\1\51\25\0\1\43\1\22\11\0\2\52"+ - "\16\0\1\53\17\0\1\27\7\0\1\27\1\0\1\27"+ - "\10\0\3\30\20\0\1\54\21\0\1\55\17\0\1\35"+ - "\7\0\1\35\1\0\1\35\15\0\1\56\22\0\1\57"+ - "\25\0\1\43\1\41\21\0\1\60\4\0\5\45\1\0"+ - "\1\47\15\45\3\46\1\0\1\61\20\45\1\0\1\47"+ - "\11\45\1\62\1\45\7\0\1\63\22\0\1\63\13\0"+ - "\2\53\20\0\3\54\1\0\1\64\15\0\3\55\1\0"+ - "\1\65\22\0\1\66\22\0\1\66\11\0\5\67\1\0"+ - "\1\70\11\67\1\62\1\67\5\62\1\71\13\62\1\72"+ - "\11\63\3\0\6\63\1\0\1\66\7\0\1\73\1\0"+ - "\1\66\6\0\21\71\1\74\1\0\1\73\11\0\1\73"+ - "\6\0"; + "\11\12\3\0\1\13\1\14\5\12\1\15\1\16\3\15"+ + "\1\17\1\15\1\20\1\21\1\22\1\0\1\22\1\15"+ + "\1\23\1\15\1\24\1\25\3\15\1\16\3\15\1\17"+ + "\1\15\1\20\1\21\1\22\1\0\1\22\1\15\1\26"+ + "\1\27\1\24\1\25\3\15\1\30\1\15\1\31\1\15"+ + "\1\32\3\15\1\30\1\0\1\30\1\15\1\26\1\15"+ + "\1\30\4\15\1\30\3\15\1\33\3\15\1\30\1\0"+ + "\1\30\1\15\1\26\1\15\1\30\4\15\1\16\3\15"+ + "\1\17\1\15\1\20\1\21\1\22\1\0\1\22\1\15"+ + "\1\26\1\15\1\24\1\25\2\15\1\34\1\35\7\34"+ + "\1\35\1\0\1\35\1\34\1\36\1\34\1\35\4\34"+ + "\1\35\5\34\1\37\1\40\1\35\1\0\1\35\1\34"+ + "\1\41\1\34\1\35\4\34\1\35\5\34\1\37\1\40"+ + "\1\35\1\0\1\35\1\34\1\36\1\34\1\35\3\34"+ + "\40\0\1\42\21\0\1\43\1\44\6\0\1\16\7\0"+ + "\1\22\1\0\1\22\3\0\1\22\3\0\3\45\1\46"+ + "\1\45\1\0\1\47\14\45\7\0\1\50\23\0\1\51"+ + "\13\0\1\22\7\0\1\22\1\0\1\22\3\0\1\22"+ + "\17\0\1\43\1\23\6\0\1\22\7\0\1\22\1\0"+ + "\1\22\3\0\1\52\10\0\2\53\17\0\1\54\20\0"+ + "\1\30\7\0\1\30\1\0\1\30\3\0\1\30\5\0"+ + "\3\31\21\0\1\55\22\0\1\56\20\0\1\35\7\0"+ + "\1\35\1\0\1\35\3\0\1\35\12\0\1\57\23\0"+ + "\1\60\26\0\1\43\1\41\22\0\1\61\5\0\5\45"+ + "\1\0\1\47\16\45\3\46\1\0\1\62\21\45\1\0"+ + "\1\47\12\45\1\63\1\45\7\0\1\64\23\0\1\64"+ + "\13\0\1\22\7\0\1\22\1\0\1\22\3\0\1\65"+ + "\5\0\2\54\21\0\3\55\1\0\1\66\16\0\3\56"+ + "\1\0\1\67\23\0\1\70\23\0\1\70\12\0\5\71"+ + "\1\0\1\72\12\71\1\63\1\71\5\63\1\73\14\63"+ + "\1\74\11\64\3\0\7\64\1\0\1\22\7\0\1\22"+ + "\1\0\1\22\3\0\1\75\4\0\1\70\7\0\1\76"+ + "\1\0\1\70\3\0\1\70\3\0\22\73\1\77\1\0"+ + "\1\76\11\0\1\76\3\0\1\76\3\0"; private static int [] zzUnpackTrans() { - int [] result = new int[792]; + int [] result = new int[912]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -282,12 +268,12 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\11\0\1\11\2\1\1\11\10\1\1\11\5\1\1\11"+ - "\5\1\1\0\1\11\6\0\1\11\1\1\4\0\1\11"+ - "\2\0\1\1\2\11\1\0\2\1\1\0\2\1\1\11"; + "\11\0\1\11\2\1\1\11\16\1\1\11\5\1\1\0"+ + "\1\11\6\0\1\1\1\11\1\1\4\0\1\11\2\0"+ + "\2\1\2\11\1\0\2\1\1\0\3\1\1\11"; private static int [] zzUnpackAttribute() { - int [] result = new int[60]; + int [] result = new int[63]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -351,7 +337,7 @@ class _KDocLexer implements FlexLexer { return zzMarkedPos == zzBuffer.length(); } - private Boolean yytextContainLineBreaks() { + private boolean yytextContainLineBreaks() { return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos); } @@ -628,27 +614,29 @@ class _KDocLexer implements FlexLexer { case 21: break; case 2: { yybegin(CONTENTS); - return KDocTokens.TEXT; + return KDocTokens.TEXT; } case 22: break; case 3: - { if (yytextContainLineBreaks()) { - yybegin(LINE_BEGINNING); - return TokenType.WHITE_SPACE; - } else { - yybegin(yystate() == CONTENTS_BEGINNING? CONTENTS_BEGINNING:CONTENTS); - return KDocTokens.TEXT; // internal white space + { if(yystate() == CONTENTS_BEGINNING) { + yybegin(INDENTED_CODE_BLOCK); + return KDocTokens.CODE_BLOCK_TEXT; } } case 23: break; case 4: - { yybegin(CONTENTS_BEGINNING); - return KDocTokens.LEADING_ASTERISK; + { if (yytextContainLineBreaks()) { + yybegin(LINE_BEGINNING); + return TokenType.WHITE_SPACE; + } else { + yybegin(yystate() == CONTENTS_BEGINNING ? CONTENTS_BEGINNING : CONTENTS); + return KDocTokens.TEXT; // internal white space + } } case 24: break; case 5: - { yybegin(CONTENTS); - return KDocTokens.TEXT; + { yybegin(CONTENTS_BEGINNING); + return KDocTokens.LEADING_ASTERISK; } case 25: break; case 6: @@ -664,13 +652,13 @@ class _KDocLexer implements FlexLexer { } case 27: break; case 8: - { yybegin(CODE_BLOCK); + { yybegin(yystate() == INDENTED_CODE_BLOCK ? INDENTED_CODE_BLOCK : CODE_BLOCK); return KDocTokens.CODE_BLOCK_TEXT; } case 28: break; case 9: { if (yytextContainLineBreaks()) { - yybegin(CODE_BLOCK_LINE_BEGINNING); + yybegin(yystate() == INDENTED_CODE_BLOCK ? LINE_BEGINNING : CODE_BLOCK_LINE_BEGINNING); return TokenType.WHITE_SPACE; } return KDocTokens.CODE_BLOCK_TEXT; @@ -688,7 +676,7 @@ class _KDocLexer implements FlexLexer { case 31: break; case 12: { yybegin(CONTENTS); - return KDocTokens.MARKDOWN_ESCAPED_CHAR; + return KDocTokens.MARKDOWN_ESCAPED_CHAR; } case 32: break; case 13: @@ -722,7 +710,7 @@ class _KDocLexer implements FlexLexer { zzMarkedPos = Character.offsetByCodePoints (zzBufferL/*, zzStartRead, zzEndRead - zzStartRead*/, zzMarkedPos, -1); { yybegin(CONTENTS); - return KDocTokens.MARKDOWN_LINK; + return KDocTokens.MARKDOWN_LINK; } case 38: break; case 19: 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 0e410c2462a..1280ab97d23 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 @@ -67,9 +67,9 @@ open class KDocTag(node: ASTNode) : KDocElementImpl(node) { } private fun childrenAfterTagName(): List = - node.getChildren(null) - .dropWhile { it.elementType == KDocTokens.TAG_NAME } - .dropWhile { it.elementType == TokenType.WHITE_SPACE } + node.getChildren(null) + .dropWhile { it.elementType == KDocTokens.TAG_NAME } + .dropWhile { it.elementType == TokenType.WHITE_SPACE } /** * Returns the content of this tag (all text following the tag name and the subject if present, @@ -82,14 +82,17 @@ open class KDocTag(node: ASTNode) : KDocElementImpl(node) { var contentStarted = false var afterAsterisk = false + var indentedCodeBlock = false + + fun isCodeBlock() = targetBuilder == codeBlockBuilder fun startCodeBlock() { targetBuilder = codeBlockBuilder } fun flushCodeBlock() { - if (targetBuilder == codeBlockBuilder) { - builder.append(trimCommonIndent(codeBlockBuilder)) + if (isCodeBlock()) { + builder.append(trimCommonIndent(codeBlockBuilder, indentedCodeBlock)) codeBlockBuilder.setLength(0) targetBuilder = builder } @@ -102,17 +105,23 @@ open class KDocTag(node: ASTNode) : KDocElementImpl(node) { for (node in children) { val type = node.elementType if (type == KDocTokens.CODE_BLOCK_TEXT) { + //If first line of code block + if (!isCodeBlock()) + indentedCodeBlock = indentedCodeBlock || node.text.startsWith(indentationWhiteSpaces) || node.text.startsWith("\t") startCodeBlock() } else if (KDocTokens.CONTENT_TOKENS.contains(type)) { flushCodeBlock() + indentedCodeBlock = false } if (KDocTokens.CONTENT_TOKENS.contains(type)) { - targetBuilder.append(if (!contentStarted || (afterAsterisk && targetBuilder == builder)) - node.text.trimStart() - else - node.text) + val isPlainContent = afterAsterisk && !isCodeBlock() + // If content not yet started and not part of indented code block + // and not inside fenced code block we should trim leading spaces + val trimLeadingSpaces = !(contentStarted || indentedCodeBlock) || isPlainContent + + targetBuilder.append(if (trimLeadingSpaces) node.text.trimStart() else node.text) contentStarted = true afterAsterisk = false } @@ -132,11 +141,18 @@ open class KDocTag(node: ASTNode) : KDocElementImpl(node) { return builder.toString().trimEnd(' ', '\t') } - private fun trimCommonIndent(builder: StringBuilder): String { + private fun trimCommonIndent(builder: StringBuilder, prepend4WhiteSpaces: Boolean = false): String { val lines = builder.toString().split('\n') val minIndent = lines.filter { it.trim().isNotEmpty() }.map { it.calcIndent() }.min() ?: 0 - return lines.map { it.drop(minIndent) }.joinToString("\n") + var processedLines = lines.map { it.drop(minIndent) } + if (prepend4WhiteSpaces) + processedLines = processedLines.map { if (it.isNotBlank()) it.prependIndent(indentationWhiteSpaces) else it } + return processedLines.joinToString("\n") } fun String.calcIndent() = indexOfFirst { !it.isWhitespace() } + + companion object { + val indentationWhiteSpaces = " ".repeat(4) + } } diff --git a/compiler/testData/kdoc/lexer/codeBlocks.kt b/compiler/testData/kdoc/lexer/codeBlocks.kt index 2b7a2d7a0b3..1bdfe6787c2 100644 --- a/compiler/testData/kdoc/lexer/codeBlocks.kt +++ b/compiler/testData/kdoc/lexer/codeBlocks.kt @@ -1,4 +1,10 @@ /** + * @foo This is text. + * This is indented code block + * Second line of code block + * @foo This is text. + * Tabulated code block + * Tabulated second line * @foo This is text. * ``` kotlin * @foo This is code block. @@ -11,4 +17,4 @@ * @foo This is yet more text. * ``` * @foo This is an unclosed code block. - */ \ No newline at end of file + */ diff --git a/compiler/testData/kdoc/lexer/codeBlocks.txt b/compiler/testData/kdoc/lexer/codeBlocks.txt index 142a8a4856a..28e040d64a3 100644 --- a/compiler/testData/kdoc/lexer/codeBlocks.txt +++ b/compiler/testData/kdoc/lexer/codeBlocks.txt @@ -7,6 +7,30 @@ WHITE_SPACE (' ') KDOC_TEXT ('This is text.') WHITE_SPACE ('\n ') KDOC_LEADING_ASTERISK ('*') +KDOC_CODE_BLOCK_TEXT (' This is indented code block') +WHITE_SPACE ('\n ') +KDOC_LEADING_ASTERISK ('*') +KDOC_CODE_BLOCK_TEXT (' Second line of code block') +WHITE_SPACE ('\n ') +KDOC_LEADING_ASTERISK ('*') +KDOC_TEXT (' ') +KDOC_TAG_NAME ('@foo') +WHITE_SPACE (' ') +KDOC_TEXT ('This is text.') +WHITE_SPACE ('\n ') +KDOC_LEADING_ASTERISK ('*') +KDOC_CODE_BLOCK_TEXT (' Tabulated code block') +WHITE_SPACE ('\n ') +KDOC_LEADING_ASTERISK ('*') +KDOC_CODE_BLOCK_TEXT (' Tabulated second line') +WHITE_SPACE ('\n ') +KDOC_LEADING_ASTERISK ('*') +KDOC_TEXT (' ') +KDOC_TAG_NAME ('@foo') +WHITE_SPACE (' ') +KDOC_TEXT ('This is text.') +WHITE_SPACE ('\n ') +KDOC_LEADING_ASTERISK ('*') KDOC_TEXT (' ``` kotlin') WHITE_SPACE ('\n ') KDOC_LEADING_ASTERISK ('*') @@ -47,4 +71,5 @@ WHITE_SPACE ('\n ') KDOC_LEADING_ASTERISK ('*') KDOC_CODE_BLOCK_TEXT (' @foo This is an unclosed code block.') WHITE_SPACE ('\n ') -KDOC_END ('*/') \ No newline at end of file +KDOC_TEXT ('*/') +WHITE_SPACE ('\n') \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt b/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt index 250e84914a1..06c9aaeffa5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/kdoc/KDocRenderer.kt @@ -194,7 +194,6 @@ object KDocRenderer { } } MarkdownTokenTypes.TEXT, - MarkdownTokenTypes.CODE_LINE, MarkdownTokenTypes.WHITE_SPACE, MarkdownTokenTypes.COLON, MarkdownTokenTypes.SINGLE_QUOTE, @@ -206,6 +205,9 @@ object KDocRenderer { MarkdownTokenTypes.EXCLAMATION_MARK -> { sb.append(nodeText) } + MarkdownTokenTypes.CODE_LINE -> { + sb.append(nodeText.removePrefix(KDocTag.indentationWhiteSpaces).htmlEscape()) + } MarkdownTokenTypes.CODE_FENCE_CONTENT -> { sb.append(nodeText.htmlEscape()) } diff --git a/idea/testData/editor/quickDoc/IndentedCodeBlock.kt b/idea/testData/editor/quickDoc/IndentedCodeBlock.kt new file mode 100644 index 00000000000..76e22368692 --- /dev/null +++ b/idea/testData/editor/quickDoc/IndentedCodeBlock.kt @@ -0,0 +1,22 @@ +/** + * val a = A() + * println(a) // comment + * ``` + * Code_block + * ``` + * val b = B() + * println(b) + * some text content + * + * Indented code block with tab + * Second line + */ +class A + +//INFO: public final class A defined in root package
val a = A()
+//INFO: println(a) // comment

+//INFO: <fenced>Code_block</fenced>
+//INFO: 
val b = B()
+//INFO: println(b)

some text content

+//INFO:
Indented code block with tab
+//INFO: 	Second line
diff --git a/idea/tests/org/jetbrains/kotlin/idea/editor/quickDoc/QuickDocProviderTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/editor/quickDoc/QuickDocProviderTestGenerated.java index 2bfec0700d0..b08c14c2211 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/editor/quickDoc/QuickDocProviderTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/editor/quickDoc/QuickDocProviderTestGenerated.java @@ -84,6 +84,12 @@ public class QuickDocProviderTestGenerated extends AbstractQuickDocProviderTest doTest(fileName); } + @TestMetadata("IndentedCodeBlock.kt") + public void testIndentedCodeBlock() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/editor/quickDoc/IndentedCodeBlock.kt"); + doTest(fileName); + } + @TestMetadata("JavaClassUsedInKotlin.kt") public void testJavaClassUsedInKotlin() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/editor/quickDoc/JavaClassUsedInKotlin.kt");