Skip to content

Commit 25ea122

Browse files
committed
Handle unclosed code snippets
1 parent cc644ed commit 25ea122

File tree

3 files changed

+29
-19
lines changed

3 files changed

+29
-19
lines changed

org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterMarkdownCommentsTests.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -768,30 +768,25 @@ class TestFakeFences {
768768
""";
769769
formatSource(input, expected);
770770
}
771-
public void testMarkdownInvalidCodeFences() throws JavaModelException {
771+
public void testMarkdownUnclosedCodeFences() throws JavaModelException {
772772
setComplianceLevel(CompilerOptions.VERSION_23);
773-
this.formatterPrefs.comment_line_length = 25;
774773
String input = """
775774
/// ```
776775
/// public class HelloWorld3 {
777776
/// public static void main(String args) {
778777
/// System.out.println("ssdd World!");
779778
/// }
780779
/// }
781-
///
782-
/// New err
783780
class Mark61 {
784781
}
785782
""";
786783
String expected = """
787-
/// ``` public class
788-
/// HelloWorld3 { public
789-
/// static void
790-
/// main(String args) {
791-
/// System.out.println("ssdd
792-
/// World!"); } }
793-
///
794-
/// New err
784+
/// ```
785+
/// public class HelloWorld3 {
786+
/// public static void main(String args) {
787+
/// System.out.println("ssdd World!");
788+
/// }
789+
/// }\s
795790
class Mark61 {
796791
}
797792
""";

org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ public class CommentsPreparator extends ASTVisitor {
136136
private DefaultCodeFormatter preTagCodeFormatter;
137137
private DefaultCodeFormatter snippetCodeFormatter;
138138
private boolean snippetForMarkdown = false;
139+
private boolean isUnclosedSnippet = false;
139140

140141
public CommentsPreparator(TokenManager tm, DefaultCodeFormatterOptions options, String sourceLevel) {
141142
this.tm = tm;
@@ -886,6 +887,18 @@ private void handleMarkdown(TagElement node) {
886887
}
887888
if (shouldDisable) {
888889
disableFormatting(tokenIndex, tokenIndexLast, false);
890+
} else if (closingToken == null) {
891+
if (tokenIndex > 1)
892+
openingToken.breakBefore();
893+
openingToken.breakAfter();
894+
tokenIndexLast = this.ctm.findIndex(startPos + node.getLength(), ANY, true);
895+
this.snippetForMarkdown = true;
896+
this.isUnclosedSnippet = true;
897+
formatCode(tokenIndex, tokenIndexLast - 1, true);
898+
this.snippetForMarkdown = false;
899+
this.isUnclosedSnippet = false;
900+
closingToken = this.ctm.get(tokenIndexLast);
901+
closingToken.putLineBreaksAfter(0);
889902
}
890903
}
891904

@@ -1613,7 +1626,7 @@ private void addSubstituteWraps() {
16131626

16141627
private boolean formatCode(int openingIndex, int closingIndex, boolean snippetTag) {
16151628
int codeStartPosition = this.ctm.get(openingIndex).originalEnd + 1;
1616-
int codeEndPosition = this.ctm.get(closingIndex).originalStart - 1;
1629+
int codeEndPosition = this.isUnclosedSnippet ? this.ctm.get(closingIndex).originalStart + 1 : this.ctm.get(closingIndex).originalStart - 1;
16171630
StringBuilder codeBuilder = new StringBuilder(codeEndPosition - codeStartPosition + 1);
16181631
int[] positionMapping = new int[codeEndPosition - codeStartPosition + 1];
16191632
// ^ index: original source position (minus startPosition), value: position in code string
@@ -1636,11 +1649,12 @@ private boolean formatCode(int openingIndex, int closingIndex, boolean snippetTa
16361649
// there are too few linebreaks at the start and end
16371650
Token start = formattedTokens.get(0);
16381651
start.putLineBreaksBefore(start.getLineBreaksBefore() + 1);
1639-
Token end = formattedTokens.get(formattedTokens.size() - 1);
1640-
end.putLineBreaksAfter(end.getLineBreaksAfter() + 1);
1641-
// and there may be too many line breaks before closing tag
1642-
this.ctm.get(closingIndex).clearLineBreaksBefore();
1643-
1652+
if(!this.isUnclosedSnippet) {
1653+
Token end = formattedTokens.get(formattedTokens.size() - 1);
1654+
end.putLineBreaksAfter(end.getLineBreaksAfter() + 1);
1655+
// and there may be too many line breaks before closing tag
1656+
this.ctm.get(closingIndex).clearLineBreaksBefore();
1657+
}
16441658
List<Token> tokensToReplace = this.commentStructure.subList(openingIndex + 1, closingIndex);
16451659
tokensToReplace.clear();
16461660
tokensToReplace.addAll(formattedTokens);

org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,8 @@ private ReplaceEdit getReplaceEdit(int editStart, int editEnd, String text, IReg
419419
text = adaptReplaceText(text, breaksToPreserve, true, regionEnd);
420420
editEnd = regionEnd;
421421
}
422-
return new ReplaceEdit(editStart, editEnd - editStart, text);
422+
int length = editEnd - editStart < 0 ? 0 : editEnd - editStart;
423+
return new ReplaceEdit(editStart, length, text);
423424
}
424425

425426
private boolean isOnlyWhitespace(String text) {

0 commit comments

Comments
 (0)