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

- use language level to predict the order of comments

GitOrigin-RevId: e7986fcb2302dde7ad80fae9346f6a27edb576ae
This commit is contained in:
Mikhail Pyltsin
2025-02-03 13:44:12 +01:00
committed by intellij-monorepo-bot
parent 4d7c03c5e3
commit 1d0c8692a3
24 changed files with 434 additions and 94 deletions

View File

@@ -128,6 +128,7 @@ feature.module.import.declarations=Module Import Declarations
feature.package.import.shadow.module.import=Import-on-demand over module import 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.package.transitive.dependency.on.java.base=Transitive dependency on java.base module
feature.valhalla.value.classes=Valhalla value classes feature.valhalla.value.classes=Valhalla value classes
feature.markdown.comment=Markdown Documentation Comments
else.without.if='else' without 'if' else.without.if='else' without 'if'
enum.constant.context=Enum constant ''{0}'' in ''{1}'' enum.constant.context=Enum constant ''{0}'' in ''{1}''

View File

@@ -120,6 +120,12 @@ public enum JavaFeature {
//see together with PACKAGE_IMPORTS_SHADOW_MODULE_IMPORTS and TRANSITIVE_DEPENDENCY_ON_JAVA_BASE //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"), 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"), 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"), TRANSITIVE_DEPENDENCY_ON_JAVA_BASE(LanguageLevel.JDK_24_PREVIEW, "feature.package.transitive.dependency.on.java.base"),
VALHALLA_VALUE_CLASSES(LanguageLevel.JDK_X, "feature.valhalla.value.classes"), VALHALLA_VALUE_CLASSES(LanguageLevel.JDK_X, "feature.valhalla.value.classes"),

View File

@@ -136,7 +136,7 @@ public class BasicDeclarationParser {
parseClassBodyWithBraces(builder, isAnnotation, isEnum); parseClassBodyWithBraces(builder, isAnnotation, isEnum);
} }
done(declaration, myJavaElementTypeContainer.CLASS, WhiteSpaceAndCommentSetHolder.INSTANCE); done(declaration, myJavaElementTypeContainer.CLASS, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return declaration; return declaration;
} }
@@ -195,10 +195,10 @@ public class BasicDeclarationParser {
if (builder.getTokenType() == JavaTokenType.LBRACE) { if (builder.getTokenType() == JavaTokenType.LBRACE) {
final PsiBuilder.Marker constantInit = builder.mark(); final PsiBuilder.Marker constantInit = builder.mark();
parseClassBodyWithBraces(builder, false, false); parseClassBodyWithBraces(builder, false, false);
done(constantInit, myJavaElementTypeContainer.ENUM_CONSTANT_INITIALIZER, WhiteSpaceAndCommentSetHolder.INSTANCE); done(constantInit, myJavaElementTypeContainer.ENUM_CONSTANT_INITIALIZER, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
} }
done(constant, myJavaElementTypeContainer.ENUM_CONSTANT, WhiteSpaceAndCommentSetHolder.INSTANCE); done(constant, myJavaElementTypeContainer.ENUM_CONSTANT, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return constant; return constant;
} }
else { else {
@@ -312,7 +312,7 @@ public class BasicDeclarationParser {
error.errorBefore(JavaPsiBundle.message("unexpected.token"), codeBlock); error.errorBefore(JavaPsiBundle.message("unexpected.token"), codeBlock);
} }
done(declaration, myJavaElementTypeContainer.CLASS_INITIALIZER, WhiteSpaceAndCommentSetHolder.INSTANCE); done(declaration, myJavaElementTypeContainer.CLASS_INITIALIZER, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return declaration; return declaration;
} }
@@ -492,7 +492,7 @@ public class BasicDeclarationParser {
} }
} }
done(modList, myJavaElementTypeContainer.MODIFIER_LIST, WhiteSpaceAndCommentSetHolder.INSTANCE); done(modList, myJavaElementTypeContainer.MODIFIER_LIST, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return Pair.create(modList, isEmpty); return Pair.create(modList, isEmpty);
} }
@@ -541,7 +541,7 @@ public class BasicDeclarationParser {
} }
done(declaration, anno ? myJavaElementTypeContainer.ANNOTATION_METHOD : myJavaElementTypeContainer.METHOD, done(declaration, anno ? myJavaElementTypeContainer.ANNOTATION_METHOD : myJavaElementTypeContainer.METHOD,
WhiteSpaceAndCommentSetHolder.INSTANCE); builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return declaration; return declaration;
} }
@@ -680,7 +680,7 @@ public class BasicDeclarationParser {
invalidElements.error(errorMessage); invalidElements.error(errorMessage);
} }
done(elementList, type.getNodeType(myJavaElementTypeContainer), WhiteSpaceAndCommentSetHolder.INSTANCE); done(elementList, type.getNodeType(myJavaElementTypeContainer), builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
} }
public @Nullable PsiBuilder.Marker parseParameter(PsiBuilder builder, boolean ellipsis, boolean disjunctiveType, boolean varType) { public @Nullable PsiBuilder.Marker parseParameter(PsiBuilder builder, boolean ellipsis, boolean disjunctiveType, boolean varType) {
@@ -750,7 +750,7 @@ public class BasicDeclarationParser {
PsiBuilder.Marker expr = myParser.getExpressionParser().parse(builder); PsiBuilder.Marker expr = myParser.getExpressionParser().parse(builder);
if (expr != null && exprType(expr) == myJavaElementTypeContainer.THIS_EXPRESSION) { if (expr != null && exprType(expr) == myJavaElementTypeContainer.THIS_EXPRESSION) {
mark.drop(); mark.drop();
done(param, myJavaElementTypeContainer.RECEIVER_PARAMETER, WhiteSpaceAndCommentSetHolder.INSTANCE); done(param, myJavaElementTypeContainer.RECEIVER_PARAMETER, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return param; return param;
} }
@@ -761,7 +761,7 @@ public class BasicDeclarationParser {
if (expect(builder, JavaTokenType.IDENTIFIER)) { if (expect(builder, JavaTokenType.IDENTIFIER)) {
if (type == myJavaElementTypeContainer.PARAMETER || type == myJavaElementTypeContainer.RECORD_COMPONENT) { if (type == myJavaElementTypeContainer.PARAMETER || type == myJavaElementTypeContainer.RECORD_COMPONENT) {
eatBrackets(builder, null); eatBrackets(builder, null);
done(param, type, WhiteSpaceAndCommentSetHolder.INSTANCE); done(param, type, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return param; return param;
} }
} }
@@ -777,7 +777,7 @@ public class BasicDeclarationParser {
} }
} }
done(param, myJavaElementTypeContainer.RESOURCE_VARIABLE, WhiteSpaceAndCommentSetHolder.INSTANCE); done(param, myJavaElementTypeContainer.RESOURCE_VARIABLE, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return param; return param;
} }
@@ -824,7 +824,7 @@ public class BasicDeclarationParser {
} }
if (builder.getTokenType() != JavaTokenType.COMMA) break; if (builder.getTokenType() != JavaTokenType.COMMA) break;
done(variable, varType, WhiteSpaceAndCommentSetHolder.INSTANCE); done(variable, varType, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
builder.advanceLexer(); builder.advanceLexer();
if (builder.getTokenType() != JavaTokenType.IDENTIFIER) { if (builder.getTokenType() != JavaTokenType.IDENTIFIER) {
@@ -863,7 +863,7 @@ public class BasicDeclarationParser {
} }
if (openMarker) { if (openMarker) {
done(variable, varType, WhiteSpaceAndCommentSetHolder.INSTANCE); done(variable, varType, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
} }
return declaration; return declaration;
@@ -934,7 +934,7 @@ public class BasicDeclarationParser {
parseAnnotationParameterList(builder); parseAnnotationParameterList(builder);
done(anno, myJavaElementTypeContainer.ANNOTATION, WhiteSpaceAndCommentSetHolder.INSTANCE); done(anno, myJavaElementTypeContainer.ANNOTATION, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return anno; return anno;
} }
@@ -942,13 +942,13 @@ public class BasicDeclarationParser {
PsiBuilder.Marker list = builder.mark(); PsiBuilder.Marker list = builder.mark();
if (!expect(builder, JavaTokenType.LPARENTH) || expect(builder, JavaTokenType.RPARENTH)) { if (!expect(builder, JavaTokenType.LPARENTH) || expect(builder, JavaTokenType.RPARENTH)) {
done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, WhiteSpaceAndCommentSetHolder.INSTANCE); done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return; return;
} }
if (builder.getTokenType() == null) { if (builder.getTokenType() == null) {
error(builder, JavaPsiBundle.message("expected.parameter.or.rparen")); error(builder, JavaPsiBundle.message("expected.parameter.or.rparen"));
done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, WhiteSpaceAndCommentSetHolder.INSTANCE); done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return; return;
} }
PsiBuilder.Marker elementMarker = parseAnnotationElement(builder); PsiBuilder.Marker elementMarker = parseAnnotationElement(builder);
@@ -980,7 +980,7 @@ public class BasicDeclarationParser {
} }
} }
done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, WhiteSpaceAndCommentSetHolder.INSTANCE); done(list, myJavaElementTypeContainer.ANNOTATION_PARAMETER_LIST, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
} }
private PsiBuilder.Marker parseAnnotationElement(PsiBuilder builder) { private PsiBuilder.Marker parseAnnotationElement(PsiBuilder builder) {
@@ -992,7 +992,7 @@ public class BasicDeclarationParser {
return null; return null;
} }
if (builder.getTokenType() != JavaTokenType.EQ) { if (builder.getTokenType() != JavaTokenType.EQ) {
done(pair, myJavaElementTypeContainer.NAME_VALUE_PAIR, WhiteSpaceAndCommentSetHolder.INSTANCE); done(pair, myJavaElementTypeContainer.NAME_VALUE_PAIR, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return pair; return pair;
} }
@@ -1004,7 +1004,7 @@ public class BasicDeclarationParser {
valueMarker = parseAnnotationValue(builder); valueMarker = parseAnnotationValue(builder);
if (valueMarker == null) error(builder, JavaPsiBundle.message("expected.value")); if (valueMarker == null) error(builder, JavaPsiBundle.message("expected.value"));
done(pair, myJavaElementTypeContainer.NAME_VALUE_PAIR, WhiteSpaceAndCommentSetHolder.INSTANCE); done(pair, myJavaElementTypeContainer.NAME_VALUE_PAIR, builder, WhiteSpaceAndCommentSetHolder.INSTANCE);
return pair; return pair;
} }

View File

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

View File

@@ -60,10 +60,30 @@ public final class BasicJavaParserUtil {
return Boolean.TRUE.equals(builder.getUserData(DEEP_PARSE_BLOCKS_IN_STATEMENTS)); 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); marker.done(type);
final WhitespacesAndCommentsBinder left = 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; : null;
final WhitespacesAndCommentsBinder right = final WhitespacesAndCommentsBinder right =
commentSetHolder.getTrailingCommentSet().contains(type) ? commentSetHolder.getTrailingCommentBinder() commentSetHolder.getTrailingCommentSet().contains(type) ? commentSetHolder.getTrailingCommentBinder()

View File

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

View File

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

View File

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

View File

@@ -79,7 +79,7 @@ public class BasicStatementParser {
boolean greedyBlock = !expectOrError(builder, JavaTokenType.RBRACE, "expected.rbrace"); boolean greedyBlock = !expectOrError(builder, JavaTokenType.RBRACE, "expected.rbrace");
builder.getTokenType(); // eat spaces builder.getTokenType(); // eat spaces
done(codeBlock, myJavaElementTypeContainer.CODE_BLOCK, myWhiteSpaceAndCommentSetHolder); done(codeBlock, myJavaElementTypeContainer.CODE_BLOCK, builder, myWhiteSpaceAndCommentSetHolder);
if (greedyBlock) { if (greedyBlock) {
codeBlock.setCustomEdgeTokenBinders(null, WhitespacesBinders.GREEDY_RIGHT_BINDER); codeBlock.setCustomEdgeTokenBinders(null, WhitespacesBinders.GREEDY_RIGHT_BINDER);
} }
@@ -172,7 +172,7 @@ public class BasicStatementParser {
else if (tokenType == JavaTokenType.SEMICOLON) { else if (tokenType == JavaTokenType.SEMICOLON) {
PsiBuilder.Marker empty = builder.mark(); PsiBuilder.Marker empty = builder.mark();
builder.advanceLexer(); builder.advanceLexer();
done(empty, myJavaElementTypeContainer.EMPTY_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(empty, myJavaElementTypeContainer.EMPTY_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return empty; return empty;
} }
else if (tokenType == JavaTokenType.IDENTIFIER || tokenType == JavaTokenType.AT) { else if (tokenType == JavaTokenType.IDENTIFIER || tokenType == JavaTokenType.AT) {
@@ -187,7 +187,7 @@ public class BasicStatementParser {
PsiBuilder.Marker declStatement = builder.mark(); PsiBuilder.Marker declStatement = builder.mark();
if (myParser.getDeclarationParser().parse(builder, BasicDeclarationParser.BaseContext.CODE_BLOCK) != null) { 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; return declStatement;
} }
@@ -198,7 +198,7 @@ public class BasicStatementParser {
else if (type == null || builder.getTokenType() != JavaTokenType.DOUBLE_COLON) { else if (type == null || builder.getTokenType() != JavaTokenType.DOUBLE_COLON) {
error(builder, JavaPsiBundle.message("expected.identifier")); error(builder, JavaPsiBundle.message("expected.identifier"));
if (type == null) builder.advanceLexer(); if (type == null) builder.advanceLexer();
done(declStatement, myJavaElementTypeContainer.DECLARATION_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(declStatement, myJavaElementTypeContainer.DECLARATION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return declStatement; return declStatement;
} }
else { else {
@@ -228,15 +228,15 @@ public class BasicStatementParser {
} }
if (count > 1) { if (count > 1) {
pos.drop(); pos.drop();
done(list, myJavaElementTypeContainer.EXPRESSION_LIST, myWhiteSpaceAndCommentSetHolder); done(list, myJavaElementTypeContainer.EXPRESSION_LIST, builder, myWhiteSpaceAndCommentSetHolder);
semicolon(builder); semicolon(builder);
done(statement, myJavaElementTypeContainer.EXPRESSION_LIST_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.EXPRESSION_LIST_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
if (exprType(expr) != myJavaElementTypeContainer.REFERENCE_EXPRESSION) { if (exprType(expr) != myJavaElementTypeContainer.REFERENCE_EXPRESSION) {
drop(list, pos); drop(list, pos);
semicolon(builder); semicolon(builder);
done(statement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
boolean singleToken = expr.getEndIndex() - expr.getStartIndex() == 1; boolean singleToken = expr.getEndIndex() - expr.getStartIndex() == 1;
@@ -258,7 +258,7 @@ public class BasicStatementParser {
PsiBuilder.Marker decl = myParser.getDeclarationParser().parse(builder, BasicDeclarationParser.BaseContext.CODE_BLOCK); PsiBuilder.Marker decl = myParser.getDeclarationParser().parse(builder, BasicDeclarationParser.BaseContext.CODE_BLOCK);
if (decl != null) { if (decl != null) {
PsiBuilder.Marker statement = decl.precede(); PsiBuilder.Marker statement = decl.precede();
done(statement, myJavaElementTypeContainer.DECLARATION_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.DECLARATION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -266,7 +266,7 @@ public class BasicStatementParser {
PsiBuilder.Marker statement = builder.mark(); PsiBuilder.Marker statement = builder.mark();
advance(builder, 2); advance(builder, 2);
parseStatement(builder); parseStatement(builder);
done(statement, myJavaElementTypeContainer.LABELED_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.LABELED_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -283,7 +283,7 @@ public class BasicStatementParser {
statementType = myJavaElementTypeContainer.EXPRESSION_STATEMENT; statementType = myJavaElementTypeContainer.EXPRESSION_STATEMENT;
semicolon(builder); semicolon(builder);
} }
done(statement, statementType, myWhiteSpaceAndCommentSetHolder); done(statement, statementType, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -346,11 +346,11 @@ public class BasicStatementParser {
} }
break; break;
} }
done(statement, myJavaElementTypeContainer.IF_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.IF_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
if (stack != null) { if (stack != null) {
for (int i = stack.size() - 1; i >= 0; i--) { for (int i = stack.size() - 1; i >= 0; i--) {
statement = stack.get(i); statement = stack.get(i);
done(statement, myJavaElementTypeContainer.IF_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.IF_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
} }
} }
return statement; return statement;
@@ -404,7 +404,7 @@ public class BasicStatementParser {
if (!expect(builder, JavaTokenType.LPARENTH)) { if (!expect(builder, JavaTokenType.LPARENTH)) {
error(builder, JavaPsiBundle.message("expected.lparen")); error(builder, JavaPsiBundle.message("expected.lparen"));
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -418,7 +418,7 @@ public class BasicStatementParser {
while (true) { while (true) {
IElementType tokenType = builder.getTokenType(); IElementType tokenType = builder.getTokenType();
if (tokenType == null) { if (tokenType == null) {
done(statement, myJavaElementTypeContainer.FOREACH_PATTERN_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.FOREACH_PATTERN_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
if (tokenType == JavaTokenType.RPARENTH) { if (tokenType == JavaTokenType.RPARENTH) {
@@ -444,7 +444,7 @@ public class BasicStatementParser {
if (parseStatement(builder) == null) { if (parseStatement(builder) == null) {
error(builder, JavaPsiBundle.message("expected.statement")); error(builder, JavaPsiBundle.message("expected.statement"));
if (!expect(builder, JavaTokenType.RPARENTH)) { if (!expect(builder, JavaTokenType.RPARENTH)) {
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
} }
@@ -462,7 +462,7 @@ public class BasicStatementParser {
error(builder, JavaPsiBundle.message("expected.semicolon")); error(builder, JavaPsiBundle.message("expected.semicolon"));
} }
if (!expect(builder, JavaTokenType.RPARENTH)) { if (!expect(builder, JavaTokenType.RPARENTH)) {
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
} }
@@ -470,7 +470,7 @@ public class BasicStatementParser {
parseForUpdateExpressions(builder); parseForUpdateExpressions(builder);
if (!expect(builder, JavaTokenType.RPARENTH)) { if (!expect(builder, JavaTokenType.RPARENTH)) {
error(builder, JavaPsiBundle.message("expected.rparen")); error(builder, JavaPsiBundle.message("expected.rparen"));
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
} }
@@ -481,7 +481,7 @@ public class BasicStatementParser {
error(builder, JavaPsiBundle.message("expected.statement")); error(builder, JavaPsiBundle.message("expected.statement"));
} }
done(statement, myJavaElementTypeContainer.FOR_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.FOR_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -499,7 +499,7 @@ public class BasicStatementParser {
PsiBuilder.Marker expressionStatement; PsiBuilder.Marker expressionStatement;
if (builder.getTokenType() != JavaTokenType.COMMA) { if (builder.getTokenType() != JavaTokenType.COMMA) {
expressionStatement = expr.precede(); expressionStatement = expr.precede();
done(expressionStatement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(expressionStatement, myJavaElementTypeContainer.EXPRESSION_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
} }
else { else {
PsiBuilder.Marker expressionList = expr.precede(); PsiBuilder.Marker expressionList = expr.precede();
@@ -514,8 +514,8 @@ public class BasicStatementParser {
} }
while (builder.getTokenType() == JavaTokenType.COMMA); while (builder.getTokenType() == JavaTokenType.COMMA);
done(expressionList, myJavaElementTypeContainer.EXPRESSION_LIST, myWhiteSpaceAndCommentSetHolder); done(expressionList, myJavaElementTypeContainer.EXPRESSION_LIST, builder, myWhiteSpaceAndCommentSetHolder);
done(expressionStatement, myJavaElementTypeContainer.EXPRESSION_LIST_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(expressionStatement, myJavaElementTypeContainer.EXPRESSION_LIST_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
} }
expressionStatement.setCustomEdgeTokenBinders(null, WhitespacesBinders.DEFAULT_RIGHT_BINDER); expressionStatement.setCustomEdgeTokenBinders(null, WhitespacesBinders.DEFAULT_RIGHT_BINDER);
@@ -536,7 +536,7 @@ public class BasicStatementParser {
error(builder, JavaPsiBundle.message("expected.statement")); error(builder, JavaPsiBundle.message("expected.statement"));
} }
done(statement, forEachType, myWhiteSpaceAndCommentSetHolder); done(statement, forEachType, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -555,7 +555,7 @@ public class BasicStatementParser {
semicolon(builder); semicolon(builder);
} }
done(statement, myJavaElementTypeContainer.DO_WHILE_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.DO_WHILE_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -571,7 +571,7 @@ public class BasicStatementParser {
if (builder.getTokenType() == JavaTokenType.DEFAULT_KEYWORD) { if (builder.getTokenType() == JavaTokenType.DEFAULT_KEYWORD) {
PsiBuilder.Marker defaultElement = builder.mark(); PsiBuilder.Marker defaultElement = builder.mark();
builder.advanceLexer(); builder.advanceLexer();
done(defaultElement, myJavaElementTypeContainer.DEFAULT_CASE_LABEL_ELEMENT, myWhiteSpaceAndCommentSetHolder); done(defaultElement, myJavaElementTypeContainer.DEFAULT_CASE_LABEL_ELEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return Pair.create(defaultElement, false); return Pair.create(defaultElement, false);
} }
if (myParser.getPatternParser().isPattern(builder)) { if (myParser.getPatternParser().isPattern(builder)) {
@@ -597,7 +597,7 @@ public class BasicStatementParser {
} }
} }
while (expect(builder, JavaTokenType.COMMA)); while (expect(builder, JavaTokenType.COMMA));
done(list, myJavaElementTypeContainer.CASE_LABEL_ELEMENT_LIST, myWhiteSpaceAndCommentSetHolder); done(list, myJavaElementTypeContainer.CASE_LABEL_ELEMENT_LIST, builder, myWhiteSpaceAndCommentSetHolder);
parseGuard(builder); parseGuard(builder);
} }
@@ -625,11 +625,11 @@ public class BasicStatementParser {
error(builder, JavaPsiBundle.message("expected.switch.rule")); error(builder, JavaPsiBundle.message("expected.switch.rule"));
expect(builder, JavaTokenType.SEMICOLON); expect(builder, JavaTokenType.SEMICOLON);
} }
done(statement, myJavaElementTypeContainer.SWITCH_LABELED_RULE, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.SWITCH_LABELED_RULE, builder, myWhiteSpaceAndCommentSetHolder);
} }
else { else {
expectOrError(builder, JavaTokenType.COLON, "expected.colon.or.arrow"); 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; return statement;
@@ -651,7 +651,7 @@ public class BasicStatementParser {
builder.advanceLexer(); builder.advanceLexer();
expect(builder, JavaTokenType.IDENTIFIER); expect(builder, JavaTokenType.IDENTIFIER);
semicolon(builder); semicolon(builder);
done(statement, myJavaElementTypeContainer.BREAK_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.BREAK_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -667,7 +667,7 @@ public class BasicStatementParser {
semicolon(builder); semicolon(builder);
} }
done(statement, myJavaElementTypeContainer.YIELD_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.YIELD_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -676,7 +676,7 @@ public class BasicStatementParser {
builder.advanceLexer(); builder.advanceLexer();
expect(builder, JavaTokenType.IDENTIFIER); expect(builder, JavaTokenType.IDENTIFIER);
semicolon(builder); semicolon(builder);
done(statement, myJavaElementTypeContainer.CONTINUE_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.CONTINUE_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -685,7 +685,7 @@ public class BasicStatementParser {
builder.advanceLexer(); builder.advanceLexer();
myParser.getExpressionParser().parse(builder); myParser.getExpressionParser().parse(builder);
semicolon(builder); semicolon(builder);
done(statement, myJavaElementTypeContainer.RETURN_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.RETURN_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -700,7 +700,7 @@ public class BasicStatementParser {
semicolon(builder); semicolon(builder);
} }
done(statement, myJavaElementTypeContainer.THROW_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.THROW_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -737,7 +737,7 @@ public class BasicStatementParser {
} }
} }
done(statement, myJavaElementTypeContainer.TRY_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.TRY_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -748,7 +748,7 @@ public class BasicStatementParser {
if (!expect(builder, JavaTokenType.LPARENTH)) { if (!expect(builder, JavaTokenType.LPARENTH)) {
error(builder, JavaPsiBundle.message("expected.lparen")); error(builder, JavaPsiBundle.message("expected.lparen"));
done(section, myJavaElementTypeContainer.CATCH_SECTION, myWhiteSpaceAndCommentSetHolder); done(section, myJavaElementTypeContainer.CATCH_SECTION, builder, myWhiteSpaceAndCommentSetHolder);
return false; return false;
} }
@@ -759,18 +759,18 @@ public class BasicStatementParser {
if (!expect(builder, JavaTokenType.RPARENTH)) { if (!expect(builder, JavaTokenType.RPARENTH)) {
error(builder, JavaPsiBundle.message("expected.rparen")); error(builder, JavaPsiBundle.message("expected.rparen"));
done(section, myJavaElementTypeContainer.CATCH_SECTION, myWhiteSpaceAndCommentSetHolder); done(section, myJavaElementTypeContainer.CATCH_SECTION, builder, myWhiteSpaceAndCommentSetHolder);
return false; return false;
} }
PsiBuilder.Marker body = parseCodeBlock(builder, true); PsiBuilder.Marker body = parseCodeBlock(builder, true);
if (body == null) { if (body == null) {
error(builder, JavaPsiBundle.message("expected.lbrace")); error(builder, JavaPsiBundle.message("expected.lbrace"));
done(section, myJavaElementTypeContainer.CATCH_SECTION, myWhiteSpaceAndCommentSetHolder); done(section, myJavaElementTypeContainer.CATCH_SECTION, builder, myWhiteSpaceAndCommentSetHolder);
return false; return false;
} }
done(section, myJavaElementTypeContainer.CATCH_SECTION, myWhiteSpaceAndCommentSetHolder); done(section, myJavaElementTypeContainer.CATCH_SECTION, builder, myWhiteSpaceAndCommentSetHolder);
return true; return true;
} }
@@ -788,14 +788,14 @@ public class BasicStatementParser {
semicolon(builder); semicolon(builder);
} }
done(statement, myJavaElementTypeContainer.ASSERT_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.ASSERT_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
private @NotNull PsiBuilder.Marker parseBlockStatement(PsiBuilder builder) { private @NotNull PsiBuilder.Marker parseBlockStatement(PsiBuilder builder) {
PsiBuilder.Marker statement = builder.mark(); PsiBuilder.Marker statement = builder.mark();
parseCodeBlock(builder, true); parseCodeBlock(builder, true);
done(statement, myJavaElementTypeContainer.BLOCK_STATEMENT, myWhiteSpaceAndCommentSetHolder); done(statement, myJavaElementTypeContainer.BLOCK_STATEMENT, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }
@@ -810,7 +810,7 @@ public class BasicStatementParser {
} }
} }
done(statement, type, myWhiteSpaceAndCommentSetHolder); done(statement, type, builder, myWhiteSpaceAndCommentSetHolder);
return statement; return statement;
} }

View File

@@ -3,6 +3,8 @@ package com.intellij.psi.impl.source;
import com.intellij.lang.WhitespacesAndCommentsBinder; import com.intellij.lang.WhitespacesAndCommentsBinder;
import com.intellij.openapi.util.text.StringUtil; 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.IElementType;
import com.intellij.psi.tree.ParentAwareTokenSet; import com.intellij.psi.tree.ParentAwareTokenSet;
import com.intellij.psi.tree.TokenSet; import com.intellij.psi.tree.TokenSet;
@@ -28,16 +30,22 @@ public class WhiteSpaceAndCommentSetHolder {
private WhiteSpaceAndCommentSetHolder() { private WhiteSpaceAndCommentSetHolder() {
} }
private final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER = new PrecedingWhitespacesAndCommentsBinder(false); private final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER_WITH_MARKDOWN = new PrecedingWhitespacesAndCommentsBinder(false, true);
private final WhitespacesAndCommentsBinder SPECIAL_PRECEDING_COMMENT_BINDER = new PrecedingWhitespacesAndCommentsBinder(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(); private final WhitespacesAndCommentsBinder TRAILING_COMMENT_BINDER = new TrailingWhitespacesAndCommentsBinder();
public WhitespacesAndCommentsBinder getPrecedingCommentBinder() { public WhitespacesAndCommentsBinder getPrecedingCommentBinder(@NotNull LanguageLevel myLanguageLevel) {
return PRECEDING_COMMENT_BINDER; return JavaFeature.MARKDOWN_COMMENT.isSufficient(myLanguageLevel)
? PRECEDING_COMMENT_BINDER_WITH_MARKDOWN
: PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN;
} }
public WhitespacesAndCommentsBinder getSpecialPrecedingCommentBinder() { public WhitespacesAndCommentsBinder getSpecialPrecedingCommentBinder(@NotNull LanguageLevel myLanguageLevel) {
return SPECIAL_PRECEDING_COMMENT_BINDER; return JavaFeature.MARKDOWN_COMMENT.isSufficient(myLanguageLevel)
? SPECIAL_PRECEDING_COMMENT_BINDER_WITH_MARKDOWN
: SPECIAL_PRECEDING_COMMENT_BINDER_WITHOUT_MARKDOWN;
} }
public WhitespacesAndCommentsBinder getTrailingCommentBinder() { public WhitespacesAndCommentsBinder getTrailingCommentBinder() {
@@ -55,9 +63,11 @@ public class WhiteSpaceAndCommentSetHolder {
private static class PrecedingWhitespacesAndCommentsBinder implements WhitespacesAndCommentsBinder { private static class PrecedingWhitespacesAndCommentsBinder implements WhitespacesAndCommentsBinder {
private final boolean myAfterEmptyImport; private final boolean myAfterEmptyImport;
private final boolean mySupportMarkdown;
PrecedingWhitespacesAndCommentsBinder(final boolean afterImport) { PrecedingWhitespacesAndCommentsBinder(final boolean afterImport, final boolean supportMarkdown) {
this.myAfterEmptyImport = afterImport; this.myAfterEmptyImport = afterImport;
this.mySupportMarkdown = supportMarkdown;
} }
@Override @Override
@@ -67,16 +77,24 @@ public class WhiteSpaceAndCommentSetHolder {
// 1. bind doc comment // 1. bind doc comment
// now there are markdown comments. // now there are markdown comments.
// To preserve previous orders, let's try to find the first non-markdown comment (and skip markdown comments). if (mySupportMarkdown) {
// If there is no non-markdown, take the first markdown //collect everything
for (int idx = tokens.size() - 1; idx >= 0; idx--) { for (int idx = tokens.size() - 1; idx >= 0; idx--) {
if (BasicJavaAstTreeUtil.is(tokens.get(idx), BASIC_DOC_COMMENT) && !isDocMarkdownComment(idx, getter)) { if (BasicJavaAstTreeUtil.is(tokens.get(idx), BASIC_DOC_COMMENT)) return idx;
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--) { for (int idx = tokens.size() - 1; idx >= 0; idx--) {
if (BasicJavaAstTreeUtil.is(tokens.get(idx), BASIC_DOC_COMMENT)) return idx; if (BasicJavaAstTreeUtil.is(tokens.get(idx), BASIC_DOC_COMMENT)) return idx;
}
} }
// 2. bind plain comments // 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. // 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; package com.intellij.java.parser;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public abstract class AbstractBasicJavadocParsingTest extends AbstractBasicJavaParsingTestCase { public abstract class AbstractBasicJavadocParsingTest extends AbstractBasicJavaParsingTestCase {
@@ -213,5 +214,24 @@ public abstract class AbstractBasicJavadocParsingTest extends AbstractBasicJavaP
public void testReferenceLinkMarkdown09() { doTest(true); } public void testReferenceLinkMarkdown09() { doTest(true); }
public void testReferenceLinkMarkdown10() { doTest(true); } public void testReferenceLinkMarkdown10() { doTest(true); }
public void testReferenceLinkMarkdown11() { 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 { public interface ParserWrapper extends BasicJavaParserUtil.ParserWrapper {
} }
/**
* @deprecated please, use {@link WhiteSpaceAndCommentSetHolder#INSTANCE} instead
*/
@Deprecated
public static final WhitespacesAndCommentsBinder PRECEDING_COMMENT_BINDER = 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 = 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 = public static final WhitespacesAndCommentsBinder TRAILING_COMMENT_BINDER =
WhiteSpaceAndCommentSetHolder.INSTANCE.getTrailingCommentBinder(); 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) { public static void done(final PsiBuilder.Marker marker, final IElementType type) {
BasicJavaParserUtil.done(marker, type, WhiteSpaceAndCommentSetHolder.INSTANCE); 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 PsiPackageStatement:test.pkg
PsiKeyword:package('package') PsiKeyword:package('package')
PsiWhiteSpace(' ') 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