diff --git a/open-java-format/src/main/java/com/palantir/javaformat/java/JavaCommentsHelper.java b/open-java-format/src/main/java/com/palantir/javaformat/java/JavaCommentsHelper.java index a31fb7c25..83996c93d 100644 --- a/open-java-format/src/main/java/com/palantir/javaformat/java/JavaCommentsHelper.java +++ b/open-java-format/src/main/java/com/palantir/javaformat/java/JavaCommentsHelper.java @@ -167,10 +167,12 @@ private static boolean isJBangDirective(String text) { return matcher.lookingAt() && (matcher.group(1) != null || JBANG_DIRECTIVE_NAMES.contains(matcher.group(2))); } + private static final Pattern LINE_COMMENT_MISSING_SPACE_PREFIX = Pattern.compile("^(//+)[^\\s/]"); + // Preserve special `//noinspection` and `//$NON-NLS-x$` comments used by IDEs, which cannot // contain leading spaces. - private static final Pattern LINE_COMMENT_MISSING_SPACE_PREFIX = - Pattern.compile("^(//+)(?!noinspection|\\$NON-NLS-\\d+\\$)[^\\s/]"); + private static final Pattern LINE_COMMENT_NO_SPACE_PREFIX = + Pattern.compile("^//+(noinspection|\\$NON-NLS-\\d+\\$)"); private static String lineCommentPrefix(String line) { int prefixLength = 0; @@ -191,7 +193,7 @@ private List wrapLineComments(List lines, int column0) { line = CharMatcher.whitespace().trimLeadingFrom(line); // Add missing leading spaces to line comments: `//foo` -> `// foo`. Matcher matcher = LINE_COMMENT_MISSING_SPACE_PREFIX.matcher(line); - if (matcher.find()) { + if (matcher.find() && !LINE_COMMENT_NO_SPACE_PREFIX.matcher(line).find()) { int length = matcher.group(1).length(); line = "/".repeat(length) + " " + line.substring(length); } diff --git a/open-java-format/src/test/java/com/palantir/javaformat/java/FormatterTest.java b/open-java-format/src/test/java/com/palantir/javaformat/java/FormatterTest.java index 46be7a302..8a773d9b6 100644 --- a/open-java-format/src/test/java/com/palantir/javaformat/java/FormatterTest.java +++ b/open-java-format/src/test/java/com/palantir/javaformat/java/FormatterTest.java @@ -368,6 +368,33 @@ void onlyWrapLineCommentOnWhitespace_noLeadingWhitespace() throws Exception { + "}\n"); } + @Test + void lineCommentGetsItsMissingSpaceExceptIdeMarkers() throws Exception { + // `//foo` gets a space after any number of slashes, while the IDE markers `//noinspection` and `//$NON-NLS-n$` + // are recognised by their tools only without one and stay as written. + String input = "class T {\n" + + " //noinspection unchecked\n" + + " //$NON-NLS-1$ //$NON-NLS-2$\n" + + " //$NON-NLS-12$ and more\n" + + " //foo\n" + + " ///foo\n" + + " // bar\n" + + " // two spaces\n" + + " void m() {}\n" + + "}\n"; + String expected = "class T {\n" + + " //noinspection unchecked\n" + + " //$NON-NLS-1$ //$NON-NLS-2$\n" + + " //$NON-NLS-12$ and more\n" + + " // foo\n" + + " /// foo\n" + + " // bar\n" + + " // two spaces\n" + + " void m() {}\n" + + "}\n"; + assertThat(Formatter.create().formatSource(input)).isEqualTo(expected); + } + @Test void throwsFormatterException() throws Exception { assertThatThrownBy(() -> Formatter.create().formatSourceAndFixImports("package foo; public class {"))