[java-parser] IJ-CR-153901 IDEA-366391 Inconsistent doc comment association after markdown support

- use language level to predict the order of comments

(cherry picked from commit e7986fcb2302dde7ad80fae9346f6a27edb576ae)

GitOrigin-RevId: f1cee2d3123a9a9845f999ac03984427799c84db
This commit is contained in:
Mikhail Pyltsin
2025-02-03 13:44:12 +01:00
committed by intellij-monorepo-bot
parent 19af3dce28
commit 770cfd6fff
24 changed files with 434 additions and 94 deletions

View File

@@ -125,6 +125,7 @@ feature.statements.before.super=Flexible Constructor Bodies
feature.module.import.declarations=Module Import Declarations
feature.package.import.shadow.module.import=Import-on-demand over module import
feature.package.transitive.dependency.on.java.base=Transitive dependency on java.base module
feature.markdown.comment=Markdown Documentation Comments
else.without.if='else' without 'if'
enum.constant.context=Enum constant ''{0}'' in ''{1}''

View File

@@ -119,6 +119,12 @@ public enum JavaFeature {
//see together with PACKAGE_IMPORTS_SHADOW_MODULE_IMPORTS and TRANSITIVE_DEPENDENCY_ON_JAVA_BASE
MODULE_IMPORT_DECLARATIONS(LanguageLevel.JDK_23_PREVIEW, "feature.module.import.declarations"),
/**
* Usually, this type of comments is shown as Javadoc despite language level.
* This option can be used only to adjust behavior for cases with conflicts between different types of comments (markdown and old-style)
*/
MARKDOWN_COMMENT(LanguageLevel.JDK_23, "feature.markdown.comment"),
PACKAGE_IMPORTS_SHADOW_MODULE_IMPORTS(LanguageLevel.JDK_24_PREVIEW, "feature.package.import.shadow.module.import"),
TRANSITIVE_DEPENDENCY_ON_JAVA_BASE(LanguageLevel.JDK_24_PREVIEW, "feature.package.transitive.dependency.on.java.base"),
;

View File

@@ -139,7 +139,7 @@ public class BasicDeclarationParser {
parseClassBodyWithBraces(builder, isAnnotation, isEnum);
}
done(declaration, myJavaElementTypeContainer.CLASS, myWhiteSpaceAndCommentSetHolder);
done(declaration, myJavaElementTypeContainer.CLASS, builder, myWhiteSpaceAndCommentSetHolder);
return declaration;
}
@@ -199,10 +199,10 @@ public class BasicDeclarationParser {
if (builder.getTokenType() == JavaTokenType.LBRACE) {
final PsiBuilder.Marker constantInit = builder.mark();
parseClassBodyWithBraces(builder, false, false);
done(constantInit, myJavaElementTypeContainer.ENUM_CONSTANT_INITIALIZER, myWhiteSpaceAndCommentSetHolder);
done(constantInit, myJavaElementTypeContainer.ENUM_CONSTANT_INITIALIZER, builder, myWhiteSpaceAndCommentSetHolder);
}
done(constant, myJavaElementTypeContainer.ENUM_CONSTANT, myWhiteSpaceAndCommentSetHolder);
done(constant, myJavaElementTypeContainer.ENUM_CONSTANT, builder, myWhiteSpaceAndCommentSetHolder);
return constant;
}
else {
@@ -317,7 +317,7 @@ public class BasicDeclarationParser {
error.errorBefore(JavaPsiBundle.message("unexpected.token"), codeBlock);
}
done(declaration, myJavaElementTypeContainer.CLASS_INITIALIZER, myWhiteSpaceAndCommentSetHolder);
done(declaration, myJavaElementTypeContainer.CLASS_INITIALIZER, builder, myWhiteSpaceAndCommentSetHolder);
return declaration;
}
@@ -477,7 +477,7 @@ public class BasicDeclarationParser {
}
}
done(modList, myJavaElementTypeContainer.MODIFIER_LIST, myWhiteSpaceAndCommentSetHolder);
done(modList, myJavaElementTypeContainer.MODIFIER_LIST, builder, myWhiteSpaceAndCommentSetHolder);
return Pair.create(modList, isEmpty);
}
@@ -526,7 +526,7 @@ public class BasicDeclarationParser {
}
}
done(declaration, anno ? myJavaElementTypeContainer.ANNOTATION_METHOD : myJavaElementTypeContainer.METHOD,
done(declaration, anno ? myJavaElementTypeContainer.ANNOTATION_METHOD : myJavaElementTypeContainer.METHOD, builder,
myWhiteSpaceAndCommentSetHolder);
return declaration;
}
@@ -666,7 +666,7 @@ public class BasicDeclarationParser {
invalidElements.error(errorMessage);
}
done(elementList, type.getNodeType(myJavaElementTypeContainer), myWhiteSpaceAndCommentSetHolder);
done(elementList, type.getNodeType(myJavaElementTypeContainer), builder, myWhiteSpaceAndCommentSetHolder);
}
@Nullable
@@ -742,7 +742,7 @@ public class BasicDeclarationParser {
PsiBuilder.Marker expr = myParser.getExpressionParser().parse(builder);
if (expr != null && exprType(expr) == myJavaElementTypeContainer.THIS_EXPRESSION) {
mark.drop();
done(param, myJavaElementTypeContainer.RECEIVER_PARAMETER, myWhiteSpaceAndCommentSetHolder);
done(param, myJavaElementTypeContainer.RECEIVER_PARAMETER, builder, myWhiteSpaceAndCommentSetHolder);
return param;
}
@@ -753,7 +753,7 @@ public class BasicDeclarationParser {
if (expect(builder, JavaTokenType.IDENTIFIER)) {
if (type == myJavaElementTypeContainer.PARAMETER || type == myJavaElementTypeContainer.RECORD_COMPONENT) {
eatBrackets(builder, null);
done(param, type, myWhiteSpaceAndCommentSetHolder);
done(param, type, builder, myWhiteSpaceAndCommentSetHolder);
return param;
}
}
@@ -769,7 +769,7 @@ public class BasicDeclarationParser {
}
}
done(param, myJavaElementTypeContainer.RESOURCE_VARIABLE, myWhiteSpaceAndCommentSetHolder);
done(param, myJavaElementTypeContainer.RESOURCE_VARIABLE, builder, myWhiteSpaceAndCommentSetHolder);
return param;
}
@@ -816,7 +816,7 @@ public class BasicDeclarationParser {
}
if (builder.getTokenType() != JavaTokenType.COMMA) break;
done(variable, varType, myWhiteSpaceAndCommentSetHolder);
done(variable, varType, builder, myWhiteSpaceAndCommentSetHolder);
builder.advanceLexer();
if (builder.getTokenType() != JavaTokenType.IDENTIFIER) {
@@ -855,7 +855,7 @@ public class BasicDeclarationParser {
}
if (openMarker) {
done(variable, varType, myWhiteSpaceAndCommentSetHolder);
done(variable, varType, builder, myWhiteSpaceAndCommentSetHolder);
}
return declaration;
@@ -928,7 +928,7 @@ public class BasicDeclarationParser {
parseAnnotationParameterList(builder);
done(anno, myJavaElementTypeContainer.ANNOTATION, myWhiteSpaceAndCommentSetHolder);
done(anno, myJavaElementTypeContainer.ANNOTATION, builder, myWhiteSpaceAndCommentSetHolder);
return anno;
}
@@ -936,13 +936,13 @@ public class BasicDeclarationParser {
PsiBuilder.Marker list = builder.mark();
if (!expect(builder, JavaTokenType.LPARENTH) || expect(builder, JavaTokenType.RPARENTH)) {
done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, myWhiteSpaceAndCommentSetHolder);
done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, builder, myWhiteSpaceAndCommentSetHolder);
return;
}
if (builder.getTokenType() == null) {
error(builder, JavaPsiBundle.message("expected.parameter.or.rparen"));
done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, myWhiteSpaceAndCommentSetHolder);
done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, builder, myWhiteSpaceAndCommentSetHolder);
return;
}
PsiBuilder.Marker elementMarker = parseAnnotationElement(builder);
@@ -974,7 +974,7 @@ public class BasicDeclarationParser {
}
}
done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, myWhiteSpaceAndCommentSetHolder);
done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, builder, myWhiteSpaceAndCommentSetHolder);
}
private PsiBuilder.Marker parseAnnotationElement(final PsiBuilder builder) {
@@ -986,7 +986,7 @@ public class BasicDeclarationParser {
return null;
}
if (builder.getTokenType() != JavaTokenType.EQ) {
done(pair, myJavaElementTypeContainer.NAME_VALUE_PAIR, myWhiteSpaceAndCommentSetHolder);
done(pair, myJavaElementTypeContainer.NAME_VALUE_PAIR, builder, myWhiteSpaceAndCommentSetHolder);
return pair;
}
@@ -998,7 +998,7 @@ public class BasicDeclarationParser {
valueMarker = parseAnnotationValue(builder);
if (valueMarker == null) error(builder, JavaPsiBundle.message("expected.value"));
done(pair, myJavaElementTypeContainer.NAME_VALUE_PAIR, myWhiteSpaceAndCommentSetHolder);
done(pair, myJavaElementTypeContainer.NAME_VALUE_PAIR, builder, myWhiteSpaceAndCommentSetHolder);
return pair;
}

View File

@@ -93,12 +93,12 @@ public class BasicFileParser {
}
if (impListInfo.second && firstDeclarationOk == Boolean.TRUE) {
impListInfo.first.setCustomEdgeTokenBinders(myWhiteSpaceAndCommentSetHolder.getPrecedingCommentBinder(), null); // pass comments behind fake import list
firstDeclaration.setCustomEdgeTokenBinders(myWhiteSpaceAndCommentSetHolder.getSpecialPrecedingCommentBinder(), null);
impListInfo.first.setCustomEdgeTokenBinders(myWhiteSpaceAndCommentSetHolder.getPrecedingCommentBinder(getLanguageLevel(builder)), null); // pass comments behind fake import list
firstDeclaration.setCustomEdgeTokenBinders(myWhiteSpaceAndCommentSetHolder.getSpecialPrecedingCommentBinder(getLanguageLevel(builder)), null);
}
if (isImplicitClass) {
PsiBuilder.Marker beforeFirst = firstDeclaration.precede();
done(beforeFirst, myJavaElementTypeContainer.IMPLICIT_CLASS, myWhiteSpaceAndCommentSetHolder);
done(beforeFirst, myJavaElementTypeContainer.IMPLICIT_CLASS, builder, myWhiteSpaceAndCommentSetHolder);
}
}
@@ -123,7 +123,7 @@ public class BasicFileParser {
if (!expect(builder, JavaTokenType.PACKAGE_KEYWORD)) {
PsiBuilder.Marker modList = builder.mark();
myParser.getDeclarationParser().parseAnnotations(builder);
done(modList, myJavaElementTypeContainer.MODIFIER_LIST, myWhiteSpaceAndCommentSetHolder);
done(modList, myJavaElementTypeContainer.MODIFIER_LIST, builder, myWhiteSpaceAndCommentSetHolder);
if (!expect(builder, JavaTokenType.PACKAGE_KEYWORD)) {
statement.rollbackTo();
return;
@@ -138,7 +138,7 @@ public class BasicFileParser {
semicolon(builder);
done(statement, myJavaElementTypeContainer.PACKAGE_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.PACKAGE_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
}
@NotNull
@@ -182,7 +182,7 @@ public class BasicFileParser {
list = precede;
}
done(list, myJavaElementTypeContainer.IMPORT_LIST, myWhiteSpaceAndCommentSetHolder);
done(list, myJavaElementTypeContainer.IMPORT_LIST, builder, myWhiteSpaceAndCommentSetHolder);
return Pair.create(list, isEmpty);
}
@@ -213,7 +213,7 @@ public class BasicFileParser {
semicolon(builder);
}
done(statement, type, myWhiteSpaceAndCommentSetHolder);
done(statement, type, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}

View File

@@ -61,10 +61,30 @@ public final class BasicJavaParserUtil {
return Boolean.TRUE.equals(builder.getUserData(DEEP_PARSE_BLOCKS_IN_STATEMENTS));
}
public static void done(final PsiBuilder.Marker marker, final IElementType type, final WhiteSpaceAndCommentSetHolder commentSetHolder) {
/**
* @deprecated use {@link BasicJavaParserUtil#done(PsiBuilder.Marker, IElementType, PsiBuilder, WhiteSpaceAndCommentSetHolder)}
*/
@Deprecated
public static void done(final @NotNull PsiBuilder.Marker marker,
final @NotNull IElementType type,
final @NotNull WhiteSpaceAndCommentSetHolder commentSetHolder) {
marker.done(type);
final WhitespacesAndCommentsBinder left =
commentSetHolder.getPrecedingCommentSet().contains(type) ? commentSetHolder.getPrecedingCommentBinder()
commentSetHolder.getPrecedingCommentSet().contains(type) ? commentSetHolder.getPrecedingCommentBinder(LanguageLevel.HIGHEST)
: null;
final WhitespacesAndCommentsBinder right =
commentSetHolder.getTrailingCommentSet().contains(type) ? commentSetHolder.getTrailingCommentBinder()
: null;
marker.setCustomEdgeTokenBinders(left, right);
}
public static void done(final @NotNull PsiBuilder.Marker marker,
final @NotNull IElementType type,
final @NotNull PsiBuilder builder,
final @NotNull WhiteSpaceAndCommentSetHolder commentSetHolder) {
marker.done(type);
final WhitespacesAndCommentsBinder left =
commentSetHolder.getPrecedingCommentSet().contains(type) ? commentSetHolder.getPrecedingCommentBinder(getLanguageLevel(builder))
: null;
final WhitespacesAndCommentsBinder right =
commentSetHolder.getTrailingCommentSet().contains(type) ? commentSetHolder.getTrailingCommentBinder()

View File

@@ -51,7 +51,7 @@ public class BasicModuleParser {
mapAndAdvance(builder, JavaTokenType.OPEN_KEYWORD);
text = builder.getTokenText();
}
BasicJavaParserUtil.done(modifierList, myJavaElementTypeContainer.MODIFIER_LIST, myWhiteSpaceAndCommentSetHolder);
BasicJavaParserUtil.done(modifierList, myJavaElementTypeContainer.MODIFIER_LIST, builder, myWhiteSpaceAndCommentSetHolder);
if (PsiKeyword.MODULE.equals(text)) {
mapAndAdvance(builder, JavaTokenType.MODULE_KEYWORD);
@@ -85,7 +85,7 @@ public class BasicModuleParser {
parseModuleContent(builder);
}
BasicJavaParserUtil.done(module, myJavaElementTypeContainer.MODULE, myWhiteSpaceAndCommentSetHolder);
BasicJavaParserUtil.done(module, myJavaElementTypeContainer.MODULE, builder, myWhiteSpaceAndCommentSetHolder);
if (builder.getTokenType() != null) {
parseExtras(builder, JavaPsiBundle.message("unexpected.tokens"));
@@ -186,7 +186,7 @@ public class BasicModuleParser {
}
break;
}
BasicJavaParserUtil.done(modifierList, myJavaElementTypeContainer.MODIFIER_LIST, myWhiteSpaceAndCommentSetHolder);
BasicJavaParserUtil.done(modifierList, myJavaElementTypeContainer.MODIFIER_LIST, builder, myWhiteSpaceAndCommentSetHolder);
if (parseNameRef(builder) != null) {
semicolon(builder);

View File

@@ -47,7 +47,7 @@ public class BasicPatternParser {
"_".equals(builder.getTokenText())) {
emptyElement(builder, myJavaElementTypeContainer.TYPE);
builder.advanceLexer();
done(patternStart, myJavaElementTypeContainer.UNNAMED_PATTERN, myWhiteSpaceAndCommentSetHolder);
done(patternStart, myJavaElementTypeContainer.UNNAMED_PATTERN, builder, myWhiteSpaceAndCommentSetHolder);
return true;
}
patternStart.rollbackTo();
@@ -160,16 +160,16 @@ public class BasicPatternParser {
if (isRecord) {
patternVariable.drop();
done(pattern, myJavaElementTypeContainer.DECONSTRUCTION_PATTERN, myWhiteSpaceAndCommentSetHolder);
done(pattern, myJavaElementTypeContainer.DECONSTRUCTION_PATTERN, builder, myWhiteSpaceAndCommentSetHolder);
}
else {
if (hasIdentifier) {
done(patternVariable, myJavaElementTypeContainer.PATTERN_VARIABLE, myWhiteSpaceAndCommentSetHolder);
done(patternVariable, myJavaElementTypeContainer.PATTERN_VARIABLE, builder, myWhiteSpaceAndCommentSetHolder);
}
else {
patternVariable.drop();
}
done(pattern, myJavaElementTypeContainer.TYPE_TEST_PATTERN, myWhiteSpaceAndCommentSetHolder);
done(pattern, myJavaElementTypeContainer.TYPE_TEST_PATTERN, builder, myWhiteSpaceAndCommentSetHolder);
}
return pattern;
}

View File

@@ -973,7 +973,7 @@ public class BasicPrattExpressionParser {
if (right == null) {
error(builder, JavaPsiBundle.message("expected.expression"));
}
done(beforeLhs, myJavaElementTypeContainer.ASSIGNMENT_EXPRESSION, myWhiteSpaceAndCommentSetHolder);
done(beforeLhs, myJavaElementTypeContainer.ASSIGNMENT_EXPRESSION, builder, myWhiteSpaceAndCommentSetHolder);
}
}
@@ -1001,7 +1001,7 @@ public class BasicPrattExpressionParser {
}
done(beforeLhs, operandCount > 2
? myJavaElementTypeContainer.POLYADIC_EXPRESSION
: myJavaElementTypeContainer.BINARY_EXPRESSION, myWhiteSpaceAndCommentSetHolder);
: myJavaElementTypeContainer.BINARY_EXPRESSION, builder, myWhiteSpaceAndCommentSetHolder);
}
}

View File

@@ -82,7 +82,7 @@ public class BasicStatementParser {
boolean greedyBlock = !expectOrError(builder, JavaTokenType.RBRACE, "expected.rbrace");
builder.getTokenType(); // eat spaces
done(codeBlock, myJavaElementTypeContainer.CODE_BLOCK, myWhiteSpaceAndCommentSetHolder);
done(codeBlock, myJavaElementTypeContainer.CODE_BLOCK, builder, myWhiteSpaceAndCommentSetHolder);
if (greedyBlock) {
codeBlock.setCustomEdgeTokenBinders(null, WhitespacesBinders.GREEDY_RIGHT_BINDER);
}
@@ -176,7 +176,7 @@ public class BasicStatementParser {
else if (tokenType == JavaTokenType.SEMICOLON) {
PsiBuilder.Marker empty = builder.mark();
builder.advanceLexer();
done(empty, myJavaElementTypeContainer.EMPTY_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(empty, myJavaElementTypeContainer.EMPTY_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return empty;
}
else if (tokenType == JavaTokenType.IDENTIFIER || tokenType == JavaTokenType.AT) {
@@ -191,7 +191,7 @@ public class BasicStatementParser {
PsiBuilder.Marker declStatement = builder.mark();
if (myParser.getDeclarationParser().parse(builder, BasicDeclarationParser.BaseContext.CODE_BLOCK) != null) {
done(declStatement, myJavaElementTypeContainer.DECLARATION_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(declStatement, myJavaElementTypeContainer.DECLARATION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return declStatement;
}
@@ -202,7 +202,7 @@ public class BasicStatementParser {
else if (type == null || builder.getTokenType() != JavaTokenType.DOUBLE_COLON) {
error(builder, JavaPsiBundle.message("expected.identifier"));
if (type == null) builder.advanceLexer();
done(declStatement, myJavaElementTypeContainer.DECLARATION_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(declStatement, myJavaElementTypeContainer.DECLARATION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return declStatement;
}
else {
@@ -231,15 +231,15 @@ public class BasicStatementParser {
}
if (count > 1) {
pos.drop();
done(list, myJavaElementTypeContainer.EXPRESSION_LIST, myWhiteSpaceAndCommentSetHolder);
done(list, myJavaElementTypeContainer.EXPRESSION_LIST, builder, myWhiteSpaceAndCommentSetHolder);
semicolon(builder);
done(statement, myJavaElementTypeContainer.EXPRESSION_LIST_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.EXPRESSION_LIST_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
if (exprType(expr) != myJavaElementTypeContainer.REFERENCE_EXPRESSION) {
drop(list, pos);
semicolon(builder);
done(statement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
pos.rollbackTo();
@@ -251,7 +251,7 @@ public class BasicStatementParser {
PsiBuilder.Marker decl = myParser.getDeclarationParser().parse(builder, BasicDeclarationParser.BaseContext.CODE_BLOCK);
if (decl != null) {
PsiBuilder.Marker statement = decl.precede();
done(statement, myJavaElementTypeContainer.DECLARATION_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.DECLARATION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -259,7 +259,7 @@ public class BasicStatementParser {
PsiBuilder.Marker statement = builder.mark();
advance(builder, 2);
parseStatement(builder);
done(statement, myJavaElementTypeContainer.LABELED_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.LABELED_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -267,7 +267,7 @@ public class BasicStatementParser {
PsiBuilder.Marker statement = builder.mark();
myParser.getExpressionParser().parse(builder);
semicolon(builder);
done(statement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -331,11 +331,11 @@ public class BasicStatementParser {
}
break;
}
done(statement, myJavaElementTypeContainer.IF_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.IF_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
if (stack != null) {
for (int i = stack.size() - 1; i >= 0; i--) {
statement = stack.get(i);
done(statement, myJavaElementTypeContainer.IF_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.IF_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
}
}
return statement;
@@ -391,7 +391,7 @@ public class BasicStatementParser {
if (!expect(builder, JavaTokenType.LPARENTH)) {
error(builder, JavaPsiBundle.message("expected.lparen"));
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -405,7 +405,7 @@ public class BasicStatementParser {
while (true) {
IElementType tokenType = builder.getTokenType();
if (tokenType == null) {
done(statement, myJavaElementTypeContainer.FOREACH_PATTERN_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.FOREACH_PATTERN_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
if (tokenType == JavaTokenType.RPARENTH) {
@@ -432,7 +432,7 @@ public class BasicStatementParser {
if (parseStatement(builder) == null) {
error(builder, JavaPsiBundle.message("expected.statement"));
if (!expect(builder, JavaTokenType.RPARENTH)) {
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
}
@@ -450,7 +450,7 @@ public class BasicStatementParser {
error(builder, JavaPsiBundle.message("expected.semicolon"));
}
if (!expect(builder, JavaTokenType.RPARENTH)) {
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
}
@@ -458,7 +458,7 @@ public class BasicStatementParser {
parseForUpdateExpressions(builder);
if (!expect(builder, JavaTokenType.RPARENTH)) {
error(builder, JavaPsiBundle.message("expected.rparen"));
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
}
@@ -469,7 +469,7 @@ public class BasicStatementParser {
error(builder, JavaPsiBundle.message("expected.statement"));
}
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -487,7 +487,7 @@ public class BasicStatementParser {
PsiBuilder.Marker expressionStatement;
if (builder.getTokenType() != JavaTokenType.COMMA) {
expressionStatement = expr.precede();
done(expressionStatement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(expressionStatement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
}
else {
PsiBuilder.Marker expressionList = expr.precede();
@@ -502,8 +502,8 @@ public class BasicStatementParser {
}
while (builder.getTokenType() == JavaTokenType.COMMA);
done(expressionList, myJavaElementTypeContainer.EXPRESSION_LIST, myWhiteSpaceAndCommentSetHolder);
done(expressionStatement, myJavaElementTypeContainer.EXPRESSION_LIST_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(expressionList, myJavaElementTypeContainer.EXPRESSION_LIST, builder, myWhiteSpaceAndCommentSetHolder);
done(expressionStatement, myJavaElementTypeContainer.EXPRESSION_LIST_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
}
expressionStatement.setCustomEdgeTokenBinders(null, WhitespacesBinders.DEFAULT_RIGHT_BINDER);
@@ -525,7 +525,7 @@ public class BasicStatementParser {
error(builder, JavaPsiBundle.message("expected.statement"));
}
done(statement, forEachType, myWhiteSpaceAndCommentSetHolder);
done(statement, forEachType, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -545,7 +545,7 @@ public class BasicStatementParser {
semicolon(builder);
}
done(statement, myJavaElementTypeContainer.DO_WHILE_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.DO_WHILE_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -563,7 +563,7 @@ public class BasicStatementParser {
if (builder.getTokenType() == JavaTokenType.DEFAULT_KEYWORD) {
PsiBuilder.Marker defaultElement = builder.mark();
builder.advanceLexer();
done(defaultElement, myJavaElementTypeContainer.DEFAULT_CASE_LABEL_ELEMENT, myWhiteSpaceAndCommentSetHolder);
done(defaultElement, myJavaElementTypeContainer.DEFAULT_CASE_LABEL_ELEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return Pair.create(defaultElement, false);
}
if (myParser.getPatternParser().isPattern(builder)) {
@@ -589,7 +589,7 @@ public class BasicStatementParser {
}
}
while (expect(builder, JavaTokenType.COMMA));
done(list, myJavaElementTypeContainer.CASE_LABEL_ELEMENT_LIST, myWhiteSpaceAndCommentSetHolder);
done(list, myJavaElementTypeContainer.CASE_LABEL_ELEMENT_LIST, builder, myWhiteSpaceAndCommentSetHolder);
parseGuard(builder);
}
@@ -617,11 +617,11 @@ public class BasicStatementParser {
error(builder, JavaPsiBundle.message("expected.switch.rule"));
expect(builder, JavaTokenType.SEMICOLON);
}
done(statement, myJavaElementTypeContainer.SWITCH_LABELED_RULE, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.SWITCH_LABELED_RULE, builder, myWhiteSpaceAndCommentSetHolder);
}
else {
expectOrError(builder, JavaTokenType.COLON, "expected.colon.or.arrow");
done(statement, myJavaElementTypeContainer.SWITCH_LABEL_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.SWITCH_LABEL_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
}
return statement;
@@ -644,7 +644,7 @@ public class BasicStatementParser {
builder.advanceLexer();
expect(builder, JavaTokenType.IDENTIFIER);
semicolon(builder);
done(statement, myJavaElementTypeContainer.BREAK_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.BREAK_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -661,7 +661,7 @@ public class BasicStatementParser {
semicolon(builder);
}
done(statement, myJavaElementTypeContainer.YIELD_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.YIELD_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -671,7 +671,7 @@ public class BasicStatementParser {
builder.advanceLexer();
expect(builder, JavaTokenType.IDENTIFIER);
semicolon(builder);
done(statement, myJavaElementTypeContainer.CONTINUE_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.CONTINUE_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -681,7 +681,7 @@ public class BasicStatementParser {
builder.advanceLexer();
myParser.getExpressionParser().parse(builder);
semicolon(builder);
done(statement, myJavaElementTypeContainer.RETURN_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.RETURN_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -697,7 +697,7 @@ public class BasicStatementParser {
semicolon(builder);
}
done(statement, myJavaElementTypeContainer.THROW_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.THROW_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -736,7 +736,7 @@ public class BasicStatementParser {
}
}
done(statement, myJavaElementTypeContainer.TRY_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.TRY_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -747,7 +747,7 @@ public class BasicStatementParser {
if (!expect(builder, JavaTokenType.LPARENTH)) {
error(builder, JavaPsiBundle.message("expected.lparen"));
done(section, myJavaElementTypeContainer.CATCH_SECTION, myWhiteSpaceAndCommentSetHolder);
done(section, myJavaElementTypeContainer.CATCH_SECTION, builder, myWhiteSpaceAndCommentSetHolder);
return false;
}
@@ -758,18 +758,18 @@ public class BasicStatementParser {
if (!expect(builder, JavaTokenType.RPARENTH)) {
error(builder, JavaPsiBundle.message("expected.rparen"));
done(section, myJavaElementTypeContainer.CATCH_SECTION, myWhiteSpaceAndCommentSetHolder);
done(section, myJavaElementTypeContainer.CATCH_SECTION, builder, myWhiteSpaceAndCommentSetHolder);
return false;
}
PsiBuilder.Marker body = parseCodeBlock(builder, true);
if (body == null) {
error(builder, JavaPsiBundle.message("expected.lbrace"));
done(section, myJavaElementTypeContainer.CATCH_SECTION, myWhiteSpaceAndCommentSetHolder);
done(section, myJavaElementTypeContainer.CATCH_SECTION, builder, myWhiteSpaceAndCommentSetHolder);
return false;
}
done(section, myJavaElementTypeContainer.CATCH_SECTION, myWhiteSpaceAndCommentSetHolder);
done(section, myJavaElementTypeContainer.CATCH_SECTION, builder, myWhiteSpaceAndCommentSetHolder);
return true;
}
@@ -788,7 +788,7 @@ public class BasicStatementParser {
semicolon(builder);
}
done(statement, myJavaElementTypeContainer.ASSERT_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.ASSERT_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -796,7 +796,7 @@ public class BasicStatementParser {
private PsiBuilder.Marker parseBlockStatement(PsiBuilder builder) {
PsiBuilder.Marker statement = builder.mark();
parseCodeBlock(builder, true);
done(statement, myJavaElementTypeContainer.BLOCK_STATEMENT, myWhiteSpaceAndCommentSetHolder);
done(statement, myJavaElementTypeContainer.BLOCK_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}
@@ -812,7 +812,7 @@ public class BasicStatementParser {
}
}
done(statement, type, myWhiteSpaceAndCommentSetHolder);
done(statement, type, builder, myWhiteSpaceAndCommentSetHolder);
return statement;
}

View File

@@ -3,6 +3,8 @@ package com.intellij.psi.impl.source;
import com.intellij.lang.WhitespacesAndCommentsBinder;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.JavaFeature;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ParentAwareTokenSet;
import com.intellij.psi.tree.TokenSet;
@@ -28,16 +30,22 @@ public class WhiteSpaceAndCommentSetHolder {
private WhiteSpaceAndCommentSetHolder() {
}
private final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER = new PrecedingWhitespacesAndCommentsBinder(false);
private final WhitespacesAndCommentsBinder SPECIAL_PRECEDING_COMMENT_BINDER = new PrecedingWhitespacesAndCommentsBinder(true);
private final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER_WITH_MARKDOWN = new PrecedingWhitespacesAndCommentsBinder(false, true);
private final WhitespacesAndCommentsBinder SPECIAL_PRECEDING_COMMENT_BINDER_WITH_MARKDOWN = new PrecedingWhitespacesAndCommentsBinder(true, true);
private final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN = new PrecedingWhitespacesAndCommentsBinder(false, false);
private final WhitespacesAndCommentsBinder SPECIAL_PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN = new PrecedingWhitespacesAndCommentsBinder(true, false);
private final WhitespacesAndCommentsBinder TRAILING_COMMENT_BINDER = new TrailingWhitespacesAndCommentsBinder();
public WhitespacesAndCommentsBinder getPrecedingCommentBinder() {
return PRECEDING_COMMENT_BINDER;
public WhitespacesAndCommentsBinder getPrecedingCommentBinder(@NotNull LanguageLevel myLanguageLevel) {
return JavaFeature.MARKDOWN_COMMENT.isSufficient(myLanguageLevel)
? PRECEDING_COMMENT_BINDER_WITH_MARKDOWN
: PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN;
}
public WhitespacesAndCommentsBinder getSpecialPrecedingCommentBinder() {
return SPECIAL_PRECEDING_COMMENT_BINDER;
public WhitespacesAndCommentsBinder getSpecialPrecedingCommentBinder(@NotNull LanguageLevel myLanguageLevel) {
return JavaFeature.MARKDOWN_COMMENT.isSufficient(myLanguageLevel)
? SPECIAL_PRECEDING_COMMENT_BINDER_WITH_MARKDOWN
: SPECIAL_PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN;
}
public WhitespacesAndCommentsBinder getTrailingCommentBinder() {
@@ -55,9 +63,11 @@ public class WhiteSpaceAndCommentSetHolder {
private static class PrecedingWhitespacesAndCommentsBinder implements WhitespacesAndCommentsBinder {
private final boolean myAfterEmptyImport;
private final boolean mySupportMarkdown;
PrecedingWhitespacesAndCommentsBinder(final boolean afterImport) {
PrecedingWhitespacesAndCommentsBinder(final boolean afterImport, final boolean supportMarkdown) {
this.myAfterEmptyImport = afterImport;
this.mySupportMarkdown = supportMarkdown;
}
@Override
@@ -67,16 +77,24 @@ public class WhiteSpaceAndCommentSetHolder {
// 1. bind doc comment
// now there are markdown comments.
// To preserve previous orders, let's try to find the first non-markdown comment (and skip markdown comments).
// If there is no non-markdown, take the first markdown
for (int idx = tokens.size() - 1; idx >= 0; idx--) {
if (BasicJavaAstTreeUtil.is(tokens.get(idx), BASIC_DOC_COMMENT) && !isDocMarkdownComment(idx, getter)) {
return idx;
if (mySupportMarkdown) {
//collect everything
for (int idx = tokens.size() - 1; idx >= 0; idx--) {
if (BasicJavaAstTreeUtil.is(tokens.get(idx), BASIC_DOC_COMMENT)) return idx;
}
}
else {
// To preserve previous orders, let's try to find the first non-markdown comment (and skip markdown comments).
// If there is no non-markdown, take the first markdown
for (int idx = tokens.size() - 1; idx >= 0; idx--) {
if (BasicJavaAstTreeUtil.is(tokens.get(idx), BASIC_DOC_COMMENT) && !isDocMarkdownComment(idx, getter)) {
return idx;
}
}
for (int idx = tokens.size() - 1; idx >= 0; idx--) {
if (BasicJavaAstTreeUtil.is(tokens.get(idx), BASIC_DOC_COMMENT)) return idx;
for (int idx = tokens.size() - 1; idx >= 0; idx--) {
if (BasicJavaAstTreeUtil.is(tokens.get(idx), BASIC_DOC_COMMENT)) return idx;
}
}
// 2. bind plain comments

View File

@@ -1,6 +1,7 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.parser;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull;
public abstract class AbstractBasicJavadocParsingTest extends AbstractBasicJavaParsingTestCase {
@@ -213,5 +214,24 @@ public abstract class AbstractBasicJavadocParsingTest extends AbstractBasicJavaP
public void testReferenceLinkMarkdown09() { doTest(true); }
public void testReferenceLinkMarkdown10() { doTest(true); }
public void testReferenceLinkMarkdown11() { doTest(true); }
public void testMarkdownWithDocComment() { doTest(true);}
public void testMarkdownWithDocCommentBeforeMarkdown() {
setLanguageLevel(LanguageLevel.JDK_21);
doTest(true);
}
public void testOnlyMarkdownBeforeMarkdown() {
setLanguageLevel(LanguageLevel.JDK_21);
doTest(true);
}
public void testMarkdownWithDocCommentAfterMarkdown() {
setLanguageLevel(LanguageLevel.JDK_23);
doTest(true);
}
public void testOnlyMarkdownAfterMarkdown() {
setLanguageLevel(LanguageLevel.JDK_23);
doTest(true);
}
}

View File

@@ -42,10 +42,22 @@ public final class JavaParserUtil {
public interface ParserWrapper extends BasicJavaParserUtil.ParserWrapper {
}
/**
* @deprecated please, use {@link WhiteSpaceAndCommentSetHolder#INSTANCE} instead
*/
@Deprecated
public static final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER =
WhiteSpaceAndCommentSetHolder.INSTANCE.getPrecedingCommentBinder();
WhiteSpaceAndCommentSetHolder.INSTANCE.getPrecedingCommentBinder(LanguageLevel.HIGHEST);
/**
* @deprecated please, use {@link WhiteSpaceAndCommentSetHolder#INSTANCE} instead
*/
@Deprecated
public static final WhitespacesAndCommentsBinder SPECIAL_PRECEDING_COMMENT_BINDER =
WhiteSpaceAndCommentSetHolder.INSTANCE.getSpecialPrecedingCommentBinder();
WhiteSpaceAndCommentSetHolder.INSTANCE.getSpecialPrecedingCommentBinder(LanguageLevel.HIGHEST);
/**
* @deprecated please, use {@link WhiteSpaceAndCommentSetHolder#INSTANCE} instead
*/
@Deprecated
public static final WhitespacesAndCommentsBinder TRAILING_COMMENT_BINDER =
WhiteSpaceAndCommentSetHolder.INSTANCE.getTrailingCommentBinder();
@@ -98,6 +110,10 @@ public final class JavaParserUtil {
);
}
/**
* @deprecated use {@link BasicJavaParserUtil#done(PsiBuilder.Marker, IElementType, PsiBuilder, WhiteSpaceAndCommentSetHolder)}
*/
@Deprecated
public static void done(final PsiBuilder.Marker marker, final IElementType type) {
BasicJavaParserUtil.done(marker, type, WhiteSpaceAndCommentSetHolder.INSTANCE);
}

View File

@@ -0,0 +1,46 @@
PsiJavaFile:MarkdownWithDocCommentAfterMarkdown.java
PsiPackageStatement:test.pkg
PsiKeyword:package('package')
PsiWhiteSpace(' ')
PsiJavaCodeReferenceElement:test.pkg
PsiJavaCodeReferenceElement:test
PsiIdentifier:test('test')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiIdentifier:pkg('pkg')
PsiReferenceParameterList
<empty list>
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n\n')
PsiDocComment
PsiDocToken:DOC_COMMENT_START('/**')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('*')
PsiDocToken:DOC_COMMENT_DATA(' Doc')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_END('*/')
PsiWhiteSpace('\n')
PsiImportList
<empty list>
PsiClass:Test
PsiDocComment
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('///')
PsiWhiteSpace(' ')
PsiDocToken:DOC_COMMENT_DATA('Inline comment as markdown')
PsiWhiteSpace('\n')
PsiModifierList:public
PsiKeyword:public('public')
PsiWhiteSpace(' ')
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Test('Test')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')

View File

@@ -0,0 +1,46 @@
java.FILE
PACKAGE_STATEMENT
PACKAGE_KEYWORD
WHITE_SPACE
JAVA_CODE_REFERENCE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
DOT
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
SEMICOLON
WHITE_SPACE
DOC_COMMENT
DOC_COMMENT_START
WHITE_SPACE
DOC_COMMENT_LEADING_ASTERISKS
DOC_COMMENT_DATA
WHITE_SPACE
DOC_COMMENT_END
WHITE_SPACE
IMPORT_LIST
<empty list>
CLASS
DOC_COMMENT
DOC_COMMENT_LEADING_ASTERISKS
WHITE_SPACE
DOC_COMMENT_DATA
WHITE_SPACE
MODIFIER_LIST
PUBLIC_KEYWORD
WHITE_SPACE
CLASS_KEYWORD
WHITE_SPACE
IDENTIFIER
TYPE_PARAMETER_LIST
<empty list>
EXTENDS_LIST
<empty list>
IMPLEMENTS_LIST
<empty list>
WHITE_SPACE
LBRACE
RBRACE

View File

@@ -0,0 +1,7 @@
package test.pkg;
/**
* Doc
*/
/// Inline comment as markdown
public class Test {}

View File

@@ -1,4 +1,4 @@
PsiJavaFile:MarkdownWithDocComment.java
PsiJavaFile:MarkdownWithDocCommentBeforeMarkdown.java
PsiPackageStatement:test.pkg
PsiKeyword:package('package')
PsiWhiteSpace(' ')

View File

@@ -0,0 +1,4 @@
package test.pkg;
/// Inline comment as markdown
public class Test {}

View File

@@ -0,0 +1,38 @@
PsiJavaFile:OnlyMarkdownAfterMarkdown.java
PsiPackageStatement:test.pkg
PsiKeyword:package('package')
PsiWhiteSpace(' ')
PsiJavaCodeReferenceElement:test.pkg
PsiJavaCodeReferenceElement:test
PsiIdentifier:test('test')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiIdentifier:pkg('pkg')
PsiReferenceParameterList
<empty list>
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n\n')
PsiImportList
<empty list>
PsiClass:Test
PsiDocComment
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('///')
PsiWhiteSpace(' ')
PsiDocToken:DOC_COMMENT_DATA('Inline comment as markdown')
PsiWhiteSpace('\n')
PsiModifierList:public
PsiKeyword:public('public')
PsiWhiteSpace(' ')
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Test('Test')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')

View File

@@ -0,0 +1,38 @@
java.FILE
PACKAGE_STATEMENT
PACKAGE_KEYWORD
WHITE_SPACE
JAVA_CODE_REFERENCE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
DOT
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
SEMICOLON
WHITE_SPACE
IMPORT_LIST
<empty list>
CLASS
DOC_COMMENT
DOC_COMMENT_LEADING_ASTERISKS
WHITE_SPACE
DOC_COMMENT_DATA
WHITE_SPACE
MODIFIER_LIST
PUBLIC_KEYWORD
WHITE_SPACE
CLASS_KEYWORD
WHITE_SPACE
IDENTIFIER
TYPE_PARAMETER_LIST
<empty list>
EXTENDS_LIST
<empty list>
IMPLEMENTS_LIST
<empty list>
WHITE_SPACE
LBRACE
RBRACE

View File

@@ -0,0 +1,4 @@
package test.pkg;
/// Inline comment as markdown
public class Test {}

View File

@@ -0,0 +1,38 @@
PsiJavaFile:OnlyMarkdownBeforeMarkdown.java
PsiPackageStatement:test.pkg
PsiKeyword:package('package')
PsiWhiteSpace(' ')
PsiJavaCodeReferenceElement:test.pkg
PsiJavaCodeReferenceElement:test
PsiIdentifier:test('test')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiIdentifier:pkg('pkg')
PsiReferenceParameterList
<empty list>
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n\n')
PsiImportList
<empty list>
PsiClass:Test
PsiDocComment
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('///')
PsiWhiteSpace(' ')
PsiDocToken:DOC_COMMENT_DATA('Inline comment as markdown')
PsiWhiteSpace('\n')
PsiModifierList:public
PsiKeyword:public('public')
PsiWhiteSpace(' ')
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Test('Test')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')

View File

@@ -0,0 +1,38 @@
java.FILE
PACKAGE_STATEMENT
PACKAGE_KEYWORD
WHITE_SPACE
JAVA_CODE_REFERENCE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
DOT
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
SEMICOLON
WHITE_SPACE
IMPORT_LIST
<empty list>
CLASS
DOC_COMMENT
DOC_COMMENT_LEADING_ASTERISKS
WHITE_SPACE
DOC_COMMENT_DATA
WHITE_SPACE
MODIFIER_LIST
PUBLIC_KEYWORD
WHITE_SPACE
CLASS_KEYWORD
WHITE_SPACE
IDENTIFIER
TYPE_PARAMETER_LIST
<empty list>
EXTENDS_LIST
<empty list>
IMPLEMENTS_LIST
<empty list>
WHITE_SPACE
LBRACE
RBRACE