diff options
30 files changed, 749 insertions, 514 deletions
diff --git a/.idea/runConfigurations/All_tests.xml b/.idea/runConfigurations/All_tests.xml index 4e7c9c09..deb51b1a 100644 --- a/.idea/runConfigurations/All_tests.xml +++ b/.idea/runConfigurations/All_tests.xml @@ -23,8 +23,14 @@ <option name="TRANSPORT" value="0" /> <option name="LOCAL" value="true" /> </RunnerSettings> + <RunnerSettings RunnerId="Debug"> + <option name="DEBUG_PORT" value="" /> + <option name="TRANSPORT" value="0" /> + <option name="LOCAL" value="true" /> + </RunnerSettings> <RunnerSettings RunnerId="Run" /> <ConfigurationWrapper RunnerId="Debug" /> + <ConfigurationWrapper RunnerId="Debug" /> <ConfigurationWrapper RunnerId="Run" /> <method /> </configuration> diff --git a/gen/org/jetbrains/markdown/MarkdownElementTypes.java b/gen/org/jetbrains/markdown/MarkdownElementTypes.java index 757cc62f..8c2d77ba 100644 --- a/gen/org/jetbrains/markdown/MarkdownElementTypes.java +++ b/gen/org/jetbrains/markdown/MarkdownElementTypes.java @@ -6,7 +6,9 @@ import org.jetbrains.dokka.Markdown.MarkdownTokenType; public interface MarkdownElementTypes { + IElementType ANONYMOUS_SECTION = new IElementType("ANONYMOUS_SECTION", null); IElementType BLANK_LINE = new IElementType("BLANK_LINE", null); + IElementType BLOCK = new IElementType("BLOCK", null); IElementType BULLET = new IElementType("BULLET", null); IElementType BULLET_LIST = new IElementType("BULLET_LIST", null); IElementType EMPH = new IElementType("EMPH", null); @@ -14,22 +16,22 @@ public interface MarkdownElementTypes { IElementType ENUMERATOR = new IElementType("ENUMERATOR", null); IElementType HORIZONTAL_RULE = new IElementType("HORIZONTAL_RULE", null); IElementType HREF = new IElementType("HREF", null); - IElementType INDENTED_LINE = new IElementType("INDENTED_LINE", null); + IElementType INLINE = new IElementType("INLINE", null); IElementType LINK = new IElementType("LINK", null); IElementType LIST_BLOCK = new IElementType("LIST_BLOCK", null); IElementType LIST_BLOCK_LINE = new IElementType("LIST_BLOCK_LINE", null); IElementType LIST_CONTINUATION_BLOCK = new IElementType("LIST_CONTINUATION_BLOCK", null); IElementType LIST_ITEM = new IElementType("LIST_ITEM", null); - IElementType NONBLANK_INDENTED_LINE = new IElementType("NONBLANK_INDENTED_LINE", null); + IElementType NAMED_SECTION = new IElementType("NAMED_SECTION", null); IElementType ORDERED_LIST = new IElementType("ORDERED_LIST", null); IElementType PARA = new IElementType("PARA", null); IElementType PLAIN_TEXT = new IElementType("PLAIN_TEXT", null); + IElementType SECTION_BODY = new IElementType("SECTION_BODY", null); + IElementType SECTION_NAME = new IElementType("SECTION_NAME", null); IElementType STRONG = new IElementType("STRONG", null); IElementType STRONG_STAR = new IElementType("STRONG_STAR", null); IElementType STRONG_UNDERSCORE = new IElementType("STRONG_UNDERSCORE", null); IElementType TARGET = new IElementType("TARGET", null); - IElementType VERBATIM = new IElementType("VERBATIM", null); - IElementType VERBATIM_ITEM = new IElementType("VERBATIM_ITEM", null); IElementType WHITESPACE = new IElementType("WHITESPACE", null); IElementType ANYCHAR = new MarkdownTokenType("AnyChar"); diff --git a/gen/org/jetbrains/markdown/MarkdownParser.java b/gen/org/jetbrains/markdown/MarkdownParser.java index 90c69985..09c4a0f9 100644 --- a/gen/org/jetbrains/markdown/MarkdownParser.java +++ b/gen/org/jetbrains/markdown/MarkdownParser.java @@ -22,9 +22,15 @@ public class MarkdownParser implements PsiParser { boolean result_; builder_ = adapt_builder_(root_, builder_, this, null); Marker marker_ = enter_section_(builder_, 0, _COLLAPSE_, null); - if (root_ == BLANK_LINE) { + if (root_ == ANONYMOUS_SECTION) { + result_ = AnonymousSection(builder_, 0); + } + else if (root_ == BLANK_LINE) { result_ = BlankLine(builder_, 0); } + else if (root_ == BLOCK) { + result_ = Block(builder_, 0); + } else if (root_ == BULLET) { result_ = Bullet(builder_, 0); } @@ -46,8 +52,8 @@ public class MarkdownParser implements PsiParser { else if (root_ == HREF) { result_ = Href(builder_, 0); } - else if (root_ == INDENTED_LINE) { - result_ = IndentedLine(builder_, 0); + else if (root_ == INLINE) { + result_ = Inline(builder_, 0); } else if (root_ == LINK) { result_ = Link(builder_, 0); @@ -64,8 +70,8 @@ public class MarkdownParser implements PsiParser { else if (root_ == LIST_ITEM) { result_ = ListItem(builder_, 0); } - else if (root_ == NONBLANK_INDENTED_LINE) { - result_ = NonblankIndentedLine(builder_, 0); + else if (root_ == NAMED_SECTION) { + result_ = NamedSection(builder_, 0); } else if (root_ == ORDERED_LIST) { result_ = OrderedList(builder_, 0); @@ -76,6 +82,12 @@ public class MarkdownParser implements PsiParser { else if (root_ == PLAIN_TEXT) { result_ = PlainText(builder_, 0); } + else if (root_ == SECTION_BODY) { + result_ = SectionBody(builder_, 0); + } + else if (root_ == SECTION_NAME) { + result_ = SectionName(builder_, 0); + } else if (root_ == STRONG) { result_ = Strong(builder_, 0); } @@ -88,12 +100,6 @@ public class MarkdownParser implements PsiParser { else if (root_ == TARGET) { result_ = Target(builder_, 0); } - else if (root_ == VERBATIM) { - result_ = Verbatim(builder_, 0); - } - else if (root_ == VERBATIM_ITEM) { - result_ = VerbatimItem(builder_, 0); - } else if (root_ == WHITESPACE) { result_ = Whitespace(builder_, 0); } @@ -108,6 +114,17 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ + // SectionBody + public static boolean AnonymousSection(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "AnonymousSection")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_, level_, _NONE_, "<anonymous section>"); + result_ = SectionBody(builder_, level_ + 1); + exit_section_(builder_, level_, marker_, ANONYMOUS_SECTION, result_, false, null); + return result_; + } + + /* ********************************************************** */ // OptionalSpace Newline public static boolean BlankLine(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "BlankLine")) return false; @@ -122,19 +139,18 @@ public class MarkdownParser implements PsiParser { /* ********************************************************** */ // BlankLine* ( - // Para - // | Verbatim - // | OrderedList - // | BulletList - // | Inlines - // ) - static boolean Block(PsiBuilder builder_, int level_) { + // OrderedList + // | BulletList + // | HorizontalRule + // | Para + // ) + public static boolean Block(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Block")) return false; boolean result_; - Marker marker_ = enter_section_(builder_); + Marker marker_ = enter_section_(builder_, level_, _NONE_, "<block>"); result_ = Block_0(builder_, level_ + 1); result_ = result_ && Block_1(builder_, level_ + 1); - exit_section_(builder_, marker_, null, result_); + exit_section_(builder_, level_, marker_, BLOCK, result_, false, null); return result_; } @@ -150,20 +166,18 @@ public class MarkdownParser implements PsiParser { return true; } - // Para - // | Verbatim - // | OrderedList - // | BulletList - // | Inlines + // OrderedList + // | BulletList + // | HorizontalRule + // | Para private static boolean Block_1(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Block_1")) return false; boolean result_; Marker marker_ = enter_section_(builder_); - result_ = Para(builder_, level_ + 1); - if (!result_) result_ = Verbatim(builder_, level_ + 1); - if (!result_) result_ = OrderedList(builder_, level_ + 1); + result_ = OrderedList(builder_, level_ + 1); if (!result_) result_ = BulletList(builder_, level_ + 1); - if (!result_) result_ = Inlines(builder_, level_ + 1); + if (!result_) result_ = HorizontalRule(builder_, level_ + 1); + if (!result_) result_ = Para(builder_, level_ + 1); exit_section_(builder_, marker_, null, result_); return result_; } @@ -243,13 +257,15 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ - // BOM? ( Block )* + // BOM? Whitespace* AnonymousSection? (Whitespace* NamedSection)* static boolean Document(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Document")) return false; boolean result_; Marker marker_ = enter_section_(builder_); result_ = Document_0(builder_, level_ + 1); result_ = result_ && Document_1(builder_, level_ + 1); + result_ = result_ && Document_2(builder_, level_ + 1); + result_ = result_ && Document_3(builder_, level_ + 1); exit_section_(builder_, marker_, null, result_); return result_; } @@ -261,28 +277,60 @@ public class MarkdownParser implements PsiParser { return true; } - // ( Block )* + // Whitespace* private static boolean Document_1(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Document_1")) return false; int pos_ = current_position_(builder_); while (true) { - if (!Document_1_0(builder_, level_ + 1)) break; + if (!Whitespace(builder_, level_ + 1)) break; if (!empty_element_parsed_guard_(builder_, "Document_1", pos_)) break; pos_ = current_position_(builder_); } return true; } - // ( Block ) - private static boolean Document_1_0(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "Document_1_0")) return false; + // AnonymousSection? + private static boolean Document_2(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "Document_2")) return false; + AnonymousSection(builder_, level_ + 1); + return true; + } + + // (Whitespace* NamedSection)* + private static boolean Document_3(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "Document_3")) return false; + int pos_ = current_position_(builder_); + while (true) { + if (!Document_3_0(builder_, level_ + 1)) break; + if (!empty_element_parsed_guard_(builder_, "Document_3", pos_)) break; + pos_ = current_position_(builder_); + } + return true; + } + + // Whitespace* NamedSection + private static boolean Document_3_0(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "Document_3_0")) return false; boolean result_; Marker marker_ = enter_section_(builder_); - result_ = Block(builder_, level_ + 1); + result_ = Document_3_0_0(builder_, level_ + 1); + result_ = result_ && NamedSection(builder_, level_ + 1); exit_section_(builder_, marker_, null, result_); return result_; } + // Whitespace* + private static boolean Document_3_0_0(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "Document_3_0_0")) return false; + int pos_ = current_position_(builder_); + while (true) { + if (!Whitespace(builder_, level_ + 1)) break; + if (!empty_element_parsed_guard_(builder_, "Document_3_0_0", pos_)) break; + pos_ = current_position_(builder_); + } + return true; + } + /* ********************************************************** */ // EmphStar | EmphUnderscore public static boolean Emph(PsiBuilder builder_, int level_) { @@ -663,28 +711,16 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ - // Indent PlainText - public static boolean IndentedLine(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "IndentedLine")) return false; - boolean result_; - Marker marker_ = enter_section_(builder_, level_, _NONE_, "<indented line>"); - result_ = Indent(builder_, level_ + 1); - result_ = result_ && PlainText(builder_, level_ + 1); - exit_section_(builder_, level_, marker_, INDENTED_LINE, result_, false, null); - return result_; - } - - /* ********************************************************** */ // Strong | Emph | Link | PlainText - static boolean Inline(PsiBuilder builder_, int level_) { + public static boolean Inline(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Inline")) return false; boolean result_; - Marker marker_ = enter_section_(builder_); + Marker marker_ = enter_section_(builder_, level_, _NONE_, "<inline>"); result_ = Strong(builder_, level_ + 1); if (!result_) result_ = Emph(builder_, level_ + 1); if (!result_) result_ = Link(builder_, level_ + 1); if (!result_) result_ = PlainText(builder_, level_ + 1); - exit_section_(builder_, marker_, null, result_); + exit_section_(builder_, level_, marker_, INLINE, result_, false, null); return result_; } @@ -1052,24 +1088,14 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ - // !BlankLine IndentedLine - public static boolean NonblankIndentedLine(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "NonblankIndentedLine")) return false; + // SectionHeader SectionBody + public static boolean NamedSection(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "NamedSection")) return false; boolean result_; - Marker marker_ = enter_section_(builder_, level_, _NONE_, "<nonblank indented line>"); - result_ = NonblankIndentedLine_0(builder_, level_ + 1); - result_ = result_ && IndentedLine(builder_, level_ + 1); - exit_section_(builder_, level_, marker_, NONBLANK_INDENTED_LINE, result_, false, null); - return result_; - } - - // !BlankLine - private static boolean NonblankIndentedLine_0(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "NonblankIndentedLine_0")) return false; - boolean result_; - Marker marker_ = enter_section_(builder_, level_, _NOT_, null); - result_ = !BlankLine(builder_, level_ + 1); - exit_section_(builder_, level_, marker_, null, result_, false, null); + Marker marker_ = enter_section_(builder_, level_, _NONE_, "<named section>"); + result_ = SectionHeader(builder_, level_ + 1); + result_ = result_ && SectionBody(builder_, level_ + 1); + exit_section_(builder_, level_, marker_, NAMED_SECTION, result_, false, null); return result_; } @@ -1094,22 +1120,21 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ - // OptionalSpace Newline !BlankLine + // Newline !BlankLine static boolean NormalEndline(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "NormalEndline")) return false; - if (!nextTokenIs(builder_, "", NEWLINE, SPACECHAR)) return false; + if (!nextTokenIs(builder_, NEWLINE)) return false; boolean result_; Marker marker_ = enter_section_(builder_); - result_ = OptionalSpace(builder_, level_ + 1); - result_ = result_ && consumeToken(builder_, NEWLINE); - result_ = result_ && NormalEndline_2(builder_, level_ + 1); + result_ = consumeToken(builder_, NEWLINE); + result_ = result_ && NormalEndline_1(builder_, level_ + 1); exit_section_(builder_, marker_, null, result_); return result_; } // !BlankLine - private static boolean NormalEndline_2(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "NormalEndline_2")) return false; + private static boolean NormalEndline_1(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "NormalEndline_1")) return false; boolean result_; Marker marker_ = enter_section_(builder_, level_, _NOT_, null); result_ = !BlankLine(builder_, level_ + 1); @@ -1153,21 +1178,27 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ - // NonindentSpace Inlines (BlankLine | TerminalEndline) + // Inlines (BlankLine | TerminalEndline)? public static boolean Para(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Para")) return false; boolean result_; Marker marker_ = enter_section_(builder_, level_, _NONE_, "<para>"); - result_ = NonindentSpace(builder_, level_ + 1); - result_ = result_ && Inlines(builder_, level_ + 1); - result_ = result_ && Para_2(builder_, level_ + 1); + result_ = Inlines(builder_, level_ + 1); + result_ = result_ && Para_1(builder_, level_ + 1); exit_section_(builder_, level_, marker_, PARA, result_, false, null); return result_; } + // (BlankLine | TerminalEndline)? + private static boolean Para_1(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "Para_1")) return false; + Para_1_0(builder_, level_ + 1); + return true; + } + // BlankLine | TerminalEndline - private static boolean Para_2(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "Para_2")) return false; + private static boolean Para_1_0(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "Para_1_0")) return false; boolean result_; Marker marker_ = enter_section_(builder_); result_ = BlankLine(builder_, level_ + 1); @@ -1177,7 +1208,7 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ - // (String | Number | Spacechar)+ + // (String | Number | Spacechar+)+ public static boolean PlainText(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "PlainText")) return false; boolean result_; @@ -1193,14 +1224,30 @@ public class MarkdownParser implements PsiParser { return result_; } - // String | Number | Spacechar + // String | Number | Spacechar+ private static boolean PlainText_0(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "PlainText_0")) return false; boolean result_; Marker marker_ = enter_section_(builder_); result_ = consumeToken(builder_, STRING); if (!result_) result_ = consumeToken(builder_, NUMBER); - if (!result_) result_ = consumeToken(builder_, SPACECHAR); + if (!result_) result_ = PlainText_0_2(builder_, level_ + 1); + exit_section_(builder_, marker_, null, result_); + return result_; + } + + // Spacechar+ + private static boolean PlainText_0_2(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "PlainText_0_2")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_); + result_ = consumeToken(builder_, SPACECHAR); + int pos_ = current_position_(builder_); + while (result_) { + if (!consumeToken(builder_, SPACECHAR)) break; + if (!empty_element_parsed_guard_(builder_, "PlainText_0_2", pos_)) break; + pos_ = current_position_(builder_); + } exit_section_(builder_, marker_, null, result_); return result_; } @@ -1219,17 +1266,95 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ + // Block* + public static boolean SectionBody(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "SectionBody")) return false; + Marker marker_ = enter_section_(builder_, level_, _NONE_, "<section body>"); + int pos_ = current_position_(builder_); + while (true) { + if (!Block(builder_, level_ + 1)) break; + if (!empty_element_parsed_guard_(builder_, "SectionBody", pos_)) break; + pos_ = current_position_(builder_); + } + exit_section_(builder_, level_, marker_, SECTION_BODY, true, false, null); + return true; + } + + /* ********************************************************** */ + // '$' SectionName OptionalSpace ':' OptionalSpace + static boolean SectionHeader(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "SectionHeader")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_); + result_ = consumeToken(builder_, "$"); + result_ = result_ && SectionName(builder_, level_ + 1); + result_ = result_ && OptionalSpace(builder_, level_ + 1); + result_ = result_ && consumeToken(builder_, ":"); + result_ = result_ && OptionalSpace(builder_, level_ + 1); + exit_section_(builder_, marker_, null, result_); + return result_; + } + + /* ********************************************************** */ + // SectionNameStart | '{' OptionalSpace SectionNameStart (Spacechar+ String)* OptionalSpace '}' + public static boolean SectionName(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "SectionName")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_, level_, _NONE_, "<section name>"); + result_ = SectionNameStart(builder_, level_ + 1); + if (!result_) result_ = SectionName_1(builder_, level_ + 1); + exit_section_(builder_, level_, marker_, SECTION_NAME, result_, false, null); + return result_; + } + + // '{' OptionalSpace SectionNameStart (Spacechar+ String)* OptionalSpace '}' + private static boolean SectionName_1(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "SectionName_1")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_); + result_ = consumeToken(builder_, "{"); + result_ = result_ && OptionalSpace(builder_, level_ + 1); + result_ = result_ && SectionNameStart(builder_, level_ + 1); + result_ = result_ && SectionName_1_3(builder_, level_ + 1); + result_ = result_ && OptionalSpace(builder_, level_ + 1); + result_ = result_ && consumeToken(builder_, "}"); + exit_section_(builder_, marker_, null, result_); + return result_; + } + + // (Spacechar+ String)* + private static boolean SectionName_1_3(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "SectionName_1_3")) return false; + int pos_ = current_position_(builder_); + while (true) { + if (!SectionName_1_3_0(builder_, level_ + 1)) break; + if (!empty_element_parsed_guard_(builder_, "SectionName_1_3", pos_)) break; + pos_ = current_position_(builder_); + } + return true; + } + + // Spacechar+ String + private static boolean SectionName_1_3_0(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "SectionName_1_3_0")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_); + result_ = SectionName_1_3_0_0(builder_, level_ + 1); + result_ = result_ && consumeToken(builder_, STRING); + exit_section_(builder_, marker_, null, result_); + return result_; + } + // Spacechar+ - static boolean RequiredSpace(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "RequiredSpace")) return false; - if (!nextTokenIs(builder_, SPACECHAR)) return false; + private static boolean SectionName_1_3_0_0(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "SectionName_1_3_0_0")) return false; boolean result_; Marker marker_ = enter_section_(builder_); result_ = consumeToken(builder_, SPACECHAR); int pos_ = current_position_(builder_); while (result_) { if (!consumeToken(builder_, SPACECHAR)) break; - if (!empty_element_parsed_guard_(builder_, "RequiredSpace", pos_)) break; + if (!empty_element_parsed_guard_(builder_, "SectionName_1_3_0_0", pos_)) break; pos_ = current_position_(builder_); } exit_section_(builder_, marker_, null, result_); @@ -1237,6 +1362,25 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ + // '$'? String + static boolean SectionNameStart(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "SectionNameStart")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_); + result_ = SectionNameStart_0(builder_, level_ + 1); + result_ = result_ && consumeToken(builder_, STRING); + exit_section_(builder_, marker_, null, result_); + return result_; + } + + // '$'? + private static boolean SectionNameStart_0(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "SectionNameStart_0")) return false; + consumeToken(builder_, "$"); + return true; + } + + /* ********************************************************** */ // StrongStar | StrongUnderscore public static boolean Strong(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Strong")) return false; @@ -1383,34 +1527,11 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ - // (OptionalSpace Newline <<eof>>) | (OptionalSpace <<eof>>) + // OptionalSpace <<eof>> static boolean TerminalEndline(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "TerminalEndline")) return false; boolean result_; Marker marker_ = enter_section_(builder_); - result_ = TerminalEndline_0(builder_, level_ + 1); - if (!result_) result_ = TerminalEndline_1(builder_, level_ + 1); - exit_section_(builder_, marker_, null, result_); - return result_; - } - - // OptionalSpace Newline <<eof>> - private static boolean TerminalEndline_0(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "TerminalEndline_0")) return false; - boolean result_; - Marker marker_ = enter_section_(builder_); - result_ = OptionalSpace(builder_, level_ + 1); - result_ = result_ && consumeToken(builder_, NEWLINE); - result_ = result_ && eof(builder_, level_ + 1); - exit_section_(builder_, marker_, null, result_); - return result_; - } - - // OptionalSpace <<eof>> - private static boolean TerminalEndline_1(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "TerminalEndline_1")) return false; - boolean result_; - Marker marker_ = enter_section_(builder_); result_ = OptionalSpace(builder_, level_ + 1); result_ = result_ && eof(builder_, level_ + 1); exit_section_(builder_, marker_, null, result_); @@ -1418,47 +1539,6 @@ public class MarkdownParser implements PsiParser { } /* ********************************************************** */ - // VerbatimItem+ - public static boolean Verbatim(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "Verbatim")) return false; - boolean result_; - Marker marker_ = enter_section_(builder_, level_, _NONE_, "<verbatim>"); - result_ = VerbatimItem(builder_, level_ + 1); - int pos_ = current_position_(builder_); - while (result_) { - if (!VerbatimItem(builder_, level_ + 1)) break; - if (!empty_element_parsed_guard_(builder_, "Verbatim", pos_)) break; - pos_ = current_position_(builder_); - } - exit_section_(builder_, level_, marker_, VERBATIM, result_, false, null); - return result_; - } - - /* ********************************************************** */ - // BlankLine* NonblankIndentedLine - public static boolean VerbatimItem(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "VerbatimItem")) return false; - boolean result_; - Marker marker_ = enter_section_(builder_, level_, _NONE_, "<verbatim item>"); - result_ = VerbatimItem_0(builder_, level_ + 1); - result_ = result_ && NonblankIndentedLine(builder_, level_ + 1); - exit_section_(builder_, level_, marker_, VERBATIM_ITEM, result_, false, null); - return result_; - } - - // BlankLine* - private static boolean VerbatimItem_0(PsiBuilder builder_, int level_) { - if (!recursion_guard_(builder_, level_, "VerbatimItem_0")) return false; - int pos_ = current_position_(builder_); - while (true) { - if (!BlankLine(builder_, level_ + 1)) break; - if (!empty_element_parsed_guard_(builder_, "VerbatimItem_0", pos_)) break; - pos_ = current_position_(builder_); - } - return true; - } - - /* ********************************************************** */ // Spacechar | Newline public static boolean Whitespace(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "Whitespace")) return false; diff --git a/src/Markdown/_MarkdownLexer.flex b/gen/org/jetbrains/markdown/lexer/_MarkdownLexer.flex index 0a15e41a..f5aab899 100644 --- a/src/Markdown/_MarkdownLexer.flex +++ b/gen/org/jetbrains/markdown/lexer/_MarkdownLexer.flex @@ -22,7 +22,7 @@ import static org.jetbrains.markdown.MarkdownElementTypes.*; Newline="\r"|"\n"|"\r\n" Spacechar=[\ \t\f] Number=[0-9]+(\.[0-9]*)? -String=[^~\*_`&\[\]()<!#\\ \t\n\r]+ +String=[^~:{}$\*_`&\[\]()<!#\\ \t\n\r]+ AnyChar=. Line=!'\r' !'\n' .* {Newline} @@ -32,8 +32,10 @@ Line=!'\r' !'\n' .* {Newline} {Newline} { return NEWLINE; } "\\357\\273\\277" { return BOM; } + {Number} { return NUMBER; } {String} { return STRING; } + {AnyChar} { return ANYCHAR; } [^] { return com.intellij.psi.TokenType.BAD_CHARACTER; } diff --git a/gen/org/jetbrains/markdown/lexer/_MarkdownLexer.java b/gen/org/jetbrains/markdown/lexer/_MarkdownLexer.java index 0052e3ea..c84a83d8 100644 --- a/gen/org/jetbrains/markdown/lexer/_MarkdownLexer.java +++ b/gen/org/jetbrains/markdown/lexer/_MarkdownLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 9/25/14 10:26 PM */ +/* The following code was generated by JFlex 1.4.3 on 9/29/14 3:24 PM */ package org.jetbrains.markdown.lexer; @@ -10,8 +10,8 @@ import static org.jetbrains.markdown.MarkdownElementTypes.*; /** * This class is a scanner generated by * <a href="http://www.jflex.de/">JFlex</a> 1.4.3 - * on 9/25/14 10:26 PM from the specification file - * <tt>/Users/orangy/Projects/dokka/src/Markdown/_MarkdownLexer.flex</tt> + * on 9/29/14 3:24 PM from the specification file + * <tt>/Users/orangy/Projects/dokka/gen/org/jetbrains/markdown/lexer/_MarkdownLexer.flex</tt> */ public class _MarkdownLexer implements FlexLexer { /** initial size of the lookahead buffer */ @@ -35,9 +35,9 @@ public class _MarkdownLexer implements FlexLexer { */ private static final String ZZ_CMAP_PACKED = "\11\0\1\7\1\2\1\0\1\3\1\1\22\0\1\7\1\6\1\0"+ - "\1\6\2\0\1\6\1\0\3\6\3\0\1\5\1\0\2\4\1\14"+ - "\1\11\1\4\1\12\1\4\1\13\2\4\2\0\1\6\36\0\1\6"+ - "\1\10\1\6\1\0\2\6\35\0\1\6\uff81\0"; + "\2\6\1\0\1\6\1\0\3\6\3\0\1\5\1\0\2\4\1\14"+ + "\1\11\1\4\1\12\1\4\1\13\2\4\1\6\1\0\1\6\36\0"+ + "\1\6\1\10\1\6\1\0\2\6\32\0\1\6\1\0\2\6\uff81\0"; /** * Translates characters to character classes @@ -245,7 +245,7 @@ public class _MarkdownLexer implements FlexLexer { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 74) { + while (i < 80) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); diff --git a/src/Analysis/CommentsAPI.kt b/src/Analysis/CommentsAPI.kt index 5df4bd38..a17b6aa4 100644 --- a/src/Analysis/CommentsAPI.kt +++ b/src/Analysis/CommentsAPI.kt @@ -31,5 +31,5 @@ fun KDoc?.extractText(): String { comment.substring(0, comment.length - 2) else comment).trim() - }.filter { it.any() }.join("\n") + }.join("\n") }
\ No newline at end of file diff --git a/src/Formats/MarkdownFormatService.kt b/src/Formats/MarkdownFormatService.kt index d7530a25..3b87835f 100644 --- a/src/Formats/MarkdownFormatService.kt +++ b/src/Formats/MarkdownFormatService.kt @@ -16,10 +16,6 @@ public open class MarkdownFormatService(locationService: LocationService, return text.htmlEscape() } - override public fun formatText(text: RichString): String { - return text.toString().htmlEscape() - } - override public fun formatCode(code: String): String { return "`$code`" } diff --git a/src/Formats/StructuredFormatService.kt b/src/Formats/StructuredFormatService.kt index 0c58f553..b1e614f6 100644 --- a/src/Formats/StructuredFormatService.kt +++ b/src/Formats/StructuredFormatService.kt @@ -28,19 +28,17 @@ public abstract class StructuredFormatService(val locationService: LocationServi public abstract fun formatCode(code: String): String public abstract fun formatBreadcrumbs(items: Iterable<FormatLink>): String - open fun formatText(text: RichString): String { + open fun formatText(nodes: Iterable<ContentNode>): String { + return nodes.map { formatText(it) }.join("") + } + + open fun formatText(text: ContentNode): String { return StringBuilder { - for (slice in text.slices) { - val style = slice.style - when (style) { - is NormalStyle -> append(slice.text) - is BoldStyle -> append(formatBold(slice.text)) - is CodeStyle -> append(formatCode(slice.text)) - is LinkStyle -> { - val node = resolutionService.resolve(style.link) - val location = locationService.location(node) - append(formatLink(slice.text, location)) - } + for (node in text.children) { + when (node) { + is ContentText -> append(node.text) + is ContentEmphasis -> append(formatBold(formatText(node.children))) + else -> append(formatText(node.children)) } } }.toString() @@ -67,7 +65,7 @@ public abstract class StructuredFormatService(val locationService: LocationServi if (label.startsWith("$")) continue appendLine(to, formatBold(formatText(label))) - appendLine(to, formatText(section.text)) + appendLine(to, formatText(section)) appendLine(to) } } diff --git a/src/Formats/TextFormatService.kt b/src/Formats/TextFormatService.kt index 77a0bb65..8fea5a6a 100644 --- a/src/Formats/TextFormatService.kt +++ b/src/Formats/TextFormatService.kt @@ -9,12 +9,9 @@ public class TextFormatService(val signatureGenerator: LanguageService) : Format appendln(signatureGenerator.render(node)) appendln() appendln(node.doc.summary) - for (n in 0..node.doc.summary.length()) - append("=") for ((label,section) in node.doc.sections) { appendln(label) - appendln(section.text) } } } diff --git a/src/Kotlin/ContentBuilder.kt b/src/Kotlin/ContentBuilder.kt new file mode 100644 index 00000000..78bd7eaf --- /dev/null +++ b/src/Kotlin/ContentBuilder.kt @@ -0,0 +1,79 @@ +package org.jetbrains.dokka + +import org.jetbrains.markdown.MarkdownElementTypes +import java.util.ArrayDeque + +public fun MarkdownTree.toContent(): Content { + val nodeStack = ArrayDeque<ContentNode>() + nodeStack.push(Content()) + + visit {(node, text, processChildren) -> + val parent = nodeStack.peek()!! + val nodeType = node.getTokenType() + val nodeText = getNodeText(node) + when (nodeType) { + MarkdownElementTypes.BULLET_LIST -> { + nodeStack.push(ContentList()) + processChildren() + parent.children.add(nodeStack.pop()) + } + MarkdownElementTypes.ORDERED_LIST -> { + nodeStack.push(ContentList()) // TODO: add list kind + processChildren() + parent.children.add(nodeStack.pop()) + } + MarkdownElementTypes.HORIZONTAL_RULE -> { + } + MarkdownElementTypes.LIST_BLOCK -> { + nodeStack.push(ContentBlock()) + processChildren() + parent.children.add(nodeStack.pop()) + } + MarkdownElementTypes.EMPH -> { + nodeStack.push(ContentEmphasis()) + processChildren() + parent.children.add(nodeStack.pop()) + } + MarkdownElementTypes.STRONG -> { + nodeStack.push(ContentStrong()) + processChildren() + parent.children.add(nodeStack.pop()) + } + MarkdownElementTypes.ANONYMOUS_SECTION -> { + nodeStack.push(ContentSection("")) + processChildren() + parent.children.add(nodeStack.pop()) + } + MarkdownElementTypes.NAMED_SECTION -> { + val label = findChildByType(node, MarkdownElementTypes.SECTION_NAME)?.let { getNodeText(it) } ?: "" + nodeStack.push(ContentSection(label)) + processChildren() + parent.children.add(nodeStack.pop()) + } + MarkdownElementTypes.PLAIN_TEXT -> { + nodeStack.push(ContentText(nodeText)) + processChildren() + parent.children.add(nodeStack.pop()) + } + MarkdownElementTypes.END_LINE -> { + nodeStack.push(ContentText(nodeText)) + processChildren() + parent.children.add(nodeStack.pop()) + } + MarkdownElementTypes.BLANK_LINE -> { + processChildren() + } + MarkdownElementTypes.PARA -> { + nodeStack.push(ContentBlock()) + processChildren() + parent.children.add(nodeStack.pop()) + } + else -> { + processChildren() + } + } + } + return nodeStack.pop() as Content +} + + diff --git a/src/Model/Diagnostics.kt b/src/Kotlin/Diagnostics.kt index 1077da7c..5548bc01 100644 --- a/src/Model/Diagnostics.kt +++ b/src/Kotlin/Diagnostics.kt @@ -4,11 +4,11 @@ import org.jetbrains.jet.lang.descriptors.* import org.jetbrains.jet.lang.resolve.name.* import org.jetbrains.jet.lang.resolve.BindingContext -fun BindingContext.checkResolveChildren(node: DocumentationNode) { +fun DocumentationContext.checkResolveChildren(node: DocumentationNode) { if (node.kind != DocumentationNode.Kind.Module && node.kind != DocumentationNode.Kind.Package) { // TODO: we don't resolve packages and modules for now - val parentScope = getResolutionScope(node.descriptor) + val parentScope = getResolutionScope(node) for (item in node.details + node.members) { val symbolName = item.name val symbol: DeclarationDescriptor? = when (item.kind) { diff --git a/src/Model/DocumentationBuildingVisitor.kt b/src/Kotlin/DocumentationBuildingVisitor.kt index 6118b0f5..5654903b 100644 --- a/src/Model/DocumentationBuildingVisitor.kt +++ b/src/Kotlin/DocumentationBuildingVisitor.kt @@ -5,6 +5,7 @@ import org.jetbrains.jet.lang.resolve.name.* import org.jetbrains.jet.lang.resolve.* public data class DocumentationOptions(val includeNonPublic : Boolean = false) + class DocumentationBuildingVisitor(val context: BindingContext, val options: DocumentationOptions, private val worker: DeclarationDescriptorVisitor<DocumentationNode, DocumentationNode>) diff --git a/src/Kotlin/DocumentationContext.kt b/src/Kotlin/DocumentationContext.kt new file mode 100644 index 00000000..1491aa2d --- /dev/null +++ b/src/Kotlin/DocumentationContext.kt @@ -0,0 +1,47 @@ +package org.jetbrains.dokka + +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor +import org.jetbrains.jet.lang.resolve.BindingContext +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor +import org.jetbrains.jet.lang.resolve.name.FqName + +public class DocumentationContext(val bindingContext: BindingContext) { + val descriptorToNode = hashMapOf<DeclarationDescriptor, DocumentationNode>() + val nodeToDescriptor = hashMapOf<DocumentationNode, DeclarationDescriptor>() + + fun register(descriptor: DeclarationDescriptor, node: DocumentationNode) { + descriptorToNode.put(descriptor, node) + nodeToDescriptor.put(node, descriptor) + } + + fun getResolutionScope(node: DocumentationNode): JetScope { + val descriptor = nodeToDescriptor[node] ?: throw IllegalArgumentException("Node is not known to this context") + return bindingContext.getResolutionScope(descriptor) + } + + fun parseDocumentation(descriptor: DeclarationDescriptor): Content { + val docText = bindingContext.getDocumentationElements(descriptor).map { it.extractText() }.join("\n") + val tree = MarkdownProcessor.parse(docText) + println(tree.toTestString()) + val content = tree.toContent() + return content + } +} + +fun BindingContext.createDocumentationModule(name: String, + module: ModuleDescriptor, + packages: Set<FqName>, + options: DocumentationOptions = DocumentationOptions()): DocumentationModule { + val documentationModule = DocumentationModule(name) + val context = DocumentationContext(this) + val visitor = DocumentationNodeBuilder(context) + for (packageName in packages) { + val pkg = module.getPackage(packageName) + pkg!!.accept(DocumentationBuildingVisitor(this, options, visitor), documentationModule) + } + + // TODO: Uncomment for resolve verification + // checkResolveChildren(documentationModule) + return documentationModule +} diff --git a/src/Model/DocumentationNodeBuilder.kt b/src/Kotlin/DocumentationNodeBuilder.kt index f724c444..535f037f 100644 --- a/src/Model/DocumentationNodeBuilder.kt +++ b/src/Kotlin/DocumentationNodeBuilder.kt @@ -1,12 +1,23 @@ package org.jetbrains.dokka -import org.jetbrains.jet.lang.resolve.* -import org.jetbrains.jet.lang.descriptors.* -import org.jetbrains.jet.lang.descriptors.impl.* -import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns +import org.jetbrains.jet.lang.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies +import org.jetbrains.jet.lang.descriptors.MemberDescriptor +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor import org.jetbrains.jet.lang.types.JetType +import org.jetbrains.jet.lang.descriptors.Named +import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor +import org.jetbrains.jet.lang.descriptors.ClassDescriptor +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor +import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor +import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor +import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor +import org.jetbrains.jet.lang.descriptors.ClassKind +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns -class DocumentationNodeBuilder(val context: BindingContext) : DeclarationDescriptorVisitorEmptyBodies<DocumentationNode, DocumentationNode>() { +class DocumentationNodeBuilder(val context: DocumentationContext) : DeclarationDescriptorVisitorEmptyBodies<DocumentationNode, DocumentationNode>() { fun reference(from: DocumentationNode, to: DocumentationNode, kind: DocumentationReference.Kind) { from.addReferenceTo(to, kind) @@ -18,13 +29,13 @@ class DocumentationNodeBuilder(val context: BindingContext) : DeclarationDescrip fun addModality(descriptor: MemberDescriptor, data: DocumentationNode) { val modifier = descriptor.getModality().name().toLowerCase() - val node = DocumentationNode(descriptor, modifier, DocumentationContent.Empty, DocumentationNode.Kind.Modifier) + val node = DocumentationNode(modifier, Content.Empty, DocumentationNode.Kind.Modifier) reference(data, node, DocumentationReference.Kind.Detail) } fun addVisibility(descriptor: MemberDescriptor, data: DocumentationNode) { val modifier = descriptor.getVisibility().toString() - val node = DocumentationNode(descriptor, modifier, DocumentationContent.Empty, DocumentationNode.Kind.Modifier) + val node = DocumentationNode(modifier, Content.Empty, DocumentationNode.Kind.Modifier) reference(data, node, DocumentationReference.Kind.Detail) } @@ -37,7 +48,7 @@ class DocumentationNodeBuilder(val context: BindingContext) : DeclarationDescrip is Named -> classifierDescriptor.getName().asString() else -> "<anonymous>" } - val node = DocumentationNode(descriptor, name, DocumentationContent.Empty, DocumentationNode.Kind.Type) + val node = DocumentationNode(name, Content.Empty, DocumentationNode.Kind.Type) reference(data, node, DocumentationReference.Kind.Detail) for (param in t.getArguments()) @@ -45,14 +56,17 @@ class DocumentationNodeBuilder(val context: BindingContext) : DeclarationDescrip } override fun visitDeclarationDescriptor(descriptor: DeclarationDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!) - val node = DocumentationNode(descriptor, descriptor.getName().asString(), doc, DocumentationNode.Kind.Unknown) + descriptor!! + val doc = context.parseDocumentation(descriptor) + val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Unknown) reference(data!!, node, DocumentationReference.Kind.Link) + context.register(descriptor, node) return node } override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor?, data: DocumentationNode?): DocumentationNode? { - val node = DocumentationNode(descriptor!!, descriptor.getName().asString(), DocumentationContent.Empty, DocumentationNode.Kind.Receiver) + descriptor!! + val node = DocumentationNode(descriptor.getName().asString(), Content.Empty, DocumentationNode.Kind.Receiver) reference(data!!, node, DocumentationReference.Kind.Detail) addType(descriptor, descriptor.getType(), node) @@ -61,8 +75,9 @@ class DocumentationNodeBuilder(val context: BindingContext) : DeclarationDescrip } override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!) - val node = DocumentationNode(descriptor, descriptor.getName().asString(), doc, DocumentationNode.Kind.Parameter) + descriptor!! + val doc = context.parseDocumentation(descriptor) + val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Parameter) reference(data!!, node, DocumentationReference.Kind.Detail) addType(descriptor, descriptor.getType(), node) @@ -71,83 +86,92 @@ class DocumentationNodeBuilder(val context: BindingContext) : DeclarationDescrip } override fun visitClassDescriptor(descriptor: ClassDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!) - val node = DocumentationNode(descriptor, descriptor.getName().asString(), doc, when (descriptor.getKind()) { - ClassKind.OBJECT -> DocumentationNode.Kind.Object - ClassKind.CLASS_OBJECT -> DocumentationNode.Kind.Object - ClassKind.TRAIT -> DocumentationNode.Kind.Interface - ClassKind.ENUM_CLASS -> DocumentationNode.Kind.Enum - ClassKind.ENUM_ENTRY -> DocumentationNode.Kind.EnumItem + descriptor!! + val doc = context.parseDocumentation(descriptor) + val node = DocumentationNode(descriptor.getName().asString(), doc, when (descriptor.getKind()) { + ClassKind.OBJECT -> org.jetbrains.dokka.DocumentationNode.Kind.Object + ClassKind.CLASS_OBJECT -> org.jetbrains.dokka.DocumentationNode.Kind.Object + ClassKind.TRAIT -> org.jetbrains.dokka.DocumentationNode.Kind.Interface + ClassKind.ENUM_CLASS -> org.jetbrains.dokka.DocumentationNode.Kind.Enum + ClassKind.ENUM_ENTRY -> org.jetbrains.dokka.DocumentationNode.Kind.EnumItem else -> DocumentationNode.Kind.Class }) reference(data!!, node, DocumentationReference.Kind.Member) addModality(descriptor, node) addVisibility(descriptor, node) + context.register(descriptor, node) return node } override fun visitFunctionDescriptor(descriptor: FunctionDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!) - val node = DocumentationNode(descriptor, descriptor.getName().asString(), doc, DocumentationNode.Kind.Function) + descriptor!! + val doc = context.parseDocumentation(descriptor) + val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Function) reference(data!!, node, DocumentationReference.Kind.Member) addType(descriptor, descriptor.getReturnType(), node) addModality(descriptor, node) addVisibility(descriptor, node) - + context.register(descriptor, node) return node } override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!) - val node = DocumentationNode(descriptor, descriptor.getName().asString(), doc, DocumentationNode.Kind.TypeParameter) + descriptor!! + val doc = context.parseDocumentation(descriptor) + val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.TypeParameter) reference(data!!, node, DocumentationReference.Kind.Detail) val builtIns = KotlinBuiltIns.getInstance() for (constraint in descriptor.getUpperBounds()) { if (constraint == builtIns.getDefaultBound()) continue - val constraintNode = DocumentationNode(descriptor, constraint.toString(), DocumentationContent.Empty, DocumentationNode.Kind.UpperBound) + val constraintNode = DocumentationNode(constraint.toString(), Content.Empty, DocumentationNode.Kind.UpperBound) reference(node, constraintNode, DocumentationReference.Kind.Detail) } for (constraint in descriptor.getLowerBounds()) { if (builtIns.isNothing(constraint)) continue - val constraintNode = DocumentationNode(descriptor, constraint.toString(), DocumentationContent.Empty, DocumentationNode.Kind.LowerBound) + val constraintNode = DocumentationNode(constraint.toString(), Content.Empty, DocumentationNode.Kind.LowerBound) reference(node, constraintNode, DocumentationReference.Kind.Detail) } return node } override fun visitPropertyDescriptor(descriptor: PropertyDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!) - val node = DocumentationNode(descriptor, descriptor.getName().asString(), doc, DocumentationNode.Kind.Property) + descriptor!! + val doc = context.parseDocumentation(descriptor) + val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Property) reference(data!!, node, DocumentationReference.Kind.Member) addType(descriptor, descriptor.getType(), node) addModality(descriptor, node) addVisibility(descriptor, node) + context.register(descriptor, node) return node } override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor?, data: DocumentationNode?): DocumentationNode? { - val doc = context.getDocumentation(descriptor!!) - val node = DocumentationNode(descriptor, descriptor.getName().asString(), doc, DocumentationNode.Kind.Constructor) + descriptor!! + val doc = context.parseDocumentation(descriptor) + val node = DocumentationNode(descriptor.getName().asString(), doc, DocumentationNode.Kind.Constructor) reference(data!!, node, DocumentationReference.Kind.Member) addVisibility(descriptor, node) - + context.register(descriptor, node) return node } override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor?, data: DocumentationNode?): DocumentationNode? { - val node = DocumentationNode(descriptor!!, descriptor.getFqName().asString(), DocumentationContent.Empty, DocumentationNode.Kind.Package) + descriptor!! + val node = DocumentationNode(descriptor.getFqName().asString(), Content.Empty, DocumentationNode.Kind.Package) reference(data!!, node, DocumentationReference.Kind.Member) return node } override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor?, data: DocumentationNode?): DocumentationNode? { - val node = DocumentationNode(descriptor!!, descriptor.fqName.asString(), DocumentationContent.Empty, DocumentationNode.Kind.Package) + descriptor!! + val node = DocumentationNode(descriptor.fqName.asString(), Content.Empty, DocumentationNode.Kind.Package) reference(data!!, node, DocumentationReference.Kind.Member) return node } -} +}
\ No newline at end of file diff --git a/src/Markdown/MarkdownProcessor.kt b/src/Markdown/MarkdownProcessor.kt index fe6e8436..19d5a8fb 100644 --- a/src/Markdown/MarkdownProcessor.kt +++ b/src/Markdown/MarkdownProcessor.kt @@ -9,12 +9,11 @@ import com.intellij.lang.LighterASTNode import com.intellij.util.diff.FlyweightCapableTreeStructure import com.intellij.openapi.util.Ref import org.jetbrains.markdown.lexer.MarkdownLexer +import com.intellij.psi.tree.IElementType -public class MarkdownProcessor { - class object { - val EXPR_LANGUAGE = object : Language("MARKDOWN") {} - val DOCUMENT = IFileElementType("DOCUMENT", EXPR_LANGUAGE); - } +public object MarkdownProcessor { + val EXPR_LANGUAGE = object : Language("MARKDOWN") {} + val DOCUMENT = IFileElementType("DOCUMENT", EXPR_LANGUAGE); public fun parse(markdown: String): MarkdownTree { val parser = MarkdownParser() @@ -30,6 +29,28 @@ public class MarkdownTree(private val text: String, private val structure: Flywe visit(structure.getRoot(), action) } + fun findChildByType(node: LighterASTNode, findType: IElementType) : LighterASTNode? { + val ref = Ref.create<Array<LighterASTNode>?>() + val count = structure.getChildren(node, ref) + val children = ref.get() + if (children != null) { + for (index in 0..count - 1) { + val child = children[index] + val nodeType = child.getTokenType() + if (nodeType == findType) + return child + val nestedChild = findChildByType(child, findType) + if (nestedChild != null) + return nestedChild + } + } + return null + } + + fun getNodeText(node: LighterASTNode) : String { + return text.substring(node.getStartOffset(), node.getEndOffset()) + } + fun visit(node: LighterASTNode, action: (LighterASTNode, String, visitChildren: () -> Unit) -> Unit) { action(node, text) { val ref = Ref.create<Array<LighterASTNode>?>() @@ -46,7 +67,7 @@ public class MarkdownTree(private val text: String, private val structure: Flywe } -public fun MarkdownTree.dump(): String { +public fun MarkdownTree.toTestString(): String { val sb = StringBuilder() var level = 0 visit {(node, text, visitChildren) -> @@ -64,29 +85,25 @@ public fun MarkdownTree.dump(): String { public fun MarkdownTree.toHtml(): String { val sb = StringBuilder() - var level = 0 visit {(node, text, processChildren) -> val nodeType = node.getTokenType() val nodeText = text.substring(node.getStartOffset(), node.getEndOffset()) - val indent = " ".repeat(level * 2) when (nodeType) { MarkdownElementTypes.BULLET_LIST -> { - sb.appendln("$indent<ul>") - level++ + sb.appendln("<ul>") processChildren() - level-- - sb.appendln("$indent</ul>") + sb.appendln("</ul>") } MarkdownElementTypes.HORIZONTAL_RULE -> { - sb.appendln("$indent<hr/>") + sb.appendln("<hr/>") } MarkdownElementTypes.ORDERED_LIST -> { - sb.appendln("$indent<ol>") + sb.appendln("<ol>") processChildren() - sb.appendln("$indent</ol>") + sb.appendln("</ol>") } MarkdownElementTypes.LIST_BLOCK -> { - sb.append("$indent<li>") + sb.append("<li>") processChildren() sb.appendln("</li>") } @@ -110,14 +127,9 @@ public fun MarkdownTree.toHtml(): String { sb.appendln() } MarkdownElementTypes.PARA -> { - sb.appendln("$indent<p>") - processChildren() - sb.appendln("$indent</p>") - } - MarkdownElementTypes.VERBATIM -> { - sb.appendln("$indent<pre><code>") + sb.append("<p>") processChildren() - sb.appendln("$indent</code></pre>") + sb.appendln("</p>") } else -> { processChildren() @@ -129,8 +141,8 @@ public fun MarkdownTree.toHtml(): String { fun markdownToHtml(markdown: String): String { - val markdownTree = MarkdownProcessor().parse(markdown) - val ast = markdownTree.dump() + val markdownTree = MarkdownProcessor.parse(markdown) + val ast = markdownTree.toTestString() return markdownTree.toHtml() } diff --git a/src/Markdown/markdown.bnf b/src/Markdown/markdown.bnf index ca254295..79e9e0b4 100644 --- a/src/Markdown/markdown.bnf +++ b/src/Markdown/markdown.bnf @@ -21,35 +21,35 @@ } -Document ::= BOM? ( Block )* +Document ::= BOM? Whitespace* AnonymousSection? (Whitespace* NamedSection)* -private OptionalSpace ::= Spacechar* -private RequiredSpace ::= Spacechar+ -private NonindentSpace ::= (" " | " " | " ")? +AnonymousSection ::= SectionBody +NamedSection ::= SectionHeader SectionBody +private SectionHeader ::= '$' SectionName OptionalSpace ':' OptionalSpace +SectionName ::= SectionNameStart | '{' OptionalSpace SectionNameStart (Spacechar+ String)* OptionalSpace '}' +private SectionNameStart ::= '$'? String +SectionBody::= Block* BlankLine ::= OptionalSpace Newline Whitespace ::= Spacechar | Newline +private OptionalSpace ::= Spacechar* +private NonindentSpace ::= (" " | " " | " ")? + EndLine ::= TerminalEndline | NormalEndline -private NormalEndline ::= OptionalSpace Newline !BlankLine -private TerminalEndline ::= (OptionalSpace Newline <<eof>>) | (OptionalSpace <<eof>>) +private NormalEndline ::= Newline !BlankLine +private TerminalEndline ::= OptionalSpace <<eof>> private Indent ::= "\t" | " " -NonblankIndentedLine ::= !BlankLine IndentedLine -IndentedLine ::= Indent PlainText // ---- BLOCKS ---- -private Block ::= BlankLine* ( - Para - | Verbatim - | OrderedList - | BulletList - | Inlines - ) - -Para ::= NonindentSpace Inlines (BlankLine | TerminalEndline) +Block ::= BlankLine* ( + OrderedList + | BulletList + | HorizontalRule + | Para + ) -Verbatim ::= VerbatimItem+ -VerbatimItem ::= BlankLine* NonblankIndentedLine +Para ::= Inlines (BlankLine | TerminalEndline)? HorizontalRule ::= NonindentSpace ( '*' OptionalSpace '*' OptionalSpace '*' (OptionalSpace '*')* @@ -74,8 +74,8 @@ ListContinuationBlock ::= BlankLine* (Indent ListBlock)+ // ---- INLINES ---- private Inlines ::= (!EndLine Inline | EndLine &Inline )+ EndLine? -private Inline ::= Strong | Emph | Link | PlainText -PlainText ::= (String | Number | Spacechar)+ +Inline ::= Strong | Emph | Link | PlainText +PlainText ::= (String | Number | Spacechar+)+ Emph ::= EmphStar | EmphUnderscore private EmphStar ::= '*' !Whitespace (!'*' Inline)+ '*' diff --git a/src/Model/Content.kt b/src/Model/Content.kt new file mode 100644 index 00000000..eb092cb2 --- /dev/null +++ b/src/Model/Content.kt @@ -0,0 +1,88 @@ +package org.jetbrains.dokka + +import kotlin.properties.Delegates + +public abstract class ContentNode { + val children = arrayListOf<ContentNode>() + + class object { + val empty = ContentEmpty + } + + fun isEmpty() = children.isEmpty() +} + +public object ContentEmpty : ContentNode( ) + +public class ContentText(val text : String) : ContentNode( ) +public class ContentBlock() : ContentNode( ) +public class ContentEmphasis() : ContentNode() +public class ContentStrong() : ContentNode() +public class ContentList() : ContentNode() +public class ContentSection(public val label: String) : ContentNode() + +public class Content() : ContentNode() { + public val sections: Map<String, ContentSection> by Delegates.lazy { + val map = hashMapOf<String, ContentSection>() + for (child in children) { + if (child is ContentSection) + map.put(child.label, child) + } + + if ("\$summary" !in map && "\$description" !in map) { + // no explicit summary and description, convert anonymous section + val anonymous = map[""] + if (anonymous != null) { + map.remove("") + val summary = ContentSection("\$summary") + val description = ContentSection("\$description") + + val summaryNodes = anonymous.children.take(1) + val descriptionNodes = anonymous.children.drop(1) + + if (summaryNodes.any()) { + summary.children.addAll(summaryNodes) + map.put("\$summary", summary) + } + + if (descriptionNodes.any()) { + description.children.addAll(descriptionNodes) + map.put("\$description", description) + } + } + } + map + } + + public val summary: ContentNode get() = sections["\$summary"] ?: ContentNode.empty + public val description: ContentNode get() = sections["\$description"] ?: ContentNode.empty + + override fun equals(other: Any?): Boolean { + if (other !is Content) + return false + if (sections.size != other.sections.size) + return false + for (keys in sections.keySet()) + if (sections[keys] != other.sections[keys]) + return false + + return true + } + + override fun hashCode(): Int { + return sections.map { it.hashCode() }.sum() + } + + override fun toString(): String { + if (sections.isEmpty()) + return "<empty>" + return sections.values().joinToString() + } + + val isEmpty: Boolean + get() = sections.none() + + class object { + val Empty = Content() + } +} diff --git a/src/Model/DocumentationContent.kt b/src/Model/DocumentationContent.kt deleted file mode 100644 index 77e8c764..00000000 --- a/src/Model/DocumentationContent.kt +++ /dev/null @@ -1,150 +0,0 @@ -package org.jetbrains.dokka - -import org.jetbrains.jet.lang.descriptors.* -import org.jetbrains.jet.lang.resolve.BindingContext - -public class DocumentationContentSection(public val label: String, public val text: RichString) { - override fun toString(): String { - return "$label = $text" - } -} - -public class DocumentationContent(public val sections: Map<String, DocumentationContentSection>) { - - public val summary: RichString get() = sections["\$summary"]?.text ?: RichString.empty - public val description: RichString get() = sections["\$description"]?.text ?: RichString.empty - - override fun equals(other: Any?): Boolean { - if (other !is DocumentationContent) - return false - if (sections.size != other.sections.size) - return false - for (keys in sections.keySet()) - if (sections[keys] != other.sections[keys]) - return false - - return true - } - - override fun hashCode(): Int { - return sections.map { it.hashCode() }.sum() - } - - override fun toString(): String { - if (sections.isEmpty()) - return "<empty>" - return sections.values().joinToString() - } - - val isEmpty: Boolean - get() = description.isEmpty() && sections.none() - - class object { - val Empty = DocumentationContent(mapOf()) - } -} - - -fun BindingContext.getDocumentation(descriptor: DeclarationDescriptor): DocumentationContent { - val docText = getDocumentationElements(descriptor).map { it.extractText() }.join("\n") - val sections = docText.parseSections() - sections.createSummaryAndDescription() - return DocumentationContent(sections) -} - -fun MutableMap<String, DocumentationContentSection>.createSummaryAndDescription() { - - val summary = get("\$summary") - val description = get("\$description") - if (summary != null && description == null) { - return - } - - if (summary == null && description != null) { - return - } - - val unnamed = get("") - if (unnamed == null) { - return - } - - val split = unnamed.text.splitBy("\n") - remove("") - if (!split.first.isEmpty()) - put("\$summary", DocumentationContentSection("\$summary", split.first)) - if (!split.second.isEmpty()) - put("\$description", DocumentationContentSection("\$description", split.second)) -} - -fun String.parseLabel(index: Int): Pair<String, Int> { - val c = get(index) - when { - Character.isJavaIdentifierStart(c) -> { - for (end in index + 1..length - 1) { - if (!Character.isJavaIdentifierPart(get(end))) { - return substring(index, end) to end - } - } - return substring(index, length) to length - } - c == '$' -> { - for (end in index + 1..length - 1) { - if (Character.isWhitespace(get(end))) { - return substring(index, end) to end - } - } - return substring(index, length) to length - } - c == '{' -> { - val end = indexOf('}', index + 1) - return substring(index + 1, end) to end + 1 - } - } - return "" to -1 -} - -fun String.parseSections(): MutableMap<String, DocumentationContentSection> { - val sections = hashMapOf<String, DocumentationContentSection>() - var currentLabel = "" - var currentSectionStart = 0 - var currentIndex = 0 - - while (currentIndex < length) { - if (get(currentIndex) == '$') { - val (label, index) = parseLabel(currentIndex + 1) - if (index != -1 && index < length() && get(index) == ':') { - // section starts, add previous section - val currentContent = substring(currentSectionStart, currentIndex).trim() - val section = DocumentationContentSection(currentLabel, currentContent.toRichString()) - sections.put(section.label, section) - - currentLabel = label - currentIndex = index + 1 - currentSectionStart = currentIndex - continue - } - } - currentIndex++ - - } - - val currentContent = substring(currentSectionStart, currentIndex).trim() - val section = DocumentationContentSection(currentLabel, currentContent.toRichString()) - sections.put(section.label, section) - return sections -} - -fun String.toRichString() : RichString { - val content = RichString() - for(index in indices) { - val ch = get(index) - when { - ch == '\\' -> continue - ch == '*' && index < length-1 && !get(index + 1).isWhitespace() -> ch - } - } - - content.addSlice(this, NormalStyle) - return content -}
\ No newline at end of file diff --git a/src/Model/DocumentationModule.kt b/src/Model/DocumentationModule.kt index 78ebda04..6084ea5e 100644 --- a/src/Model/DocumentationModule.kt +++ b/src/Model/DocumentationModule.kt @@ -1,30 +1,11 @@ package org.jetbrains.dokka -import org.jetbrains.jet.lang.resolve.BindingContext -import org.jetbrains.jet.lang.descriptors.* -import org.jetbrains.jet.lang.resolve.name.FqName - -public class DocumentationModule(name: String, val module: ModuleDescriptor) : DocumentationNode(module, name, DocumentationContent.Empty, DocumentationNode.Kind.Module) { +public class DocumentationModule(name: String) : DocumentationNode(name, Content.Empty, DocumentationNode.Kind.Module) { fun merge(other: DocumentationModule): DocumentationModule { - val model = DocumentationModule(name, module) + val model = DocumentationModule(name) model.addAllReferencesFrom(other) model.addAllReferencesFrom(this) return model } } -fun BindingContext.createDocumentationModule(name: String, - module: ModuleDescriptor, - packages: Set<FqName>, - options : DocumentationOptions = DocumentationOptions()): DocumentationModule { - val documentationModule = DocumentationModule(name, module) - val visitor = DocumentationNodeBuilder(this) - for (packageName in packages) { - val pkg = module.getPackage(packageName) - pkg!!.accept(DocumentationBuildingVisitor(this, options, visitor), documentationModule) - } - - // TODO: Uncomment for resolve verification - // checkResolveChildren(documentationModule) - return documentationModule -} diff --git a/src/Model/DocumentationNode.kt b/src/Model/DocumentationNode.kt index c96c383d..198e549b 100644 --- a/src/Model/DocumentationNode.kt +++ b/src/Model/DocumentationNode.kt @@ -1,12 +1,9 @@ package org.jetbrains.dokka -import org.jetbrains.jet.lang.descriptors.* import java.util.LinkedHashSet - -public open class DocumentationNode(val descriptor: DeclarationDescriptor, - val name: String, - val doc: DocumentationContent, +public open class DocumentationNode(val name: String, + val doc: Content, val kind: DocumentationNode.Kind) { private val references = LinkedHashSet<DocumentationReference>() diff --git a/test/data/comments/explicitSummary.kt b/test/data/comments/explicitSummary.kt new file mode 100644 index 00000000..68f75c99 --- /dev/null +++ b/test/data/comments/explicitSummary.kt @@ -0,0 +1,6 @@ + +/** + * $$summary: Summary + * $$description: Description + */ +val property = "test"
\ No newline at end of file diff --git a/test/data/comments/multilineDoc.kt b/test/data/comments/multilineDoc.kt index 960c78bd..31cfa3a7 100644 --- a/test/data/comments/multilineDoc.kt +++ b/test/data/comments/multilineDoc.kt @@ -1,5 +1,6 @@ /** * doc1 + * * doc2 * doc3 */ diff --git a/test/src/TestAPI.kt b/test/src/TestAPI.kt index 27d02710..309654e5 100644 --- a/test/src/TestAPI.kt +++ b/test/src/TestAPI.kt @@ -38,3 +38,30 @@ public fun verifyModel(vararg files: String, verifier: (DocumentationModule) -> Disposer.dispose(environment) } +fun StringBuilder.appendChildren(node: ContentNode) : StringBuilder { + for (child in node.children) { + val childText = child.toTestString() + append(childText) + } + return this +} + +fun StringBuilder.appendNode(node: ContentNode) : StringBuilder { + when (node) { + is ContentText -> { + append(node.text) + } + is ContentEmphasis -> append("*").appendChildren(node).append("*") + else -> { + appendChildren(node) + } + } + return this +} + +fun ContentNode.toTestString(): String { + val node = this + return StringBuilder { + appendNode(node) + }.toString() +} diff --git a/test/src/markdown/ParserTest.kt b/test/src/markdown/ParserTest.kt index 726505cf..2a310bb2 100644 --- a/test/src/markdown/ParserTest.kt +++ b/test/src/markdown/ParserTest.kt @@ -3,13 +3,13 @@ package org.jetbrains.dokka.tests import org.junit.Test import org.jetbrains.dokka import org.jetbrains.dokka.MarkdownProcessor -import org.jetbrains.dokka.dump +import org.jetbrains.dokka.toTestString import org.jetbrains.dokka.toHtml public class ParserTest { fun runTestFor(text : String) { - val markdownTree = MarkdownProcessor().parse(text) - println(markdownTree.dump()) + val markdownTree = MarkdownProcessor.parse(text) + println(markdownTree.toTestString()) println(markdownTree.toHtml()) } @@ -79,5 +79,37 @@ number two Test fun emph() { runTestFor("*text*") } + + Test fun emphAndEmptySection() { + runTestFor("*text* \$sec:") + } + + Test fun emphAndSection() { + runTestFor("*text* \$sec: some text") + } + + Test fun emphAndBracedSection() { + runTestFor("Text *bold* text \${sec}: some text") + } + + Test fun section() { + runTestFor( + "Plain text \$one: Summary \${two}: Description with *emphasis* \${An example of a section}: Example") + } + + Test fun anonymousSection() { + runTestFor("Summary\n\nDescription\n") + } + + Test fun specialSection() { + runTestFor( + "Plain text \$\$summary: Summary \${\$description}: Description \${\$An example of a section}: Example") + } + + Test fun emptySection() { + runTestFor( + "Plain text \$summary:") + } + } diff --git a/test/src/markdown/Specification.kt b/test/src/markdown/Specification.kt index e0cda024..ba1f8363 100644 --- a/test/src/markdown/Specification.kt +++ b/test/src/markdown/Specification.kt @@ -4,7 +4,7 @@ import org.junit.runner.* import org.jetbrains.kmark.test.* import org.jetbrains.dokka.* -[RunWith(javaClass<MarkdownTestRunner>())] +//[RunWith(javaClass<MarkdownTestRunner>())] class Specification : MarkdownSpecification("test/data/markdown/spec.txt", { markdownToHtml(it.replace("→", "\t")) })
\ No newline at end of file diff --git a/test/src/model/ClassTest.kt b/test/src/model/ClassTest.kt index 05e156f3..7068038f 100644 --- a/test/src/model/ClassTest.kt +++ b/test/src/model/ClassTest.kt @@ -10,7 +10,7 @@ public class ClassTest { with(model.members.single().members.single()) { assertEquals(DocumentationNode.Kind.Class, kind) assertEquals("Klass", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(2, details.count()) assertEquals("<init>", members.single().name) assertTrue(links.none()) @@ -23,7 +23,7 @@ public class ClassTest { with(model.members.single().members.single()) { assertEquals(DocumentationNode.Kind.Class, kind) assertEquals("Klass", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(2, details.count()) assertEquals("<init>", members.single().name) assertTrue(links.none()) @@ -36,7 +36,7 @@ public class ClassTest { with(model.members.single().members.single()) { assertEquals(DocumentationNode.Kind.Object, kind) assertEquals("Obj", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(2, details.count()) assertTrue(members.none()) assertTrue(links.none()) @@ -49,21 +49,21 @@ public class ClassTest { with (model.members.single().members.single()) { assertEquals(DocumentationNode.Kind.Class, kind) assertEquals("Klass", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(2, details.count()) assertTrue(links.none()) assertEquals(1, members.count()) with(members.elementAt(0)) { assertEquals("<init>", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(DocumentationNode.Kind.Constructor, kind) assertEquals(2, details.count()) assertEquals("public", details.elementAt(0).name) with(details.elementAt(1)) { assertEquals("name", name) assertEquals(DocumentationNode.Kind.Parameter, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals("String", details.single().name) assertTrue(links.none()) assertTrue(members.none()) @@ -80,14 +80,14 @@ public class ClassTest { with(model.members.single().members.single()) { assertEquals(DocumentationNode.Kind.Class, kind) assertEquals("Klass", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(2, details.count()) assertTrue(links.none()) assertEquals(2, members.count()) with(members.elementAt(0)) { assertEquals("<init>", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(DocumentationNode.Kind.Constructor, kind) assertEquals(1, details.count()) assertEquals("public", details.elementAt(0).name) @@ -96,7 +96,7 @@ public class ClassTest { } with(members.elementAt(1)) { assertEquals("fn", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(DocumentationNode.Kind.Function, kind) assertEquals("Unit", detail(DocumentationNode.Kind.Type).name) assertTrue(links.none()) @@ -111,14 +111,14 @@ public class ClassTest { with(model.members.single().members.single()) { assertEquals(DocumentationNode.Kind.Class, kind) assertEquals("Klass", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(2, details.count()) assertTrue(links.none()) assertEquals(2, members.count()) with(members.elementAt(0)) { assertEquals("<init>", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(DocumentationNode.Kind.Constructor, kind) assertEquals(1, details.count()) assertEquals("public", details.elementAt(0).name) @@ -127,7 +127,7 @@ public class ClassTest { } with(members.elementAt(1)) { assertEquals("name", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(DocumentationNode.Kind.Property, kind) assertEquals("String", detail(DocumentationNode.Kind.Type).name) assertTrue(members.none()) diff --git a/test/src/model/CommentTest.kt b/test/src/model/CommentTest.kt index 28f717db..62f64a58 100644 --- a/test/src/model/CommentTest.kt +++ b/test/src/model/CommentTest.kt @@ -8,7 +8,7 @@ public class CommentTest { Test fun emptyDoc() { verifyModel("test/data/comments/emptyDoc.kt") { model -> with(model.members.single().members.single()) { - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) } } } @@ -16,7 +16,7 @@ public class CommentTest { Test fun emptyDocButComment() { verifyModel("test/data/comments/emptyDocButComment.kt") { model -> with(model.members.single().members.single()) { - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) } } } @@ -24,8 +24,8 @@ public class CommentTest { Test fun multilineDoc() { verifyModel("test/data/comments/multilineDoc.kt") { model -> with(model.members.single().members.single()) { - assertEquals("doc1".toRichString(), doc.summary) - assertEquals("doc2\ndoc3".toRichString(), doc.description) + assertEquals("doc1", doc.summary.toTestString()) + assertEquals("doc2\ndoc3\n", doc.description.toTestString()) } } } @@ -33,8 +33,8 @@ public class CommentTest { Test fun multipleDocs() { verifyModel("test/data/comments/multipleDocs.kt") { model -> with(model.members.single().members.single()) { - assertEquals("doc1".toRichString(), doc.summary) - assertEquals("doc2\ndoc3".toRichString(), doc.description) + assertEquals("doc1", doc.summary.toTestString()) + assertEquals("doc2\ndoc3", doc.description.toTestString()) } } } @@ -42,8 +42,8 @@ public class CommentTest { Test fun multilineDocWithComment() { verifyModel("test/data/comments/multilineDocWithComment.kt") { model -> with(model.members.single().members.single()) { - assertEquals("doc1".toRichString(), doc.summary) - assertEquals("doc2\ndoc3".toRichString(), doc.description) + assertEquals("doc1", doc.summary.toTestString()) + assertEquals("doc2\ndoc3", doc.description.toTestString()) } } } @@ -51,7 +51,7 @@ public class CommentTest { Test fun oneLineDoc() { verifyModel("test/data/comments/oneLineDoc.kt") { model -> with(model.members.single().members.single()) { - assertEquals("doc".toRichString(), doc.summary) + assertEquals("doc", doc.summary.toTestString()) } } } @@ -59,7 +59,7 @@ public class CommentTest { Test fun oneLineDocWithComment() { verifyModel("test/data/comments/oneLineDocWithComment.kt") { model -> with(model.members.single().members.single()) { - assertEquals("doc".toRichString(), doc.summary) + assertEquals("doc", doc.summary.toTestString()) } } } @@ -67,7 +67,7 @@ public class CommentTest { Test fun oneLineDocWithEmptyLine() { verifyModel("test/data/comments/oneLineDocWithEmptyLine.kt") { model -> with(model.members.single().members.single()) { - assertEquals("doc".toRichString(), doc.summary) + assertEquals("doc", doc.summary.toTestString()) } } } @@ -76,24 +76,34 @@ public class CommentTest { verifyModel("test/data/comments/emptySection.kt") { model -> with(model.members.single().members.single()) { assertEquals(NormalStyle, NormalStyle) - assertEquals("Summary".toRichString(), doc.summary) + assertEquals("Summary", doc.summary.toTestString()) assertEquals(2, doc.sections.count()) with (doc.sections["one"]!!) { assertEquals("one", label) - assertEquals(RichString.empty, text) + assertEquals("", toTestString()) } } } } + Test fun explicitSummary() { + verifyModel("test/data/comments/explicitSummary.kt") { model -> + with(model.members.single().members.single()) { + assertEquals("Summary", doc.summary.toTestString()) + assertEquals("Description", doc.description.toTestString()) + assertEquals(2, doc.sections.count()) + } + } + } + Test fun section1() { verifyModel("test/data/comments/section1.kt") { model -> with(model.members.single().members.single()) { - assertEquals("Summary".toRichString(), doc.summary) + assertEquals("Summary", doc.summary.toTestString()) assertEquals(2, doc.sections.count()) with (doc.sections["one"]!!) { assertEquals("one", label) - assertEquals("section one".toRichString(), text) + assertEquals("section one", toTestString()) } } } @@ -102,15 +112,15 @@ public class CommentTest { Test fun section2() { verifyModel("test/data/comments/section2.kt") { model -> with(model.members.single().members.single()) { - assertEquals("Summary".toRichString(), doc.summary) + assertEquals("Summary", doc.summary.toTestString()) assertEquals(3, doc.sections.count()) with (doc.sections["one"]!!) { assertEquals("one", label) - assertEquals("section one".toRichString(), text) + assertEquals("section one", toTestString()) } with (doc.sections["two"]!!) { assertEquals("two", label) - assertEquals("section two".toRichString(), text) + assertEquals("section two", toTestString()) } } } @@ -119,11 +129,11 @@ public class CommentTest { Test fun sectionOnOneLine() { verifyModel("test/data/comments/sectionOnOneLine.kt") { model -> with(model.members.single().members.single()) { - assertEquals("Summary".toRichString(), doc.summary) + assertEquals("Summary", doc.summary.toTestString()) assertEquals(2, doc.sections.count()) with (doc.sections["one"]!!) { assertEquals("one", label) - assertEquals("same line".toRichString(), text) + assertEquals("same line", toTestString()) } } } @@ -132,11 +142,11 @@ public class CommentTest { Test fun emptySectionOnOneLine() { verifyModel("test/data/comments/emptySectionOnOneLine.kt") { model -> with(model.members.single().members.single()) { - assertEquals("Summary".toRichString(), doc.summary) + assertEquals("Summary", doc.summary.toTestString()) assertEquals(2, doc.sections.count()) with (doc.sections["one"]!!) { assertEquals("one", label) - assertEquals(RichString.empty, text) + assertEquals("", toTestString()) } } } @@ -145,12 +155,12 @@ public class CommentTest { Test fun multilineSection() { verifyModel("test/data/comments/multilineSection.kt") { model -> with(model.members.single().members.single()) { - assertEquals("Summary".toRichString(), doc.summary) + assertEquals("Summary", doc.summary.toTestString()) assertEquals(2, doc.sections.count()) with (doc.sections["one"]!!) { assertEquals("one", label) assertEquals("""line one -line two""".toRichString(), text) +line two""", toTestString()) } } } @@ -159,11 +169,11 @@ line two""".toRichString(), text) Test fun sectionWithBracedLabel() { verifyModel("test/data/comments/sectionWithBracedLabel.kt") { model -> with(model.members.single().members.single()) { - assertEquals("Summary".toRichString(), doc.summary) + assertEquals("Summary", doc.summary.toTestString()) assertEquals(2, doc.sections.count()) with (doc.sections["this.label.is.really.long"]!!) { assertEquals("this.label.is.really.long", label) - assertEquals("section one".toRichString(), text) + assertEquals("section one", toTestString()) } } } diff --git a/test/src/model/FunctionTest.kt b/test/src/model/FunctionTest.kt index f090fcd5..fe8b6397 100644 --- a/test/src/model/FunctionTest.kt +++ b/test/src/model/FunctionTest.kt @@ -10,7 +10,7 @@ public class FunctionTest { with(model.members.single().members.single()) { assertEquals("fn", name) assertEquals(DocumentationNode.Kind.Function, kind) - assertEquals("Function fn".toRichString(), doc.summary) + assertEquals("Function fn", doc.summary.toTestString()) assertEquals("Unit", detail(DocumentationNode.Kind.Type).name) assertTrue(members.none()) assertTrue(links.none()) @@ -23,7 +23,7 @@ public class FunctionTest { with(model.members.single().members.single()) { assertEquals("fn", name) assertEquals(DocumentationNode.Kind.Function, kind) - assertEquals("Function with receiver".toRichString(), doc.summary) + assertEquals("Function with receiver", doc.summary.toTestString()) assertEquals("Unit", details.elementAt(0).name) assertEquals(4, details.count()) @@ -32,7 +32,7 @@ public class FunctionTest { with(details.elementAt(3)) { assertEquals("<this>", name) assertEquals(DocumentationNode.Kind.Receiver, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals("String", details.single().name) assertTrue(members.none()) assertTrue(links.none()) @@ -48,7 +48,7 @@ public class FunctionTest { with(model.members.single().members.single()) { assertEquals("generic", name) assertEquals(DocumentationNode.Kind.Function, kind) - assertEquals("generic function".toRichString(), doc.summary) + assertEquals("generic function", doc.summary.toTestString()) assertEquals(4, details.count()) assertEquals("Unit", details.elementAt(0).name) @@ -57,7 +57,7 @@ public class FunctionTest { with(details.elementAt(3)) { assertEquals("T", name) assertEquals(DocumentationNode.Kind.TypeParameter, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertTrue(details.none()) assertTrue(members.none()) assertTrue(links.none()) @@ -73,7 +73,7 @@ public class FunctionTest { with(model.members.single().members.single()) { assertEquals("generic", name) assertEquals(DocumentationNode.Kind.Function, kind) - assertEquals("generic function".toRichString(), doc.summary) + assertEquals("generic function", doc.summary.toTestString()) assertEquals(5, details.count()) assertEquals("Unit", details.elementAt(0).name) @@ -82,11 +82,11 @@ public class FunctionTest { with(details.elementAt(3)) { assertEquals("T", name) assertEquals(DocumentationNode.Kind.TypeParameter, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) with(details.single()) { assertEquals("R", name) assertEquals(DocumentationNode.Kind.UpperBound, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertTrue(details.none()) assertTrue(members.none()) assertTrue(links.none()) @@ -97,7 +97,7 @@ public class FunctionTest { with(details.elementAt(4)) { assertEquals("R", name) assertEquals(DocumentationNode.Kind.TypeParameter, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertTrue(members.none()) assertTrue(links.none()) } @@ -113,10 +113,9 @@ public class FunctionTest { with(model.members.single().members.single()) { assertEquals("function", name) assertEquals(DocumentationNode.Kind.Function, kind) - assertEquals("Multiline".toRichString(), doc.summary) + assertEquals("Multiline", doc.summary.toTestString()) assertEquals("""Function -Documentation""".toRichString() - , doc.description) +Documentation""", doc.description.toTestString()) assertEquals(4, details.count()) assertEquals("Unit", details.elementAt(0).name) @@ -125,7 +124,7 @@ Documentation""".toRichString() with(details.elementAt(3)) { assertEquals("x", name) assertEquals(DocumentationNode.Kind.Parameter, kind) - assertEquals("parameter".toRichString(), doc.summary) + assertEquals("parameter", doc.summary.toTestString()) assertEquals("Int", details.single().name) assertTrue(members.none()) assertTrue(links.none()) diff --git a/test/src/model/PackageTest.kt b/test/src/model/PackageTest.kt index b855ad7d..848fff3e 100644 --- a/test/src/model/PackageTest.kt +++ b/test/src/model/PackageTest.kt @@ -10,7 +10,7 @@ public class PackageTest { with(model.members.single()) { assertEquals(DocumentationNode.Kind.Package, kind) assertEquals("", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertTrue(details.none()) assertTrue(members.none()) assertTrue(links.none()) @@ -23,7 +23,7 @@ public class PackageTest { with(model.members.single()) { assertEquals(DocumentationNode.Kind.Package, kind) assertEquals("simple", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertTrue(details.none()) assertTrue(members.none()) assertTrue(links.none()) @@ -36,7 +36,7 @@ public class PackageTest { with(model.members.single()) { assertEquals(DocumentationNode.Kind.Package, kind) assertEquals("dot.name", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertTrue(details.none()) assertTrue(members.none()) assertTrue(links.none()) @@ -50,14 +50,14 @@ public class PackageTest { with(model.members.single { it.name == "simple" }) { assertEquals(DocumentationNode.Kind.Package, kind) assertEquals("simple", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertTrue(details.none()) assertTrue(members.none()) assertTrue(links.none()) } with(model.members.single { it.name == "dot.name" }) { assertEquals(DocumentationNode.Kind.Package, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertTrue(details.none()) assertTrue(members.none()) assertTrue(links.none()) @@ -71,7 +71,7 @@ public class PackageTest { with(model.members.elementAt(0)) { assertEquals(DocumentationNode.Kind.Package, kind) assertEquals("simple", name) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertTrue(details.none()) assertTrue(members.none()) assertTrue(links.none()) diff --git a/test/src/model/PropertyTest.kt b/test/src/model/PropertyTest.kt index 07651ce2..ed49bd6b 100644 --- a/test/src/model/PropertyTest.kt +++ b/test/src/model/PropertyTest.kt @@ -10,7 +10,7 @@ public class PropertyTest { with(model.members.single().members.single()) { assertEquals("property", name) assertEquals(DocumentationNode.Kind.Property, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals("String", detail(DocumentationNode.Kind.Type).name) assertTrue(members.none()) assertTrue(links.none()) @@ -23,7 +23,7 @@ public class PropertyTest { with(model.members.single().members.single()) { assertEquals("property", name) assertEquals(DocumentationNode.Kind.Property, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals("String", detail(DocumentationNode.Kind.Type).name) assertTrue(members.none()) assertTrue(links.none()) @@ -36,13 +36,13 @@ public class PropertyTest { with(model.members.single().members.single()) { assertEquals("property", name) assertEquals(DocumentationNode.Kind.Property, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals("String", detail(DocumentationNode.Kind.Type).name) assertTrue(links.none()) with(members.single()) { assertEquals("<get-property>", name) assertEquals(DocumentationNode.Kind.Function, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals("String", detail(DocumentationNode.Kind.Type).name) assertTrue(links.none()) assertTrue(members.none()) @@ -56,7 +56,7 @@ public class PropertyTest { with(model.members.single().members.single()) { assertEquals("property", name) assertEquals(DocumentationNode.Kind.Property, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(3, details.count()) with(details.elementAt(0)) { assertEquals(DocumentationNode.Kind.Type, kind) @@ -76,7 +76,7 @@ public class PropertyTest { with(members.elementAt(0)) { assertEquals("<get-property>", name) assertEquals(DocumentationNode.Kind.Function, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals("String", detail(DocumentationNode.Kind.Type).name) assertTrue(links.none()) assertTrue(members.none()) @@ -84,7 +84,7 @@ public class PropertyTest { with(members.elementAt(1)) { assertEquals("<set-property>", name) assertEquals(DocumentationNode.Kind.Function, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals(4, details.count()) assertEquals("Unit", details.elementAt(0).name) assertEquals("final", details.elementAt(1).name) @@ -92,7 +92,7 @@ public class PropertyTest { with(details.elementAt(3)) { assertEquals("value", name) assertEquals(DocumentationNode.Kind.Parameter, kind) - assertEquals(DocumentationContent.Empty, doc) + assertEquals(Content.Empty, doc) assertEquals("String", detail(DocumentationNode.Kind.Type).name) assertTrue(links.none()) assertTrue(members.none()) |