diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java index a5d650f675f..1637a792f22 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java @@ -389,7 +389,8 @@ private Constant resolveCasePattern(BlockScope scope, TypeBinding caseType, Type switchStatement.totalPattern = e; } e.isTotalTypeNode = true; - if (switchStatement.nullCase == null) + if (switchStatement.nullCase == null + && SwitchStatement.IsNullRequiredWithPrimitivesInPatterns(scope, expressionType)) constant = IntConstant.fromValue(-1); } } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Javadoc.java index c9350927fad..fc16c2c03da 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Javadoc.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Javadoc.java @@ -42,6 +42,7 @@ public class Javadoc extends ASTNode { // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=153399 // Store value tag positions public long valuePositions = -1; + public boolean isMarkdown; public Javadoc(int sourceStart, int sourceEnd) { this.sourceStart = sourceStart; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java index bd57ce20c6c..a71da56bc11 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java @@ -933,7 +933,8 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { } } private void transformConstants() { - if (this.nullCase == null) { + if (this.nullCase == null + && SwitchStatement.IsNullRequiredWithPrimitivesInPatterns(this.scope, this.expression.resolvedType)) { for (int i = 0,l = this.otherConstants.length; i < l; ++i) { if (this.otherConstants[i].e == this.totalPattern) { this.otherConstants[i].index = -1; @@ -945,6 +946,12 @@ private void transformConstants() { this.constants[i] = this.otherConstants[i].index; } } + public static boolean IsNullRequiredWithPrimitivesInPatterns(BlockScope scope, + TypeBinding expressionType) { + return !(expressionType.isBaseType() && JavaFeature.PRIMITIVES_IN_PATTERNS.isSupported( + scope.compilerOptions().sourceLevel, + scope.compilerOptions().enablePreviewFeatures)); + } private void generateCodeSwitchPatternEpilogue(CodeStream codeStream) { if (needPatternDispatchCopy()) { codeStream.removeVariable(this.dispatchPatternCopy); @@ -954,7 +961,7 @@ private void generateCodeSwitchPatternEpilogue(CodeStream codeStream) { private void generateCodeSwitchPatternPrologue(BlockScope currentScope, CodeStream codeStream) { this.expression.generateCode(currentScope, codeStream, true); - if ((this.switchBits & NullCase) == 0) { + if ((this.switchBits & NullCase) == 0 && !this.expression.resolvedType.isBaseType()) { codeStream.dup(); codeStream.invokeJavaUtilObjectsrequireNonNull(); codeStream.pop(); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java index 03d68d8ff1a..2a179b9c874 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java @@ -97,6 +97,7 @@ public boolean checkDeprecation(int commentPtr) { this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr]; this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr]-1; this.firstTagPosition = this.sourceParser.scanner.commentTagStarts[commentPtr]; + this.markdown = this.sourceParser.scanner.commentIsMarkdown[commentPtr]; this.validValuePositions = -1; this.invalidValuePositions = -1; this.tagWaitingForDescription = NO_TAG_VALUE; @@ -104,11 +105,13 @@ public boolean checkDeprecation(int commentPtr) { // Init javadoc if necessary if (this.checkDocComment) { this.docComment = new Javadoc(this.javadocStart, this.javadocEnd); + this.docComment.isMarkdown = this.markdown; } else if (this.setJavadocPositions) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=189459 // if annotation processors are there, javadoc object is required but // they need not be resolved this.docComment = new Javadoc(this.javadocStart, this.javadocEnd); + this.docComment.isMarkdown = this.markdown; this.docComment.bits &= ~ASTNode.ResolveJavadoc; } else { this.docComment = null; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java index 25b507ada82..b52196f8a21 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java @@ -11499,22 +11499,14 @@ public int flushCommentsDefinedPriorTo(int position) { break; // move valid comment infos, overriding obsolete comment infos case 2: - this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1]; - this.scanner.commentStops[0] = this.scanner.commentStops[index+1]; - this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1]; - this.scanner.commentStarts[1] = this.scanner.commentStarts[index+2]; - this.scanner.commentStops[1] = this.scanner.commentStops[index+2]; - this.scanner.commentTagStarts[1] = this.scanner.commentTagStarts[index+2]; + this.scanner.copyCommentInfo(0, index+1); + this.scanner.copyCommentInfo(1, index+2); break; case 1: - this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1]; - this.scanner.commentStops[0] = this.scanner.commentStops[index+1]; - this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1]; + this.scanner.copyCommentInfo(0, index+1); break; default: - System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount); - System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount); - System.arraycopy(this.scanner.commentTagStarts, index + 1, this.scanner.commentTagStarts, 0, validCount); + this.scanner.copyAllCommentInfo(index+1, 0, validCount); } this.scanner.commentPtr = validCount - 1; return position; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java index 98c4d3bf8dd..96b7b9bb684 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java @@ -92,6 +92,7 @@ public class Scanner implements TerminalTokens { public final static int COMMENT_ARRAYS_SIZE = 30; public int[] commentStops = new int[COMMENT_ARRAYS_SIZE]; public int[] commentStarts = new int[COMMENT_ARRAYS_SIZE]; + public boolean[] commentIsMarkdown = new boolean[COMMENT_ARRAYS_SIZE]; public int[] commentTagStarts = new int[COMMENT_ARRAYS_SIZE]; public int commentPtr = -1; // no comment test with commentPtr value -1 public int lastCommentLinePosition = -1; @@ -3215,6 +3216,7 @@ public void recordComment(int token) { // compute position int commentStart = this.startPosition; int stopPosition = this.currentPosition; + boolean isMarkdown = false; switch (token) { case TokenNameCOMMENT_LINE: // both positions are negative @@ -3226,6 +3228,7 @@ public void recordComment(int token) { stopPosition = -this.currentPosition; break; case TokenNameCOMMENT_MARKDOWN: + isMarkdown = true; break; } @@ -3233,12 +3236,11 @@ public void recordComment(int token) { int length = this.commentStops.length; if (++this.commentPtr >= length) { int newLength = length + COMMENT_ARRAYS_SIZE*10; - System.arraycopy(this.commentStops, 0, this.commentStops = new int[newLength], 0, length); - System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[newLength], 0, length); - System.arraycopy(this.commentTagStarts, 0, this.commentTagStarts = new int[newLength], 0, length); + growCommentInfoArrays(length, newLength); } this.commentStops[this.commentPtr] = stopPosition; this.commentStarts[this.commentPtr] = commentStart; + this.commentIsMarkdown[this.commentPtr] = isMarkdown; } /** @@ -5938,6 +5940,25 @@ public static InvalidInputException invalidInput() { return new InvalidInputException(); } +public void copyCommentInfo(int to, int from) { + this.commentStarts[to] = this.commentStarts[from]; + this.commentStops[to] = this.commentStops[from]; + this.commentTagStarts[to] = this.commentTagStarts[from]; + this.commentIsMarkdown[to] = this.commentIsMarkdown[from]; +} + +public void copyAllCommentInfo(int from, int to, int length) { + System.arraycopy(this.commentStarts, from, this.commentStarts, to, length); + System.arraycopy(this.commentStops, from, this.commentStops, to, length); + System.arraycopy(this.commentTagStarts, from, this.commentTagStarts, to, length); + System.arraycopy(this.commentIsMarkdown, from, this.commentIsMarkdown, 0, length); +} +protected void growCommentInfoArrays(int length, int newLength) { + System.arraycopy(this.commentStops, 0, this.commentStops = new int[newLength], 0, length); + System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[newLength], 0, length); + System.arraycopy(this.commentIsMarkdown, 0, this.commentIsMarkdown = new boolean[newLength], 0, length); + System.arraycopy(this.commentTagStarts, 0, this.commentTagStarts = new int[newLength], 0, length); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTest.java index e016862438f..1506e5efefe 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTest.java @@ -31,7 +31,7 @@ public class PrimitiveInPatternsTest extends AbstractRegressionTest9 { static { // TESTS_NUMBERS = new int [] { 1 }; // TESTS_RANGE = new int[] { 1, -1 }; -// TESTS_NAMES = new String[] { "test267" }; + TESTS_NAMES = new String[] { "test268" }; } private String extraLibPath; public static Class testClass() { @@ -6782,6 +6782,25 @@ public static void main(String[] args) { }, "1"); } + // switch test cases + public void test268() { + runConformTest(new String[] { + "X.java", + """ + public class X { + public static int foo(int i) { + return switch (i) { + case int k -> 100; + }; + } + public static void main(String argv[]) { + System.out.println(X.foo(0)); + } + } + """ + }, + "100"); + } public void testNonPrim001() { runConformTest(new String[] { "X.java", @@ -6802,7 +6821,8 @@ public static void main(String argv[]) { """ }, "true"); - } // test from spec + } + // test from spec public void _testSpec001() { runConformTest(new String[] { "X.java", diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterMarkdownTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterMarkdownTest.java index 4325ea23868..eabde5d5dde 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterMarkdownTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterMarkdownTest.java @@ -3327,6 +3327,7 @@ void numberOfSpaces2() { } Comment comment = (Comment) unitComments.get(0); assertEquals("Comment should be javadoc", comment.getNodeType(), ASTNode.JAVADOC); Javadoc docComment = (Javadoc) comment; + assertTrue(this.prefix+"should be markdown", docComment.isMarkdown()); assertEquals(this.prefix+"Wrong number of tags", 1, docComment.tags().size()); TagElement tagElement = (TagElement) docComment.tags().get(0); diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters index 444ece9cff2..19c6561634e 100644 --- a/org.eclipse.jdt.core/.settings/.api_filters +++ b/org.eclipse.jdt.core/.settings/.api_filters @@ -205,6 +205,14 @@ + + + + + + + + diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java index 3f1fb22031f..b24171989d9 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java @@ -112,6 +112,7 @@ public boolean checkDeprecation(int commentPtr) { @Override protected boolean commentParse() { this.docComment = new CompletionJavadoc(this.javadocStart, this.javadocEnd); + this.docComment.isMarkdown = this.markdown; this.firstTagPosition = 1; // bug 429340: completion parser needs to parse the whole comment return super.commentParse(); } diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java index 73886c211eb..7c407a4dd38 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java @@ -65,6 +65,7 @@ public boolean checkDeprecation(int commentPtr) { @Override protected boolean commentParse() { this.docComment = new SelectionJavadoc(this.javadocStart, this.javadocEnd); + this.docComment.isMarkdown = this.markdown; return super.commentParse(); } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java index 281b70b421a..99840c7c821 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java @@ -80,6 +80,9 @@ public Javadoc parse(int start, int length) { commentParse(); } this.docComment.setSourceRange(start, length); + if (this.ast.apiLevel >= AST.JLS23_INTERNAL) { + this.docComment.setMarkdown(this.markdown); + } if (this.ast.apiLevel == AST.JLS2_INTERNAL) { setComment(start, length); // backward compatibility } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java index f6d46fa3c57..c3e37dd36bc 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java @@ -181,6 +181,7 @@ public static List propertyDescriptors(int apiLevel) { * @exception UnsupportedOperationException if this operation is used in * an AST below JLS23 * @since 3.39 + * @noreference preview feature */ public List modifiers() { if (this.ast.apiLevel < AST.JLS23_INTERNAL) @@ -202,6 +203,7 @@ public List modifiers() { * @return the bit-wise "or" of Modifier constants * @see Modifier * @since 3.39 + * @noreference preview feature */ public int getModifiers() { if (this.modifiers == null) { diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java index 6b7f9ac59af..80a7889979b 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java @@ -49,6 +49,13 @@ public class Javadoc extends Comment { public static final ChildListPropertyDescriptor TAGS_PROPERTY = new ChildListPropertyDescriptor(Javadoc.class, "tags", TagElement.class, CYCLE_RISK); //$NON-NLS-1$ + /** + * The "markdown" structural property of this node type (type: {@link Boolean}) (added in JLS23 API). + * @since 3.39 + * @noreference This field belongs to a preview feature and is not intended to be referenced by clients + */ + public static final SimplePropertyDescriptor MARKDOWN_PROPERTY = + new SimplePropertyDescriptor(Javadoc.class, "static", boolean.class, MANDATORY); //$NON-NLS-1$ /** * A list of property descriptors (element type: @@ -66,6 +73,14 @@ public class Javadoc extends Comment { */ private static final List PROPERTY_DESCRIPTORS_3_0; + /** + * A list of property descriptors (element type: + * {@link StructuralPropertyDescriptor}), + * or null if uninitialized. + * @since 3.39 + */ + private static final List PROPERTY_DESCRIPTORS_23; + static { List properyList = new ArrayList(3); createPropertyList(Javadoc.class, properyList); @@ -77,6 +92,12 @@ public class Javadoc extends Comment { createPropertyList(Javadoc.class, properyList); addProperty(TAGS_PROPERTY, properyList); PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList); + + properyList = new ArrayList(3); + createPropertyList(Javadoc.class, properyList); + addProperty(TAGS_PROPERTY, properyList); + addProperty(MARKDOWN_PROPERTY, properyList); + PROPERTY_DESCRIPTORS_23 = reapPropertyList(properyList); } /** @@ -92,8 +113,10 @@ public class Javadoc extends Comment { public static List propertyDescriptors(int apiLevel) { if (apiLevel == AST.JLS2_INTERNAL) { return PROPERTY_DESCRIPTORS_2_0; - } else { + } else if (apiLevel < AST.JLS23_INTERNAL) { return PROPERTY_DESCRIPTORS_3_0; + } else { + return PROPERTY_DESCRIPTORS_23; } } @@ -120,6 +143,8 @@ public static List propertyDescriptors(int apiLevel) { private final ASTNode.NodeList tags = new ASTNode.NodeList(TAGS_PROPERTY); + private boolean isMarkdown; + /** * Creates a new AST node for a doc comment owned by the given AST. * The new node has an empty list of tag elements (and, for backwards @@ -155,6 +180,20 @@ final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boo return super.internalGetSetObjectProperty(property, get, value); } + @Override + boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) { + if (property == MARKDOWN_PROPERTY) { + if (get) { + return isMarkdown(); + } else { + setMarkdown(value); + return false; + } + } + // allow default implementation to flag the error + return super.internalGetSetBooleanProperty(property, get, value); + } + @Override final List internalGetChildListProperty(ChildListPropertyDescriptor property) { if (property == TAGS_PROPERTY) { @@ -289,9 +328,41 @@ public List tags() { return this.tags; } + /** + * Returns whether this javadoc is a markdown comment (added in JLS23 API). + * + * @return true if this is a markdown comment, + * and false if this is a traditional javadoc comment. + * @since 3.39 + * @noreference preview feature + */ + public boolean isMarkdown() { + if (this.ast.apiLevel < AST.JLS23_INTERNAL) { + throw new UnsupportedOperationException("Operation not supported in AST below JLS23"); //$NON-NLS-1$ + } + return this.isMarkdown; + } + + /** + * Sets whether this javadoc is a markdown comment (added in JLS23 API). + * + * @param isMarkdown true if this is a markdown comment, + * and false if this is a traditional javadoc comment. + * @since 3.39 + * @noreference preview feature + */ + public void setMarkdown(boolean isMarkdown) { + if (this.ast.apiLevel < AST.JLS23_INTERNAL) { + throw new UnsupportedOperationException("Operation not supported in AST below JLS23"); //$NON-NLS-1$ + } + preValueChange(MARKDOWN_PROPERTY); + this.isMarkdown = isMarkdown; + postValueChange(MARKDOWN_PROPERTY); + } + @Override int memSize() { - int size = super.memSize() + 2 * 4; + int size = super.memSize() + 3 * 4; if (this.comment != MINIMAL_DOC_COMMENT) { // anything other than the default string takes space size += stringSize(this.comment); diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java index 1cc5704b999..58ac13df172 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java @@ -807,6 +807,7 @@ public boolean isNonSealed() { * * @return true if the receiver is the module modifier, false otherwise * @since 3.39 + * @noreference preview feature */ public static boolean isModule(int flags) { return (flags & Modifier.MODULE) != 0; diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java index a6003d06695..10aa3e1bbe5 100644 --- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java +++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CommentsPreparator.java @@ -20,6 +20,7 @@ import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_BLOCK; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_JAVADOC; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_LINE; +import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_MARKDOWN; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameNotAToken; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameStringLiteral; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameTextBlock; @@ -587,7 +588,7 @@ public boolean visit(Javadoc node) { this.commonAttributeAnnotations.clear(); this.ctm = null; - int commentIndex = this.tm.firstIndexIn(node, TokenNameCOMMENT_JAVADOC); + int commentIndex = this.tm.firstIndexIn(node, node.isMarkdown() ? TokenNameCOMMENT_MARKDOWN : TokenNameCOMMENT_JAVADOC); Token commentToken = this.tm.get(commentIndex); if (node.getParent() == null) { @@ -1209,7 +1210,8 @@ private boolean tokenizeMultilineComment(Token commentToken) { if (this.allowSubstituteWrapping == null || this.allowSubstituteWrapping.length < commentToken.countChars()) { this.allowSubstituteWrapping = new boolean[commentToken.countChars()]; } - boolean isJavadoc = commentToken.tokenType == TokenNameCOMMENT_JAVADOC; + boolean isMarkdown = commentToken.tokenType == TokenNameCOMMENT_MARKDOWN; + boolean isJavadoc = commentToken.tokenType == TokenNameCOMMENT_JAVADOC || isMarkdown; Arrays.fill(this.allowSubstituteWrapping, 0, commentToken.countChars(), !isJavadoc); final boolean cleanBlankLines = isJavadoc ? this.options.comment_clear_blank_lines_in_javadoc_comment @@ -1218,14 +1220,15 @@ private boolean tokenizeMultilineComment(Token commentToken) { List structure = new ArrayList<>(); int firstTokenEnd = commentToken.originalStart + 1; - while (firstTokenEnd < commentToken.originalEnd - 1 && this.tm.charAt(firstTokenEnd + 1) == '*') + char markerChar = isMarkdown ? '/' : '*'; + while (firstTokenEnd < commentToken.originalEnd - 1 && this.tm.charAt(firstTokenEnd + 1) == markerChar) firstTokenEnd++; Token first = new Token(commentToken.originalStart, firstTokenEnd, commentToken.tokenType); first.spaceAfter(); structure.add(first); int lastTokenStart = commentToken.originalEnd - 1; - while (lastTokenStart - 1 > firstTokenEnd && this.tm.charAt(lastTokenStart - 1) == '*') + while (lastTokenStart - 1 > firstTokenEnd && this.tm.charAt(lastTokenStart - 1) == markerChar) lastTokenStart--; int position = firstTokenEnd + 1; @@ -1241,7 +1244,7 @@ private boolean tokenizeMultilineComment(Token commentToken) { i++; position = i + 1; } else if (!ScannerHelper.isWhitespace(c)) { - while (this.tm.charAt(i) == '*' && lineBreaks > 0) + while (this.tm.charAt(i) == markerChar && lineBreaks > 0) i++; position = i; break; diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java index 34b7864ee26..0c5a2e82876 100644 --- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java +++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TextEditsBuilder.java @@ -16,6 +16,7 @@ import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_LINE; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_BLOCK; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_JAVADOC; +import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_MARKDOWN; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameNotAToken; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameStringLiteral; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameTextBlock; @@ -121,6 +122,12 @@ protected boolean token(Token token, int index) { bufferWhitespaceBefore(token, index); + if (token.tokenType == TokenNameCOMMENT_MARKDOWN) { + flushBuffer(token.originalStart); + this.counter = token.originalEnd + 1; + return true; // don't touch markdown format for now. + } + List structure = token.getInternalStructure(); if (token.tokenType == TokenNameCOMMENT_LINE) { handleSingleLineComment(token, index); diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Token.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Token.java index ca4d701f382..638cd1010bc 100644 --- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Token.java +++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Token.java @@ -17,6 +17,7 @@ import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_BLOCK; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_JAVADOC; import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_LINE; +import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_MARKDOWN; import java.util.List; @@ -142,7 +143,7 @@ public Token(Token tokenToCopy, int newOriginalStart, int newOriginalEnd, int ne public static Token fromCurrent(Scanner scanner, int currentToken) { int start = scanner.getCurrentTokenStartPosition(); int end = scanner.getCurrentTokenEndPosition(); - if (currentToken == TokenNameCOMMENT_LINE) { + if (currentToken == TokenNameCOMMENT_LINE || currentToken == TokenNameCOMMENT_MARKDOWN) { // don't include line separator, but set break-after while (end > start) { char c = scanner.source[end]; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java index 4ad300fbe1f..db43a7c6a1f 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java @@ -182,22 +182,14 @@ public int flushCommentsDefinedPriorTo(int position) { break; // move valid comment infos, overriding obsolete comment infos case 2: - this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1]; - this.scanner.commentStops[0] = this.scanner.commentStops[index+1]; - this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1]; - this.scanner.commentStarts[1] = this.scanner.commentStarts[index+2]; - this.scanner.commentStops[1] = this.scanner.commentStops[index+2]; - this.scanner.commentTagStarts[1] = this.scanner.commentTagStarts[index+2]; + this.scanner.copyCommentInfo(0, index+1); + this.scanner.copyCommentInfo(1, index+2); break; case 1: - this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1]; - this.scanner.commentStops[0] = this.scanner.commentStops[index+1]; - this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1]; + this.scanner.copyCommentInfo(0, index+1); break; default: - System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount); - System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount); - System.arraycopy(this.scanner.commentTagStarts, index + 1, this.scanner.commentTagStarts, 0, validCount); + this.scanner.copyAllCommentInfo(index + 1, 0, validCount); } this.scanner.commentPtr = validCount - 1; return position; @@ -316,6 +308,7 @@ public void resetComments() { Arrays.fill(this.commentStops, 0); Arrays.fill(this.scanner.commentStops, 0); Arrays.fill(this.scanner.commentStarts, 0); + Arrays.fill(this.scanner.commentIsMarkdown, false); Arrays.fill(this.scanner.commentTagStarts, 0); this.scanner.commentPtr = -1; // no comment test with commentPtr value -1 this.scanner.lastCommentLinePosition = -1;