From 6f86d4fbb0d0bc3fd471e0f0d4f0ca207c7b651b Mon Sep 17 00:00:00 2001 From: plumpy Date: Wed, 10 Jul 2019 08:19:07 -0700 Subject: [PATCH 001/379] Remove the untilBuild so the plugin will work with EAP IDEs. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=257407602 --- idea_plugin/build.gradle | 5 +++-- idea_plugin/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 74fcef8d4..762e58e89 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "0.4.4" + id "org.jetbrains.intellij" version "0.4.9" } repositories { @@ -38,8 +38,9 @@ intellij { patchPluginXml { pluginDescription = "Formats source code using the google-java-format tool. This version of " + "the plugin uses version ${googleJavaFormatVersion} of the tool." - version = "${googleJavaFormatVersion}.0.1" + version = "${googleJavaFormatVersion}.0.2" sinceBuild = '173' + untilBuild = '' } publishPlugin { diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index 484228779..aa8e8df1d 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -12,6 +12,8 @@ +
1.7.0.2
+
Added support for all IDEs after 2017.3.
1.7.0.1
Added support for 2019.1 IDEs.
1.7.0.0
From c753e2c812331b1ba80db8c59d5a7dc8b28febcc Mon Sep 17 00:00:00 2001 From: awturner Date: Mon, 12 Aug 2019 10:12:50 -0700 Subject: [PATCH 002/379] google-java-format: construct the Replacement range in the constructor, in order to guarantee it is closedOpen. Remove the Replacement.create(Range,String) overload, since the bounds were not checked for correctness (open/closed, lower bound >= 0). ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=262950211 --- .../googlejavaformat/java/Replacement.java | 23 ++++++++----------- .../java/SnippetFormatter.java | 21 ++++++++--------- .../java/SnippetFormatterTest.java | 15 ++++-------- 3 files changed, 23 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Replacement.java b/core/src/main/java/com/google/googlejavaformat/java/Replacement.java index dc44d710f..5df0991f2 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Replacement.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Replacement.java @@ -14,6 +14,9 @@ package com.google.googlejavaformat.java; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + import com.google.common.collect.Range; import java.util.Objects; @@ -23,28 +26,20 @@ *

google-java-format doesn't depend on AutoValue, to allow AutoValue to depend on * google-java-format. */ -public class Replacement { +public final class Replacement { public static Replacement create(int startPosition, int endPosition, String replaceWith) { + checkArgument(startPosition >= 0, "startPosition must be non-negative"); + checkArgument(startPosition <= endPosition, "startPosition cannot be after endPosition"); return new Replacement(Range.closedOpen(startPosition, endPosition), replaceWith); } - public static Replacement create(Range range, String replaceWith) { - return new Replacement(range, replaceWith); - } - private final Range replaceRange; private final String replacementString; - Replacement(Range replaceRange, String replacementString) { - if (replaceRange == null) { - throw new NullPointerException("Null replaceRange"); - } - this.replaceRange = replaceRange; - if (replacementString == null) { - throw new NullPointerException("Null replacementString"); - } - this.replacementString = replacementString; + private Replacement(Range replaceRange, String replacementString) { + this.replaceRange = checkNotNull(replaceRange, "Null replaceRange"); + this.replacementString = checkNotNull(replacementString, "Null replacementString"); } /** The range of characters in the original source to replace. */ diff --git a/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java b/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java index 3827ef958..8d426b65d 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java @@ -14,9 +14,12 @@ package com.google.googlejavaformat.java; +import static com.google.common.collect.ImmutableList.toImmutableList; + import com.google.common.base.CharMatcher; import com.google.common.base.Preconditions; import com.google.common.collect.DiscreteDomain; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; import com.google.common.collect.RangeSet; import com.google.common.collect.TreeRangeSet; @@ -87,7 +90,7 @@ private static List> offsetRanges(List> ranges, in } /** Runs the Google Java formatter on the given source, with only the given ranges specified. */ - public List format( + public ImmutableList format( SnippetKind kind, String source, List> ranges, @@ -114,14 +117,9 @@ public List format( wrapper.offset, replacement.length() - (wrapper.contents.length() - wrapper.offset - source.length())); - List replacements = toReplacements(source, replacement); - List filtered = new ArrayList<>(); - for (Replacement r : replacements) { - if (rangeSet.encloses(r.getReplaceRange())) { - filtered.add(r); - } - } - return filtered; + return toReplacements(source, replacement).stream() + .filter(r -> rangeSet.encloses(r.getReplaceRange())) + .collect(toImmutableList()); } /** @@ -142,7 +140,7 @@ private static List toReplacements(String source, String replacemen int i = NOT_WHITESPACE.indexIn(source); int j = NOT_WHITESPACE.indexIn(replacement); if (i != 0 || j != 0) { - replacements.add(Replacement.create(Range.closedOpen(0, i), replacement.substring(0, j))); + replacements.add(Replacement.create(0, i, replacement.substring(0, j))); } while (i != -1 && j != -1) { int i2 = NOT_WHITESPACE.indexIn(source, i + 1); @@ -152,8 +150,7 @@ private static List toReplacements(String source, String replacemen } if ((i2 - i) != (j2 - j) || !source.substring(i + 1, i2).equals(replacement.substring(j + 1, j2))) { - replacements.add( - Replacement.create(Range.closedOpen(i + 1, i2), replacement.substring(j + 1, j2))); + replacements.add(Replacement.create(i + 1, i2, replacement.substring(j + 1, j2))); } i = i2; j = j2; diff --git a/core/src/test/java/com/google/googlejavaformat/java/SnippetFormatterTest.java b/core/src/test/java/com/google/googlejavaformat/java/SnippetFormatterTest.java index 6cb737d4c..f763dd524 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/SnippetFormatterTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/SnippetFormatterTest.java @@ -39,9 +39,7 @@ public void expression() throws FormatterException { 4, false); assertThat(replacements) - .containsExactly( - Replacement.create(Range.closedOpen(1, 2), " "), - Replacement.create(Range.closedOpen(3, 3), " ")); + .containsExactly(Replacement.create(1, 2, " "), Replacement.create(3, 3, " ")); } @Test @@ -56,9 +54,7 @@ public void statement() throws FormatterException { 4, false); assertThat(replacements) - .containsExactly( - Replacement.create(Range.closedOpen(5, 6), " "), - Replacement.create(Range.closedOpen(7, 7), " ")); + .containsExactly(Replacement.create(5, 6, " "), Replacement.create(7, 7, " ")); } @Test @@ -72,7 +68,7 @@ public void classMember() throws FormatterException { ImmutableList.of(Range.closedOpen(0, input.length())), 4, false); - assertThat(replacements).containsExactly(Replacement.create(Range.closedOpen(10, 11), "")); + assertThat(replacements).containsExactly(Replacement.create(10, 11, "")); } @Test @@ -86,7 +82,7 @@ public void compilation() throws FormatterException { ImmutableList.of(Range.closedOpen(input.indexOf("class"), input.length())), 4, false); - assertThat(replacements).containsExactly(Replacement.create(Range.closedOpen(22, 23), "")); + assertThat(replacements).containsExactly(Replacement.create(22, 23, "")); } @Test @@ -101,7 +97,6 @@ public void compilationWithComments() throws FormatterException { 4, true); assertThat(replacements) - .containsExactly( - Replacement.create(Range.closedOpen(0, 24), "/** a b */\nclass Test {}\n")); + .containsExactly(Replacement.create(0, 24, "/** a b */\nclass Test {}\n")); } } From 75c4c063baadac67f0ada23505bf666703fe4a06 Mon Sep 17 00:00:00 2001 From: awturner Date: Tue, 13 Aug 2019 08:58:14 -0700 Subject: [PATCH 003/379] JavaInputAstVisitor: fix unchecked cast (Warnings kept cropping up while compiling my StringWrapper changes...) ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=263146682 --- .../java/JavaInputAstVisitor.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index bd462de39..c0f645654 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -454,9 +454,9 @@ public Void visitNewArray(NewArrayTree node, Void unused) { Deque dimExpressions = new ArrayDeque<>(node.getDimensions()); - Deque> annotations = new ArrayDeque<>(); + Deque> annotations = new ArrayDeque<>(); annotations.add(ImmutableList.copyOf(node.getAnnotations())); - annotations.addAll((List>) node.getDimAnnotations()); + annotations.addAll(node.getDimAnnotations()); annotations.addAll(extractedDims.dims); scan(base, null); @@ -578,7 +578,7 @@ private void visitAnnotatedArrayType(Tree node) { TypeWithDims extractedDims = DimensionHelpers.extractDims(node, SortedDims.YES); builder.open(plusFour); scan(extractedDims.node, null); - Deque> dims = new ArrayDeque<>(extractedDims.dims); + Deque> dims = new ArrayDeque<>(extractedDims.dims); maybeAddDims(dims); Verify.verify(dims.isEmpty()); builder.close(); @@ -1352,7 +1352,7 @@ public Void visitMethod(MethodTree node, Void unused) { annotations, Direction.VERTICAL, /* declarationAnnotationBreak= */ Optional.empty())); Tree baseReturnType = null; - Deque> dims = null; + Deque> dims = null; if (node.getReturnType() != null) { TypeWithDims extractedDims = DimensionHelpers.extractDims(node.getReturnType(), SortedDims.YES); @@ -3234,7 +3234,7 @@ int declareOne( builder.blankLineWanted(BlankLineWanted.conditional(verticalAnnotationBreak)); } - Deque> dims = + Deque> dims = new ArrayDeque<>( typeWithDims.isPresent() ? typeWithDims.get().dims : Collections.emptyList()); int baseDims = 0; @@ -3321,7 +3321,7 @@ int declareOne( return baseDims; } - private void maybeAddDims(Deque> annotations) { + private void maybeAddDims(Deque> annotations) { maybeAddDims(new ArrayDeque<>(), annotations); } @@ -3338,7 +3338,7 @@ private void maybeAddDims(Deque> annotations) { * [[@A, @B], [@C]]} for {@code int @A [] @B @C []} */ private void maybeAddDims( - Deque dimExpressions, Deque> annotations) { + Deque dimExpressions, Deque> annotations) { boolean lastWasAnnotation = false; while (builder.peekToken().isPresent()) { switch (builder.peekToken().get()) { @@ -3346,7 +3346,7 @@ private void maybeAddDims( if (annotations.isEmpty()) { return; } - List dimAnnotations = annotations.removeFirst(); + List dimAnnotations = annotations.removeFirst(); if (dimAnnotations.isEmpty()) { continue; } @@ -3396,7 +3396,7 @@ private void declareMany(List fragments, Direction annotationDirec builder.open(plusFour); builder.open(ZERO); TypeWithDims extractedDims = DimensionHelpers.extractDims(type, SortedDims.YES); - Deque> dims = new ArrayDeque<>(extractedDims.dims); + Deque> dims = new ArrayDeque<>(extractedDims.dims); scan(extractedDims.node, null); int baseDims = dims.size(); maybeAddDims(dims); From edfc2abd6e6580e14c05b44fd5717ec105d8523f Mon Sep 17 00:00:00 2001 From: cushon Date: Wed, 14 Aug 2019 15:55:13 -0700 Subject: [PATCH 004/379] Delete obsolete unused import logic we no longer support removing imports that are used in javadoc. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=263447679 --- .../java/RemoveUnusedImports.java | 45 +------------------ 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index fe2133a08..bd2fa8171 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -72,19 +72,6 @@ */ public class RemoveUnusedImports { - /** - * Configuration for javadoc-only imports. - * - * @deprecated This configuration is no longer supported and will be removed in the future. - */ - @Deprecated - public enum JavadocOnlyImports { - /** Remove imports that are only used in javadoc, and fully qualify any {@code @link} tags. */ - REMOVE, - /** Keep imports that are only used in javadoc. */ - KEEP - } - // Visits an AST, recording all simple names that could refer to imported // types and also any javadoc references that could refer to imported // types (`@link`, `@see`, `@throws`, etc.) @@ -197,13 +184,6 @@ public Void visitIdentifier(IdentifierTree node, Void aVoid) { } } - /** @deprecated use {@link removeUnusedImports(String)} instead. */ - @Deprecated - public static String removeUnusedImports( - final String contents, JavadocOnlyImports javadocOnlyImports) throws FormatterException { - return removeUnusedImports(contents); - } - public static String removeUnusedImports(final String contents) throws FormatterException { Context context = new Context(); // TODO(cushon): this should default to the latest supported source level, same as in Formatter @@ -276,17 +256,6 @@ private static RangeMap buildReplacements( endPosition += sep.length(); } replacements.put(Range.closedOpen(importTree.getStartPosition(), endPosition), ""); - // fully qualify any javadoc references with the same simple name as a deleted - // non-static import - if (!importTree.isStatic()) { - for (Range docRange : usedInJavadoc.get(simpleName)) { - if (docRange == null) { - continue; - } - String replaceWith = importTree.getQualifiedIdentifier().toString(); - replacements.put(docRange, replaceWith); - } - } } return replacements; } @@ -349,18 +318,6 @@ private static String applyReplacements(String source, RangeMap } offset += replaceWith.length() - (range.upperEndpoint() - range.lowerEndpoint()); } - String result = sb.toString(); - - // If there were any non-empty replaced ranges (e.g. javadoc), reformat the fixed regions. - // We could avoid formatting twice in --fix-imports=also mode, but that is not the default - // and removing imports won't usually affect javadoc. - if (!fixedRanges.isEmpty()) { - try { - result = new Formatter().formatSource(result, fixedRanges.asRanges()); - } catch (FormatterException e) { - // javadoc reformatting is best-effort - } - } - return result; + return sb.toString(); } } From 24680f3c4559bc8e14a207e01acb10e72db3a28c Mon Sep 17 00:00:00 2001 From: awturner Date: Thu, 15 Aug 2019 05:45:01 -0700 Subject: [PATCH 005/379] google-java-formatter: reformat portions of the text affected by reflowing ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=263545728 --- .../java/FormatFileCallable.java | 6 +- .../googlejavaformat/java/Formatter.java | 2 +- .../googlejavaformat/java/StringWrapper.java | 58 ++++++++++++------- .../java/StringWrapperIntegrationTest.java | 13 +++-- .../java/StringWrapperTest.java | 44 ++++++++++++++ 5 files changed, 93 insertions(+), 30 deletions(-) create mode 100644 core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java diff --git a/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java b/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java index 89cb339a1..9d8ae41ca 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java +++ b/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java @@ -41,11 +41,11 @@ public String call() throws FormatterException { return fixImports(input); } - String formatted = - new Formatter(options).formatSource(input, characterRanges(input).asRanges()); + Formatter formatter = new Formatter(options); + String formatted = formatter.formatSource(input, characterRanges(input).asRanges()); formatted = fixImports(formatted); if (parameters.reflowLongStrings()) { - formatted = StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, formatted); + formatted = StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, formatted, formatter); } return formatted; } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index a6f931109..e53f79fcf 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -219,7 +219,7 @@ public String formatSourceAndFixImports(String input) throws FormatterException input = ImportOrderer.reorderImports(input, options.style()); input = RemoveUnusedImports.removeUnusedImports(input); String formatted = formatSource(input); - formatted = StringWrapper.wrap(formatted); + formatted = StringWrapper.wrap(formatted, this); return formatted; } diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index c371a8abd..6dfca5335 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -62,19 +62,52 @@ /** Wraps string literals that exceed the column limit. */ public final class StringWrapper { /** Reflows long string literals in the given Java source code. */ - public static String wrap(String input) throws FormatterException { - return StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, input); + public static String wrap(String input, Formatter formatter) throws FormatterException { + return StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, input, formatter); } /** * Reflows string literals in the given Java source code that extend past the given column limit. */ - static String wrap(final int columnLimit, final String input) throws FormatterException { + static String wrap(final int columnLimit, String input, Formatter formatter) + throws FormatterException { if (!longLines(columnLimit, input)) { // fast path return input; } + TreeRangeMap replacements = getReflowReplacements(columnLimit, input); + String firstPass = formatter.formatSource(input, replacements.asMapOfRanges().keySet()); + + if (!firstPass.equals(input)) { + // If formatting the replacement ranges resulted in a change, recalculate the replacements on + // the updated input. + input = firstPass; + replacements = getReflowReplacements(columnLimit, input); + } + + String result = applyReplacements(input, replacements); + + { + // We really don't want bugs in this pass to change the behaviour of programs we're + // formatting, so check that the pretty-printed AST is the same before and after reformatting. + String expected = parse(input, /* allowStringFolding= */ true).toString(); + String actual = parse(result, /* allowStringFolding= */ true).toString(); + if (!expected.equals(actual)) { + throw new FormatterException( + String.format( + "Something has gone terribly wrong. Please file a bug: " + + "https://github.com/google/google-java-format/issues/new" + + "\n\n=== Actual: ===\n%s\n=== Expected: ===\n%s\n", + actual, expected)); + } + } + + return result; + } + + private static TreeRangeMap getReflowReplacements( + int columnLimit, final String input) throws FormatterException { JCTree.JCCompilationUnit unit = parse(input, /* allowStringFolding= */ false); String separator = Newlines.guessLineSeparator(input); @@ -137,24 +170,7 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) { Range.closedOpen(getStartPosition(flat.get(0)), getEndPosition(unit, getLast(flat))), reflow(separator, columnLimit, startColumn, trailing, components, first.get())); } - String result = applyReplacements(input, replacements); - - { - // We really don't want bugs in this pass to change the behaviour of programs we're - // formatting, so check that the pretty-printed AST is the same before and after reformatting. - String expected = parse(input, /* allowStringFolding= */ true).toString(); - String actual = parse(result, /* allowStringFolding= */ true).toString(); - if (!expected.equals(actual)) { - throw new FormatterException( - String.format( - "Something has gone terribly wrong. Please file a bug: " - + "https://github.com/google/google-java-format/issues/new" - + "\n\n=== Actual: ===\n%s\n=== Expected: ===\n%s\n", - actual, expected)); - } - } - - return result; + return replacements; } /** diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java index 868b392d0..89c94ea30 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java @@ -378,6 +378,8 @@ public static Collection parameters() { .collect(toImmutableList()); } + private final Formatter formatter = new Formatter(); + private final String input; private final String output; @@ -388,24 +390,25 @@ public StringWrapperIntegrationTest(String input, String output) { @Test public void test() throws Exception { - assertThat(StringWrapper.wrap(40, new Formatter().formatSource(input))).isEqualTo(output); + assertThat(StringWrapper.wrap(40, formatter.formatSource(input), formatter)).isEqualTo(output); } @Test public void testCR() throws Exception { - assertThat(StringWrapper.wrap(40, new Formatter().formatSource(input.replace("\n", "\r")))) + assertThat(StringWrapper.wrap(40, formatter.formatSource(input.replace("\n", "\r")), formatter)) .isEqualTo(output.replace("\n", "\r")); } @Test public void testCRLF() throws Exception { - assertThat(StringWrapper.wrap(40, new Formatter().formatSource(input.replace("\n", "\r\n")))) + assertThat( + StringWrapper.wrap(40, formatter.formatSource(input.replace("\n", "\r\n")), formatter)) .isEqualTo(output.replace("\n", "\r\n")); } @Test public void idempotent() throws Exception { - String wrap = StringWrapper.wrap(40, new Formatter().formatSource(input)); - assertThat(wrap).isEqualTo(new Formatter().formatSource(wrap)); + String wrap = StringWrapper.wrap(40, formatter.formatSource(input), formatter); + assertThat(wrap).isEqualTo(formatter.formatSource(wrap)); } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java new file mode 100644 index 000000000..e3e531290 --- /dev/null +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -0,0 +1,44 @@ +package com.google.googlejavaformat.java; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.base.Joiner; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** {@link StringWrapper}Test */ +@RunWith(JUnit4.class) +public class StringWrapperTest { + @Test + public void testAwkwardLineEndWrapping() throws Exception { + String input = + lines( + "class T {", + // This is a wide line, but has to be split in code because of 100-char limit. + " String s = someMethodWithQuiteALongNameThatWillGetUsUpCloseToTheColumnLimit() " + + "+ \"foo bar foo bar foo bar\";", + "", + " String someMethodWithQuiteALongNameThatWillGetUsUpCloseToTheColumnLimit() {", + " return null;", + " }", + "}"); + String output = + lines( + "class T {", + " String s =", + " someMethodWithQuiteALongNameThatWillGetUsUpCloseToTheColumnLimit()", + " + \"foo bar foo bar foo bar\";", + "", + " String someMethodWithQuiteALongNameThatWillGetUsUpCloseToTheColumnLimit() {", + " return null;", + " }", + "}"); + + assertThat(StringWrapper.wrap(100, input, new Formatter())).isEqualTo(output); + } + + private static String lines(String... line) { + return Joiner.on('\n').join(line) + '\n'; + } +} From 5f46e2e91a65bb5b73631e62660919325304bc0c Mon Sep 17 00:00:00 2001 From: cushon Date: Thu, 15 Aug 2019 10:30:08 -0700 Subject: [PATCH 006/379] Add missing license headers ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=263591284 --- .../googlejavaformat/java/StringWrapperTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java index e3e531290..99e1b2fc5 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -1,3 +1,17 @@ +/* + * Copyright 2019 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + package com.google.googlejavaformat.java; import static com.google.common.truth.Truth.assertThat; From 85edee7ea721d2c834ea04f9ccc0b821cbee4369 Mon Sep 17 00:00:00 2001 From: dpb Date: Fri, 16 Aug 2019 08:27:12 -0700 Subject: [PATCH 007/379] Switch from oraclejdk9 to openjdk9 in Travis builds, per https://travis-ci.community/t/java-9-build-failing-with-https-certificate-exception/4364/2. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=263775386 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4914ad11e..e2116b00f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ notifications: jdk: - oraclejdk8 - - oraclejdk9 + - openjdk9 - openjdk10 - openjdk11 - openjdk-ea From 05df9d3b5c10f2bdd434181b6f046309a1040a37 Mon Sep 17 00:00:00 2001 From: dpb Date: Fri, 16 Aug 2019 13:45:21 -0700 Subject: [PATCH 008/379] Changing oraclejdk8 to openjdk8 in hopes that it will fix our Travis builds. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=263837785 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e2116b00f..829f0fe06 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ notifications: on_failure: always jdk: - - oraclejdk8 + - openjdk8 - openjdk9 - openjdk10 - openjdk11 From 3717179583c59ae3cccbe4bd99bce2332b1ff554 Mon Sep 17 00:00:00 2001 From: cushon Date: Fri, 11 Oct 2019 13:23:22 -0700 Subject: [PATCH 009/379] Don't reformat javadoc comments with extra `*` ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=274236131 --- .../java/com/google/googlejavaformat/java/JavaInput.java | 4 +++- .../googlejavaformat/java/JavadocFormattingTest.java | 2 +- .../googlejavaformat/java/testdata/B142553964.input | 8 ++++++++ .../googlejavaformat/java/testdata/B142553964.output | 8 ++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B142553964.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B142553964.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index bd3286d2b..1df0f812d 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -154,7 +154,9 @@ public boolean isSlashStarComment() { @Override public boolean isJavadocComment() { - return text.startsWith("/**") && text.length() > 4; + // comments like `/***` are also javadoc, but their formatting probably won't be improved + // by the javadoc formatter + return text.startsWith("/**") && text.charAt("/**".length()) != '*' && text.length() > 4; } @Override diff --git a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java index bdad74420..411699765 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java @@ -50,7 +50,7 @@ public void empty() { "class Test {}", }; String[] expected = { - "/** */", "class Test {}", + "/***/", "class Test {}", }; doFormatTest(input, expected); } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B142553964.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B142553964.input new file mode 100644 index 000000000..fb49cc645 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B142553964.input @@ -0,0 +1,8 @@ +/************************************************************************************************************************************************************* + * Copyright + * + * Some + * + * Company + *************************************************************************************************************************************************************/ +class T {} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B142553964.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B142553964.output new file mode 100644 index 000000000..c00d84e69 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B142553964.output @@ -0,0 +1,8 @@ +/************************************************************************************************************************************************************* + * Copyright + * + * Some + * + * Company + *************************************************************************************************************************************************************/ +class T {} From f4a6eff1e1cfd9b43c87fdac7329b694a3978224 Mon Sep 17 00:00:00 2001 From: eaftan Date: Thu, 31 Oct 2019 14:14:39 -0700 Subject: [PATCH 010/379] Use https for Eclipse maven repo. Fixes #402 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=277798821 --- eclipse_plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index a49cbc358..bb581cdb6 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -40,7 +40,7 @@ mars p2 - http://download.eclipse.org/releases/mars + https://download.eclipse.org/releases/mars From 160762e4d9b975844210a700015fac6d6237db5f Mon Sep 17 00:00:00 2001 From: plumpy Date: Mon, 4 Nov 2019 10:09:13 -0800 Subject: [PATCH 011/379] Update the OSS gjf plugin to work with 2019.3. Fixes #404 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=278406689 --- idea_plugin/build.gradle | 7 +++---- .../intellij/CodeStyleManagerDecorator.java | 4 ++++ .../intellij/GoogleJavaFormatInstaller.java | 18 +++++++++++++++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 762e58e89..23691f62a 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "0.4.9" + id "org.jetbrains.intellij" version "0.4.11" } repositories { @@ -31,14 +31,13 @@ apply plugin: 'java' intellij { pluginName = "google-java-format" - updateSinceUntilBuild = true - version = "191.5849.21" + version = "193.4932.9-EAP-SNAPSHOT" } patchPluginXml { pluginDescription = "Formats source code using the google-java-format tool. This version of " + "the plugin uses version ${googleJavaFormatVersion} of the tool." - version = "${googleJavaFormatVersion}.0.2" + version = "${googleJavaFormatVersion}.0.3" sinceBuild = '173' untilBuild = '' } diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java index 893b50912..4602802c3 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java @@ -122,6 +122,10 @@ public int adjustLineIndent(Document document, int offset) { return delegate.adjustLineIndent(document, offset); } + public void scheduleIndentAdjustment(Document document, int offset) { + delegate.scheduleIndentAdjustment(document, offset); + } + @Override public boolean isLineToBeIndented(PsiFile file, int offset) { return delegate.isLineToBeIndented(file, offset); diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java index f16d6a2b2..f71ee3980 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java @@ -16,9 +16,15 @@ package com.google.googlejavaformat.intellij; +import com.intellij.ide.plugins.IdeaPluginDescriptor; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.components.ProjectComponent; +import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.project.Project; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.serviceContainer.PlatformComponentManagerImpl; import org.picocontainer.MutablePicoContainer; /** @@ -51,10 +57,20 @@ private static void installFormatter(Project project) { } private static void setManager(Project project, CodeStyleManager newManager) { - if (newManager != null) { + if (useNewServicesApi()) { + PlatformComponentManagerImpl platformComponentManager = + (PlatformComponentManagerImpl) project; + IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId("google-java-format")); + platformComponentManager.registerServiceInstance(CodeStyleManager.class, newManager, plugin); + } else { MutablePicoContainer container = (MutablePicoContainer) project.getPicoContainer(); container.unregisterComponent(CODE_STYLE_MANAGER_KEY); container.registerComponentInstance(CODE_STYLE_MANAGER_KEY, newManager); } } + + private static boolean useNewServicesApi() { + ApplicationInfo appInfo = ApplicationInfoImpl.getInstance(); + return appInfo.getBuild().getBaselineVersion() >= 193; + } } From 0eaf8067145958d7a630bb774e8bf9efa5f5970c Mon Sep 17 00:00:00 2001 From: plumpy Date: Mon, 4 Nov 2019 10:28:07 -0800 Subject: [PATCH 012/379] Update the changelog for 1.7.0.3. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=278410982 --- idea_plugin/resources/META-INF/plugin.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index aa8e8df1d..8b4bb1f70 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -12,6 +12,8 @@ +

1.7.0.3
+
Fixed the plugin on 2019.3 IDEs.
1.7.0.2
Added support for all IDEs after 2017.3.
1.7.0.1
From a27c99cd2e80f7d278efc3c0143ebee7252d2ae1 Mon Sep 17 00:00:00 2001 From: Carmi Grushko Date: Tue, 5 Nov 2019 13:02:17 -0800 Subject: [PATCH 013/379] Make JavaOutput.flush() public so it can be accessed by other formatters. Fixes #411 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=278690677 --- .../main/java/com/google/googlejavaformat/java/JavaOutput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java index 7b789977a..9e07763d2 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java @@ -178,7 +178,7 @@ public void indent(int indent) { } /** Flush any incomplete last line, then add the EOF token into our data structures. */ - void flush() { + public void flush() { String lastLine = lineBuilder.toString(); if (!CharMatcher.whitespace().matchesAllOf(lastLine)) { mutableLines.add(lastLine); From 1396e602678e1178ab049ea03c1315f1ccb636b0 Mon Sep 17 00:00:00 2001 From: Carmi Grushko Date: Tue, 5 Nov 2019 13:25:52 -0800 Subject: [PATCH 014/379] Pull JavaInput.{getkN,getToken} up to Input so `JavaOutput` can be reused in formatters of other languages. Fixes #412 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=278695343 --- .../java/com/google/googlejavaformat/Input.java | 14 ++++++++++++++ .../google/googlejavaformat/java/JavaInput.java | 6 ++++-- .../google/googlejavaformat/java/JavaOutput.java | 6 +++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Input.java b/core/src/main/java/com/google/googlejavaformat/Input.java index c2af02b7f..9e17c2bf6 100644 --- a/core/src/main/java/com/google/googlejavaformat/Input.java +++ b/core/src/main/java/com/google/googlejavaformat/Input.java @@ -111,6 +111,20 @@ public interface Token { public abstract String getText(); + /** + * Get the number of toks. + * + * @return the number of toks, including the EOF tok + */ + public abstract int getkN(); + + /** + * Get the Token by index. + * + * @param k the token index + */ + public abstract Token getToken(int k); + @Override public String toString() { return MoreObjects.toStringHelper(this).add("super", super.toString()).toString(); diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 1df0f812d..4781d5aed 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -594,7 +594,8 @@ Range characterRangeToTokenRange(int offset, int length) throws Formatt * * @return the number of toks, including the EOF tok */ - int getkN() { + @Override + public int getkN() { return kN; } @@ -603,7 +604,8 @@ int getkN() { * * @param k the token index */ - Token getToken(int k) { + @Override + public Token getToken(int k) { return kToToken[k]; } diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java index 9e07763d2..3c2248079 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java @@ -46,7 +46,7 @@ */ public final class JavaOutput extends Output { private final String lineSeparator; - private final JavaInput javaInput; // Used to follow along while emitting the output. + private final Input javaInput; // Used to follow along while emitting the output. private final CommentsHelper commentsHelper; // Used to re-flow comments. private final Map blankLines = new HashMap<>(); // Info on blank lines. private final RangeSet partialFormatRanges = TreeRangeSet.create(); @@ -62,10 +62,10 @@ public final class JavaOutput extends Output { /** * {@code JavaOutput} constructor. * - * @param javaInput the {@link JavaInput}, used to match up blank lines in the output + * @param javaInput the {@link Input}, used to match up blank lines in the output * @param commentsHelper the {@link CommentsHelper}, used to rewrite comments */ - public JavaOutput(String lineSeparator, JavaInput javaInput, CommentsHelper commentsHelper) { + public JavaOutput(String lineSeparator, Input javaInput, CommentsHelper commentsHelper) { this.lineSeparator = lineSeparator; this.javaInput = javaInput; this.commentsHelper = commentsHelper; From bd176704e73771d1dd582d2cd0ae2f8859ae9ca6 Mon Sep 17 00:00:00 2001 From: cushon Date: Mon, 11 Nov 2019 14:02:48 -0800 Subject: [PATCH 015/379] Add flag control for javadoc formatting Fixes #139, #149 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=279811849 --- .../java/CommandLineOptions.java | 18 +++++++++-- .../java/CommandLineOptionsParser.java | 3 ++ .../java/JavaCommentsHelper.java | 4 ++- .../java/JavaFormatterOptions.java | 16 ++++++++-- .../google/googlejavaformat/java/Main.java | 5 +++- .../googlejavaformat/java/UsageException.java | 2 ++ .../java/CommandLineOptionsParserTest.java | 9 ++++++ .../googlejavaformat/java/MainTest.java | 30 +++++++++++++++++++ 8 files changed, 81 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java index 80f1579bb..5a233284a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java @@ -42,6 +42,7 @@ final class CommandLineOptions { private final boolean setExitIfChanged; private final Optional assumeFilename; private final boolean reflowLongStrings; + private final boolean formatJavadoc; CommandLineOptions( ImmutableList files, @@ -59,7 +60,8 @@ final class CommandLineOptions { boolean dryRun, boolean setExitIfChanged, Optional assumeFilename, - boolean reflowLongStrings) { + boolean reflowLongStrings, + boolean formatJavadoc) { this.files = files; this.inPlace = inPlace; this.lines = lines; @@ -76,6 +78,7 @@ final class CommandLineOptions { this.setExitIfChanged = setExitIfChanged; this.assumeFilename = assumeFilename; this.reflowLongStrings = reflowLongStrings; + this.formatJavadoc = formatJavadoc; } /** The files to format. */ @@ -164,6 +167,10 @@ boolean isSelection() { return !lines().isEmpty() || !offsets().isEmpty() || !lengths().isEmpty(); } + boolean formatJavadoc() { + return formatJavadoc; + } + static Builder builder() { return new Builder(); } @@ -186,6 +193,7 @@ static class Builder { private boolean setExitIfChanged = false; private Optional assumeFilename = Optional.empty(); private boolean reflowLongStrings = true; + private boolean formatJavadoc = true; ImmutableList.Builder filesBuilder() { return files; @@ -265,6 +273,11 @@ Builder reflowLongStrings(boolean reflowLongStrings) { return this; } + Builder formatJavadoc(boolean formatJavadoc) { + this.formatJavadoc = formatJavadoc; + return this; + } + CommandLineOptions build() { return new CommandLineOptions( files.build(), @@ -282,7 +295,8 @@ CommandLineOptions build() { dryRun, setExitIfChanged, assumeFilename, - reflowLongStrings); + reflowLongStrings, + formatJavadoc); } } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java index 5abc54a6e..202382640 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java @@ -108,6 +108,9 @@ static CommandLineOptions parse(Iterable options) { case "--skip-reflowing-long-strings": optionsBuilder.reflowLongStrings(false); break; + case "--skip-javadoc-formatting": + optionsBuilder.formatJavadoc(false); + break; case "-": optionsBuilder.stdin(true); break; diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java b/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java index b29bc0115..346324a45 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java @@ -30,9 +30,11 @@ public final class JavaCommentsHelper implements CommentsHelper { private final String lineSeparator; + private final JavaFormatterOptions options; public JavaCommentsHelper(String lineSeparator, JavaFormatterOptions options) { this.lineSeparator = lineSeparator; + this.options = options; } @Override @@ -41,7 +43,7 @@ public String rewrite(Tok tok, int maxWidth, int column0) { return tok.getOriginalText(); } String text = tok.getOriginalText(); - if (tok.isJavadocComment()) { + if (tok.isJavadocComment() && options.formatJavadoc()) { text = JavadocFormatter.formatJavadoc(text, column0); } List lines = new ArrayList<>(); diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java b/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java index 950eca646..4d3d30d4c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java @@ -48,9 +48,11 @@ int indentationMultiplier() { } private final Style style; + private final boolean formatJavadoc; - private JavaFormatterOptions(Style style) { + private JavaFormatterOptions(Style style, boolean formatJavadoc) { this.style = style; + this.formatJavadoc = formatJavadoc; } /** Returns the multiplier for the unit of indent. */ @@ -58,6 +60,10 @@ public int indentationMultiplier() { return style.indentationMultiplier(); } + boolean formatJavadoc() { + return formatJavadoc; + } + /** Returns the code style. */ public Style style() { return style; @@ -76,6 +82,7 @@ public static Builder builder() { /** A builder for {@link JavaFormatterOptions}. */ public static class Builder { private Style style = Style.GOOGLE; + private boolean formatJavadoc = true; private Builder() {} @@ -84,8 +91,13 @@ public Builder style(Style style) { return this; } + Builder formatJavadoc(boolean formatJavadoc) { + this.formatJavadoc = formatJavadoc; + return this; + } + public JavaFormatterOptions build() { - return new JavaFormatterOptions(style); + return new JavaFormatterOptions(style, formatJavadoc); } } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 2304e5e59..9231bdae4 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -96,7 +96,10 @@ public int format(String... args) throws UsageException { } JavaFormatterOptions options = - JavaFormatterOptions.builder().style(parameters.aosp() ? Style.AOSP : Style.GOOGLE).build(); + JavaFormatterOptions.builder() + .style(parameters.aosp() ? Style.AOSP : Style.GOOGLE) + .formatJavadoc(parameters.formatJavadoc()) + .build(); if (parameters.stdin()) { return formatStdin(parameters, options); diff --git a/core/src/main/java/com/google/googlejavaformat/java/UsageException.java b/core/src/main/java/com/google/googlejavaformat/java/UsageException.java index 52dadb6ec..82c0843dc 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/UsageException.java +++ b/core/src/main/java/com/google/googlejavaformat/java/UsageException.java @@ -48,6 +48,8 @@ final class UsageException extends Exception { " Do not remove unused imports. Imports will still be sorted.", " . --skip-reflowing-long-strings", " Do not reflow string literals that exceed the column limit.", + " . --skip-javadoc-formatting", + " Do not reformat javadoc.", " --dry-run, -n", " Prints the paths of the files whose contents would change if the formatter were run" + " normally.", diff --git a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java index 66802f581..8d71f4dd6 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java @@ -54,6 +54,7 @@ public void defaults() { assertThat(options.dryRun()).isFalse(); assertThat(options.setExitIfChanged()).isFalse(); assertThat(options.reflowLongStrings()).isTrue(); + assertThat(options.formatJavadoc()).isTrue(); } @Test @@ -195,4 +196,12 @@ public void skipReflowLongStrings() { .reflowLongStrings()) .isFalse(); } + + @Test + public void skipJavadocFormatting() { + assertThat( + CommandLineOptionsParser.parse(Arrays.asList("--skip-javadoc-formatting")) + .formatJavadoc()) + .isFalse(); + } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index e0eed520f..0d559440d 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -565,4 +565,34 @@ public void noReflowLongStrings() throws Exception { assertThat(main.format("--skip-reflowing-long-strings", "-")).isEqualTo(0); assertThat(out.toString()).isEqualTo(joiner.join(expected)); } + + @Test + public void noFormatJavadoc() throws Exception { + String[] input = { + "/**", + " * graph", + " *", + " * graph", + " *", + " * @param foo lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do" + + " eiusmod tempor incididunt ut labore et dolore magna aliqua", + " */", + "class Test {", + " /**", + " * creates entropy", + " */", + " public static void main(String... args) {}", + "}", + "", + }; + InputStream in = new ByteArrayInputStream(joiner.join(input).getBytes(UTF_8)); + StringWriter out = new StringWriter(); + Main main = + new Main( + new PrintWriter(out, true), + new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.err, UTF_8)), true), + in); + assertThat(main.format("--skip-javadoc-formatting", "-")).isEqualTo(0); + assertThat(out.toString()).isEqualTo(joiner.join(input)); + } } From d1f6d8968fb4271b4cfb7aa55d8ab83daa0743b0 Mon Sep 17 00:00:00 2001 From: Elliotte Rusty Harold Date: Wed, 13 Nov 2019 16:07:21 -0800 Subject: [PATCH 016/379] Update versions of Truth and Guava in Maven build. Fixes #405 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=280302646 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 26936a5da..71c3245c4 100644 --- a/pom.xml +++ b/pom.xml @@ -95,9 +95,9 @@ UTF-8 1.8 - 27.0.1-jre + 28.1-jre 9+181-r4173-1 - 0.45 + 1.0 3.0.2 From 81aaab96cdde86e52863827b6bb09f5583707d89 Mon Sep 17 00:00:00 2001 From: Anthony Vanelverdinghe Date: Tue, 17 Dec 2019 17:07:16 -0800 Subject: [PATCH 017/379] Update outdated Javadoc links Fixes #409 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=286092096 --- core/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index e85174f22..32bfca798 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -87,8 +87,8 @@ UTF-8 UTF-8 - https://google.github.io/guava/releases/${guava.version}/api/docs/ - https://javadoc.io/page/com.google.code.findbugs/jsr305/${jsr305.version}/ + https://guava.dev/releases/${guava.version}/api/docs/ + https://javadoc.io/static/com.google.code.findbugs/jsr305/${jsr305.version}/ https://docs.oracle.com/javase/8/docs/api/ From ed40e472878b9daa215787e6d27164bf2ec6f8ea Mon Sep 17 00:00:00 2001 From: cushon Date: Thu, 19 Dec 2019 14:46:50 -0800 Subject: [PATCH 018/379] Fix a crash on c-style arrays in parameters Fixes https://github.com/google/google-java-format/issues/374 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=286467734 --- .../googlejavaformat/java/JavaInputAstVisitor.java | 6 ++++-- .../com/google/googlejavaformat/java/testdata/I374.input | 9 +++++++++ .../google/googlejavaformat/java/testdata/I374.output | 9 +++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I374.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I374.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index c0f645654..b3f6e5ade 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -2542,18 +2542,20 @@ private void visitToDeclare( String equals, Optional trailing) { sync(node); + TypeWithDims extractedDims = DimensionHelpers.extractDims(node.getType(), SortedDims.YES); + Optional typeWithDims = Optional.of(extractedDims); declareOne( kind, annotationsDirection, Optional.of(node.getModifiers()), - node.getType(), + extractedDims.node, node.getName(), "", equals, initializer, trailing, /* receiverExpression= */ Optional.empty(), - /* typeWithDims= */ Optional.empty()); + typeWithDims); } /** Does not omit the leading '<', which should be associated with the type name. */ diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I374.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I374.input new file mode 100644 index 000000000..2364f0c16 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I374.input @@ -0,0 +1,9 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface MyTypeAnno {} + +public class GjfFailure { + void m(int a @MyTypeAnno []) {} +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I374.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I374.output new file mode 100644 index 000000000..a36919e4d --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I374.output @@ -0,0 +1,9 @@ +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) +@interface MyTypeAnno {} + +public class GjfFailure { + void m(int a @MyTypeAnno []) {} +} From 45e4afbf9158a8ab40bff8179e2135972a2cde2e Mon Sep 17 00:00:00 2001 From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Thu, 19 Dec 2019 17:15:38 -0800 Subject: [PATCH 019/379] Add SBT plugin to readme Fixes #391 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=286493206 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 72d881944..c5fdee230 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,8 @@ Implementation`. * [Cosium/maven-git-code-format](https://github.com/Cosium/maven-git-code-format): A maven plugin that automatically deploys google-java-format as a pre-commit git hook. +* SBT plugins + * [sbt/sbt-java-formatter](https://github.com/sbt/sbt-java-formatter) * [maltzj/google-style-precommit-hook](https://github.com/maltzj/google-style-precommit-hook): A pre-commit (pre-commit.com) hook that will automatically run GJF whenever you commit code to your repository From 8a215cdd190fc8b0b87bef229542336aecde24e5 Mon Sep 17 00:00:00 2001 From: cushon Date: Fri, 20 Dec 2019 15:33:32 -0800 Subject: [PATCH 020/379] annotation/parameterless annotation Parameterless annotations aren't necessarily marker annotations. All we can tell about a use of an annotation is that it's parameterless, and that's how 4.8.5 is specified. Related: #360 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=286650854 --- .../googlejavaformat/java/JavaInputAstVisitor.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index b3f6e5ade..6a600e734 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -3546,26 +3546,27 @@ private boolean hasTrailingToken(Input input, List nodes, String /** * Can a local with a set of modifiers be declared with horizontal annotations? This is currently - * true if there is at most one marker annotation, and no others. + * true if there is at most one parameterless annotation, and no others. * * @param modifiers the list of {@link ModifiersTree}s * @return whether the local can be declared with horizontal annotations */ private Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifiers) { - int markerAnnotations = 0; + int parameterlessAnnotations = 0; for (AnnotationTree annotation : modifiers.getAnnotations()) { if (annotation.getArguments().isEmpty()) { - markerAnnotations++; + parameterlessAnnotations++; } } - return markerAnnotations <= 1 && markerAnnotations == modifiers.getAnnotations().size() + return parameterlessAnnotations <= 1 + && parameterlessAnnotations == modifiers.getAnnotations().size() ? Direction.HORIZONTAL : Direction.VERTICAL; } /** * Should a field with a set of modifiers be declared with horizontal annotations? This is - * currently true if all annotations are marker annotations. + * currently true if all annotations are parameterless annotations. */ private Direction fieldAnnotationDirection(ModifiersTree modifiers) { for (AnnotationTree annotation : modifiers.getAnnotations()) { From 1288c856efb4f3d03c65b40d13f25c32b30dc0ec Mon Sep 17 00:00:00 2001 From: Carmi Grushko Date: Fri, 3 Jan 2020 10:53:49 -0800 Subject: [PATCH 021/379] Tell maven-javadoc-plugin to target JDK 8 This unbreaks `mvn install` on AdoptOpenJDK 11. Presumably it unbreaks on all JDKs >= 11. Fixes #429 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=288016119 --- core/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/core/pom.xml b/core/pom.xml index 32bfca798..3900bb6b1 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -83,6 +83,7 @@ maven-javadoc-plugin + 8 UTF-8 UTF-8 UTF-8 From 05f57ec9610a6371c38106b5e356476f2223504f Mon Sep 17 00:00:00 2001 From: "Eckert, Alexander" Date: Mon, 6 Jan 2020 13:30:33 -0800 Subject: [PATCH 022/379] Remove trailing tabs from comments to make behavior idempotent. Fixes #422, fixes #423 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=288364171 --- .../googlejavaformat/java/JavaOutput.java | 22 +++++++++++-------- .../googlejavaformat/java/FormatterTest.java | 20 +++++++++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java index 3c2248079..c059318e8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java @@ -18,6 +18,7 @@ import com.google.common.base.CharMatcher; import com.google.common.base.MoreObjects; +import com.google.common.base.Strings; import com.google.common.collect.DiscreteDomain; import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; @@ -55,9 +56,9 @@ public final class JavaOutput extends Output { private final int kN; // The number of tokens or comments in the input, excluding the EOF. private int iLine = 0; // Closest corresponding line number on input. private int lastK = -1; // Last {@link Tok} index output. - private int spacesPending = 0; private int newlinesPending = 0; private StringBuilder lineBuilder = new StringBuilder(); + private StringBuilder spacesPending = new StringBuilder(); /** * {@code JavaOutput} constructor. @@ -121,7 +122,7 @@ public void append(String text, Range range) { if (newlinesPending == 0) { ++newlinesPending; } - spacesPending = 0; + spacesPending = new StringBuilder(); } else { boolean rangesSet = false; int textN = text.length(); @@ -129,7 +130,10 @@ public void append(String text, Range range) { char c = text.charAt(i); switch (c) { case ' ': - ++spacesPending; + spacesPending.append(' '); + break; + case '\t': + spacesPending.append('\t'); break; case '\r': if (i + 1 < text.length() && text.charAt(i + 1) == '\n') { @@ -137,7 +141,7 @@ public void append(String text, Range range) { } // falls through case '\n': - spacesPending = 0; + spacesPending = new StringBuilder(); ++newlinesPending; break; default: @@ -150,9 +154,9 @@ public void append(String text, Range range) { rangesSet = false; --newlinesPending; } - while (spacesPending > 0) { - lineBuilder.append(' '); - --spacesPending; + if (spacesPending.length() > 0) { + lineBuilder.append(spacesPending); + spacesPending = new StringBuilder(); } lineBuilder.append(c); if (!range.isEmpty()) { @@ -174,7 +178,7 @@ public void append(String text, Range range) { @Override public void indent(int indent) { - spacesPending = indent; + spacesPending.append(Strings.repeat(" ", indent)); } /** Flush any incomplete last line, then add the EOF token into our data structures. */ @@ -387,7 +391,7 @@ public String toString() { return MoreObjects.toStringHelper(this) .add("iLine", iLine) .add("lastK", lastK) - .add("spacesPending", spacesPending) + .add("spacesPending", spacesPending.toString().replace("\t", "\\t")) .add("newlinesPending", newlinesPending) .add("blankLines", blankLines) .add("super", super.toString()) diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java index 952727808..3f6e974d1 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java @@ -472,4 +472,24 @@ public void dontWrapMoeLineComments() throws Exception { + " chance to interrupt;\n" + "}\n"); } + + @Test + public void removeTrailingTabsInComments() throws Exception { + assertThat( + new Formatter() + .formatSource( + "class Foo {\n" + + " void f() {\n" + + " int x = 0; // comment\t\t\t\n" + + " return;\n" + + " }\n" + + "}\n")) + .isEqualTo( + "class Foo {\n" + + " void f() {\n" + + " int x = 0; // comment\n" + + " return;\n" + + " }\n" + + "}\n"); + } } From eb76f92acdc2b02bacab29f412551c7c40ccb0e8 Mon Sep 17 00:00:00 2001 From: cushon Date: Fri, 13 Mar 2020 14:03:22 -0700 Subject: [PATCH 023/379] Migrate from JSR-305 to the Checker Framework annotations this is tangentially related to Java 11 preparedness. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=300822964 --- core/pom.xml | 5 ++--- .../google/googlejavaformat/java/JavaInputAstVisitor.java | 2 +- .../googlejavaformat/java/filer/FormattingFiler.java | 2 +- .../java/filer/FormattingJavaFileObject.java | 2 +- .../intellij/CodeStyleManagerDecorator.java | 2 +- .../intellij/GoogleJavaFormatConfigurable.java | 2 +- .../intellij/GoogleJavaFormatSettings.java | 2 +- pom.xml | 8 ++++---- 8 files changed, 12 insertions(+), 13 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 3900bb6b1..92de6d1a5 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -46,8 +46,8 @@ - com.google.code.findbugs - jsr305 + org.checkerframework + checker-qual true @@ -89,7 +89,6 @@ UTF-8 https://guava.dev/releases/${guava.version}/api/docs/ - https://javadoc.io/static/com.google.code.findbugs/jsr305/${jsr305.version}/ https://docs.oracle.com/javase/8/docs/api/ diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 6a600e734..23cae5f0c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -81,7 +81,7 @@ import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Stream; -import javax.annotation.Nullable; +import org.checkerframework.checker.nullness.qual.Nullable; import org.openjdk.javax.lang.model.element.Name; import org.openjdk.source.tree.AnnotatedTypeTree; import org.openjdk.source.tree.AnnotationTree; diff --git a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java index 7c7894754..d38d84eca 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java +++ b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java @@ -18,13 +18,13 @@ import com.google.googlejavaformat.java.Formatter; import java.io.IOException; -import javax.annotation.Nullable; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.lang.model.element.Element; import javax.tools.FileObject; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; +import org.checkerframework.checker.nullness.qual.Nullable; /** * A decorating {@link Filer} implementation which formats Java source files with a {@link diff --git a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java index 83728a0b4..c8ae80769 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java +++ b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java @@ -22,11 +22,11 @@ import com.google.googlejavaformat.java.FormatterException; import java.io.IOException; import java.io.Writer; -import javax.annotation.Nullable; import javax.annotation.processing.Messager; import javax.tools.Diagnostic; import javax.tools.ForwardingJavaFileObject; import javax.tools.JavaFileObject; +import org.checkerframework.checker.nullness.qual.Nullable; /** A {@link JavaFileObject} decorator which {@linkplain Formatter formats} source code. */ final class FormattingJavaFileObject extends ForwardingJavaFileObject { diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java index 4602802c3..ee28e1bc8 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java @@ -33,7 +33,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.ThrowableRunnable; import java.util.Collection; -import javax.annotation.Nullable; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Decorates the {@link CodeStyleManager} abstract class by delegating to a concrete implementation diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java index 79859581a..2f34b7471 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java @@ -26,12 +26,12 @@ import com.intellij.uiDesigner.core.GridLayoutManager; import com.intellij.uiDesigner.core.Spacer; import java.awt.Insets; -import javax.annotation.Nullable; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; +import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java index 15449d701..f6d9b5ff1 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java @@ -22,7 +22,7 @@ import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.project.Project; -import javax.annotation.Nullable; +import org.checkerframework.checker.nullness.qual.Nullable; @State( name = "GoogleJavaFormatSettings", diff --git a/pom.xml b/pom.xml index 71c3245c4..edb5bbb86 100644 --- a/pom.xml +++ b/pom.xml @@ -98,7 +98,7 @@ 28.1-jre 9+181-r4173-1 1.0 - 3.0.2 + 2.0.0 @@ -117,9 +117,9 @@ - com.google.code.findbugs - jsr305 - ${jsr305.version} + org.checkerframework + checker-qual + ${checker.version} com.google.errorprone From cdf7665ef22253427f9312e04001ddb1349736f9 Mon Sep 17 00:00:00 2001 From: cushon Date: Mon, 16 Mar 2020 17:37:44 -0700 Subject: [PATCH 024/379] Add Java 11 regression tests ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=301273002 --- .../google/googlejavaformat/java/testdata/java11.input | 9 +++++++++ .../google/googlejavaformat/java/testdata/java11.output | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/java11.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/java11.output diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java11.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java11.input new file mode 100644 index 000000000..97bd4ac20 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java11.input @@ -0,0 +1,9 @@ +class Java11 { + interface I { + private default void f() {} + } + + public static void main(String[] args) { + var x = 42; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java11.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java11.output new file mode 100644 index 000000000..97bd4ac20 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java11.output @@ -0,0 +1,9 @@ +class Java11 { + interface I { + private default void f() {} + } + + public static void main(String[] args) { + var x = 42; + } +} From 3c191c1326b77aabbf2a48c3edc19b628f4327d6 Mon Sep 17 00:00:00 2001 From: cushon Date: Wed, 18 Mar 2020 12:40:25 -0700 Subject: [PATCH 025/379] Use the built-in JDK 11 javac instead of relying on the shaded/vendored version. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=301645476 --- core/pom.xml | 28 +++- .../java/DimensionHelpers.java | 10 +- .../googlejavaformat/java/Formatter.java | 28 ++-- .../java/FormatterException.java | 4 +- .../googlejavaformat/java/ImportOrderer.java | 2 +- .../googlejavaformat/java/JavaInput.java | 24 +-- .../java/JavaInputAstVisitor.java | 158 +++++++++--------- .../googlejavaformat/java/JavacTokens.java | 18 +- .../java/ModifierOrderer.java | 4 +- .../java/RemoveUnusedImports.java | 62 +++---- .../googlejavaformat/java/StringWrapper.java | 42 ++--- .../google/googlejavaformat/java/Trees.java | 26 +-- pom.xml | 40 +---- 13 files changed, 219 insertions(+), 227 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 92de6d1a5..6ec553fb0 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -39,10 +39,6 @@ com.google.guava guava - - com.google.errorprone - javac-shaded - @@ -83,14 +79,26 @@ maven-javadoc-plugin - 8 + 11 UTF-8 UTF-8 UTF-8 + + https://docs.oracle.com/en/java/javase/11/docs/api + + --add-exports=jdk.compiler/com.sun.tools.javac.file=com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.main=com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.parser=com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.tree=com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.util=com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.code=com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.api=com.google.googlejavaformat + @@ -238,6 +246,14 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + diff --git a/core/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java b/core/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java index a18db691e..4bd19bee3 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java +++ b/core/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java @@ -15,16 +15,16 @@ package com.google.googlejavaformat.java; import com.google.common.collect.ImmutableList; +import com.sun.source.tree.AnnotatedTypeTree; +import com.sun.source.tree.AnnotationTree; +import com.sun.source.tree.ArrayTypeTree; +import com.sun.source.tree.Tree; +import com.sun.tools.javac.tree.JCTree; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; import java.util.Deque; import java.util.List; -import org.openjdk.source.tree.AnnotatedTypeTree; -import org.openjdk.source.tree.AnnotationTree; -import org.openjdk.source.tree.ArrayTypeTree; -import org.openjdk.source.tree.Tree; -import org.openjdk.tools.javac.tree.JCTree; /** * Utilities for working with array dimensions. diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index e53f79fcf..59a1a5e29 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -31,26 +31,26 @@ import com.google.googlejavaformat.Newlines; import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpsBuilder; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.main.Option; +import com.sun.tools.javac.parser.JavacParser; +import com.sun.tools.javac.parser.ParserFactory; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Options; import java.io.IOError; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.openjdk.javax.tools.Diagnostic; -import org.openjdk.javax.tools.DiagnosticCollector; -import org.openjdk.javax.tools.DiagnosticListener; -import org.openjdk.javax.tools.JavaFileObject; -import org.openjdk.javax.tools.SimpleJavaFileObject; -import org.openjdk.javax.tools.StandardLocation; -import org.openjdk.tools.javac.file.JavacFileManager; -import org.openjdk.tools.javac.main.Option; -import org.openjdk.tools.javac.parser.JavacParser; -import org.openjdk.tools.javac.parser.ParserFactory; -import org.openjdk.tools.javac.tree.JCTree.JCCompilationUnit; -import org.openjdk.tools.javac.util.Context; -import org.openjdk.tools.javac.util.Log; -import org.openjdk.tools.javac.util.Options; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.DiagnosticListener; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardLocation; /** * This is google-java-format, a new Java formatter that follows the Google Java Style Guide quite diff --git a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java index 972b8ce06..3ccb44a46 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java +++ b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java @@ -20,8 +20,8 @@ import com.google.common.collect.Iterables; import com.google.googlejavaformat.FormatterDiagnostic; import java.util.List; -import org.openjdk.javax.tools.Diagnostic; -import org.openjdk.javax.tools.JavaFileObject; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; /** Checked exception class for formatter errors. */ public final class FormatterException extends Exception { diff --git a/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java b/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java index a364c15e8..a82715e0a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java @@ -25,13 +25,13 @@ import com.google.googlejavaformat.Newlines; import com.google.googlejavaformat.java.JavaFormatterOptions.Style; import com.google.googlejavaformat.java.JavaInput.Tok; +import com.sun.tools.javac.parser.Tokens.TokenKind; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.function.BiFunction; import java.util.stream.Stream; -import org.openjdk.tools.javac.parser.Tokens.TokenKind; /** Orders imports in Java source code. */ public class ImportOrderer { diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 4781d5aed..e5e4f4580 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -33,24 +33,24 @@ import com.google.googlejavaformat.Input; import com.google.googlejavaformat.Newlines; import com.google.googlejavaformat.java.JavacTokens.RawTok; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.parser.Tokens.TokenKind; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; -import org.openjdk.javax.tools.Diagnostic; -import org.openjdk.javax.tools.DiagnosticCollector; -import org.openjdk.javax.tools.DiagnosticListener; -import org.openjdk.javax.tools.JavaFileObject; -import org.openjdk.javax.tools.JavaFileObject.Kind; -import org.openjdk.javax.tools.SimpleJavaFileObject; -import org.openjdk.tools.javac.file.JavacFileManager; -import org.openjdk.tools.javac.parser.Tokens.TokenKind; -import org.openjdk.tools.javac.tree.JCTree.JCCompilationUnit; -import org.openjdk.tools.javac.util.Context; -import org.openjdk.tools.javac.util.Log; -import org.openjdk.tools.javac.util.Log.DeferredDiagnosticHandler; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.DiagnosticListener; +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.SimpleJavaFileObject; /** {@code JavaInput} extends {@link Input} to represent a Java input document. */ public final class JavaInput extends Input { diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 23cae5f0c..06543598a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -29,19 +29,19 @@ import static com.google.googlejavaformat.java.Trees.operatorName; import static com.google.googlejavaformat.java.Trees.precedence; import static com.google.googlejavaformat.java.Trees.skipParen; +import static com.sun.source.tree.Tree.Kind.ANNOTATION; +import static com.sun.source.tree.Tree.Kind.ARRAY_ACCESS; +import static com.sun.source.tree.Tree.Kind.ASSIGNMENT; +import static com.sun.source.tree.Tree.Kind.BLOCK; +import static com.sun.source.tree.Tree.Kind.EXTENDS_WILDCARD; +import static com.sun.source.tree.Tree.Kind.IF; +import static com.sun.source.tree.Tree.Kind.METHOD_INVOCATION; +import static com.sun.source.tree.Tree.Kind.NEW_ARRAY; +import static com.sun.source.tree.Tree.Kind.NEW_CLASS; +import static com.sun.source.tree.Tree.Kind.STRING_LITERAL; +import static com.sun.source.tree.Tree.Kind.UNION_TYPE; +import static com.sun.source.tree.Tree.Kind.VARIABLE; import static java.util.stream.Collectors.toList; -import static org.openjdk.source.tree.Tree.Kind.ANNOTATION; -import static org.openjdk.source.tree.Tree.Kind.ARRAY_ACCESS; -import static org.openjdk.source.tree.Tree.Kind.ASSIGNMENT; -import static org.openjdk.source.tree.Tree.Kind.BLOCK; -import static org.openjdk.source.tree.Tree.Kind.EXTENDS_WILDCARD; -import static org.openjdk.source.tree.Tree.Kind.IF; -import static org.openjdk.source.tree.Tree.Kind.METHOD_INVOCATION; -import static org.openjdk.source.tree.Tree.Kind.NEW_ARRAY; -import static org.openjdk.source.tree.Tree.Kind.NEW_CLASS; -import static org.openjdk.source.tree.Tree.Kind.STRING_LITERAL; -import static org.openjdk.source.tree.Tree.Kind.UNION_TYPE; -import static org.openjdk.source.tree.Tree.Kind.VARIABLE; import com.google.common.base.MoreObjects; import com.google.common.base.Predicate; @@ -69,6 +69,72 @@ import com.google.googlejavaformat.Output.BreakTag; import com.google.googlejavaformat.java.DimensionHelpers.SortedDims; import com.google.googlejavaformat.java.DimensionHelpers.TypeWithDims; +import com.sun.source.tree.AnnotatedTypeTree; +import com.sun.source.tree.AnnotationTree; +import com.sun.source.tree.ArrayAccessTree; +import com.sun.source.tree.ArrayTypeTree; +import com.sun.source.tree.AssertTree; +import com.sun.source.tree.AssignmentTree; +import com.sun.source.tree.BinaryTree; +import com.sun.source.tree.BlockTree; +import com.sun.source.tree.BreakTree; +import com.sun.source.tree.CaseTree; +import com.sun.source.tree.CatchTree; +import com.sun.source.tree.ClassTree; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.CompoundAssignmentTree; +import com.sun.source.tree.ConditionalExpressionTree; +import com.sun.source.tree.ContinueTree; +import com.sun.source.tree.DirectiveTree; +import com.sun.source.tree.DoWhileLoopTree; +import com.sun.source.tree.EmptyStatementTree; +import com.sun.source.tree.EnhancedForLoopTree; +import com.sun.source.tree.ExportsTree; +import com.sun.source.tree.ExpressionStatementTree; +import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.ForLoopTree; +import com.sun.source.tree.IdentifierTree; +import com.sun.source.tree.IfTree; +import com.sun.source.tree.ImportTree; +import com.sun.source.tree.InstanceOfTree; +import com.sun.source.tree.IntersectionTypeTree; +import com.sun.source.tree.LabeledStatementTree; +import com.sun.source.tree.LambdaExpressionTree; +import com.sun.source.tree.LiteralTree; +import com.sun.source.tree.MemberReferenceTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.MethodInvocationTree; +import com.sun.source.tree.MethodTree; +import com.sun.source.tree.ModifiersTree; +import com.sun.source.tree.ModuleTree; +import com.sun.source.tree.NewArrayTree; +import com.sun.source.tree.NewClassTree; +import com.sun.source.tree.OpensTree; +import com.sun.source.tree.ParameterizedTypeTree; +import com.sun.source.tree.ParenthesizedTree; +import com.sun.source.tree.PrimitiveTypeTree; +import com.sun.source.tree.ProvidesTree; +import com.sun.source.tree.RequiresTree; +import com.sun.source.tree.ReturnTree; +import com.sun.source.tree.StatementTree; +import com.sun.source.tree.SwitchTree; +import com.sun.source.tree.SynchronizedTree; +import com.sun.source.tree.ThrowTree; +import com.sun.source.tree.Tree; +import com.sun.source.tree.TryTree; +import com.sun.source.tree.TypeCastTree; +import com.sun.source.tree.TypeParameterTree; +import com.sun.source.tree.UnaryTree; +import com.sun.source.tree.UnionTypeTree; +import com.sun.source.tree.UsesTree; +import com.sun.source.tree.VariableTree; +import com.sun.source.tree.WhileLoopTree; +import com.sun.source.tree.WildcardTree; +import com.sun.source.util.TreePath; +import com.sun.source.util.TreePathScanner; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeScanner; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -81,74 +147,8 @@ import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Stream; +import javax.lang.model.element.Name; import org.checkerframework.checker.nullness.qual.Nullable; -import org.openjdk.javax.lang.model.element.Name; -import org.openjdk.source.tree.AnnotatedTypeTree; -import org.openjdk.source.tree.AnnotationTree; -import org.openjdk.source.tree.ArrayAccessTree; -import org.openjdk.source.tree.ArrayTypeTree; -import org.openjdk.source.tree.AssertTree; -import org.openjdk.source.tree.AssignmentTree; -import org.openjdk.source.tree.BinaryTree; -import org.openjdk.source.tree.BlockTree; -import org.openjdk.source.tree.BreakTree; -import org.openjdk.source.tree.CaseTree; -import org.openjdk.source.tree.CatchTree; -import org.openjdk.source.tree.ClassTree; -import org.openjdk.source.tree.CompilationUnitTree; -import org.openjdk.source.tree.CompoundAssignmentTree; -import org.openjdk.source.tree.ConditionalExpressionTree; -import org.openjdk.source.tree.ContinueTree; -import org.openjdk.source.tree.DirectiveTree; -import org.openjdk.source.tree.DoWhileLoopTree; -import org.openjdk.source.tree.EmptyStatementTree; -import org.openjdk.source.tree.EnhancedForLoopTree; -import org.openjdk.source.tree.ExportsTree; -import org.openjdk.source.tree.ExpressionStatementTree; -import org.openjdk.source.tree.ExpressionTree; -import org.openjdk.source.tree.ForLoopTree; -import org.openjdk.source.tree.IdentifierTree; -import org.openjdk.source.tree.IfTree; -import org.openjdk.source.tree.ImportTree; -import org.openjdk.source.tree.InstanceOfTree; -import org.openjdk.source.tree.IntersectionTypeTree; -import org.openjdk.source.tree.LabeledStatementTree; -import org.openjdk.source.tree.LambdaExpressionTree; -import org.openjdk.source.tree.LiteralTree; -import org.openjdk.source.tree.MemberReferenceTree; -import org.openjdk.source.tree.MemberSelectTree; -import org.openjdk.source.tree.MethodInvocationTree; -import org.openjdk.source.tree.MethodTree; -import org.openjdk.source.tree.ModifiersTree; -import org.openjdk.source.tree.ModuleTree; -import org.openjdk.source.tree.NewArrayTree; -import org.openjdk.source.tree.NewClassTree; -import org.openjdk.source.tree.OpensTree; -import org.openjdk.source.tree.ParameterizedTypeTree; -import org.openjdk.source.tree.ParenthesizedTree; -import org.openjdk.source.tree.PrimitiveTypeTree; -import org.openjdk.source.tree.ProvidesTree; -import org.openjdk.source.tree.RequiresTree; -import org.openjdk.source.tree.ReturnTree; -import org.openjdk.source.tree.StatementTree; -import org.openjdk.source.tree.SwitchTree; -import org.openjdk.source.tree.SynchronizedTree; -import org.openjdk.source.tree.ThrowTree; -import org.openjdk.source.tree.Tree; -import org.openjdk.source.tree.TryTree; -import org.openjdk.source.tree.TypeCastTree; -import org.openjdk.source.tree.TypeParameterTree; -import org.openjdk.source.tree.UnaryTree; -import org.openjdk.source.tree.UnionTypeTree; -import org.openjdk.source.tree.UsesTree; -import org.openjdk.source.tree.VariableTree; -import org.openjdk.source.tree.WhileLoopTree; -import org.openjdk.source.tree.WildcardTree; -import org.openjdk.source.util.TreePath; -import org.openjdk.source.util.TreePathScanner; -import org.openjdk.tools.javac.code.Flags; -import org.openjdk.tools.javac.tree.JCTree; -import org.openjdk.tools.javac.tree.TreeScanner; /** * An AST visitor that builds a stream of {@link Op}s to format from the given {@link diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java index 72f8bce3a..a8c9efd2c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java @@ -18,16 +18,16 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import com.sun.tools.javac.parser.JavaTokenizer; +import com.sun.tools.javac.parser.Scanner; +import com.sun.tools.javac.parser.ScannerFactory; +import com.sun.tools.javac.parser.Tokens.Comment; +import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; +import com.sun.tools.javac.parser.Tokens.Token; +import com.sun.tools.javac.parser.Tokens.TokenKind; +import com.sun.tools.javac.parser.UnicodeReader; +import com.sun.tools.javac.util.Context; import java.util.Set; -import org.openjdk.tools.javac.parser.JavaTokenizer; -import org.openjdk.tools.javac.parser.Scanner; -import org.openjdk.tools.javac.parser.ScannerFactory; -import org.openjdk.tools.javac.parser.Tokens.Comment; -import org.openjdk.tools.javac.parser.Tokens.Comment.CommentStyle; -import org.openjdk.tools.javac.parser.Tokens.Token; -import org.openjdk.tools.javac.parser.Tokens.TokenKind; -import org.openjdk.tools.javac.parser.UnicodeReader; -import org.openjdk.tools.javac.util.Context; /** A wrapper around javac's lexer. */ class JavacTokens { diff --git a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java index 239973226..f7f610be7 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java @@ -23,6 +23,7 @@ import com.google.common.collect.TreeRangeMap; import com.google.googlejavaformat.Input.Tok; import com.google.googlejavaformat.Input.Token; +import com.sun.tools.javac.parser.Tokens.TokenKind; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -30,8 +31,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.openjdk.javax.lang.model.element.Modifier; -import org.openjdk.tools.javac.parser.Tokens.TokenKind; +import javax.lang.model.element.Modifier; /** Fixes sequences of modifiers to be in JLS order. */ final class ModifierOrderer { diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index bd2fa8171..8bc2f0541 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -29,42 +29,42 @@ import com.google.common.collect.TreeRangeMap; import com.google.common.collect.TreeRangeSet; import com.google.googlejavaformat.Newlines; +import com.sun.source.doctree.DocCommentTree; +import com.sun.source.doctree.ReferenceTree; +import com.sun.source.tree.IdentifierTree; +import com.sun.source.tree.ImportTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.DocTreePath; +import com.sun.source.util.DocTreePathScanner; +import com.sun.source.util.TreePathScanner; +import com.sun.source.util.TreeScanner; +import com.sun.tools.javac.api.JavacTrees; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.main.Option; +import com.sun.tools.javac.parser.JavacParser; +import com.sun.tools.javac.parser.ParserFactory; +import com.sun.tools.javac.tree.DCTree; +import com.sun.tools.javac.tree.DCTree.DCReference; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; +import com.sun.tools.javac.tree.JCTree.JCIdent; +import com.sun.tools.javac.tree.JCTree.JCImport; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Options; import java.io.IOError; import java.io.IOException; import java.net.URI; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; -import org.openjdk.javax.tools.Diagnostic; -import org.openjdk.javax.tools.DiagnosticCollector; -import org.openjdk.javax.tools.DiagnosticListener; -import org.openjdk.javax.tools.JavaFileObject; -import org.openjdk.javax.tools.SimpleJavaFileObject; -import org.openjdk.javax.tools.StandardLocation; -import org.openjdk.source.doctree.DocCommentTree; -import org.openjdk.source.doctree.ReferenceTree; -import org.openjdk.source.tree.IdentifierTree; -import org.openjdk.source.tree.ImportTree; -import org.openjdk.source.tree.Tree; -import org.openjdk.source.util.DocTreePath; -import org.openjdk.source.util.DocTreePathScanner; -import org.openjdk.source.util.TreePathScanner; -import org.openjdk.source.util.TreeScanner; -import org.openjdk.tools.javac.api.JavacTrees; -import org.openjdk.tools.javac.file.JavacFileManager; -import org.openjdk.tools.javac.main.Option; -import org.openjdk.tools.javac.parser.JavacParser; -import org.openjdk.tools.javac.parser.ParserFactory; -import org.openjdk.tools.javac.tree.DCTree; -import org.openjdk.tools.javac.tree.DCTree.DCReference; -import org.openjdk.tools.javac.tree.JCTree; -import org.openjdk.tools.javac.tree.JCTree.JCCompilationUnit; -import org.openjdk.tools.javac.tree.JCTree.JCFieldAccess; -import org.openjdk.tools.javac.tree.JCTree.JCIdent; -import org.openjdk.tools.javac.tree.JCTree.JCImport; -import org.openjdk.tools.javac.util.Context; -import org.openjdk.tools.javac.util.Log; -import org.openjdk.tools.javac.util.Options; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.DiagnosticListener; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardLocation; /** * Removes unused imports from a source file. Imports that are only used in javadoc are also @@ -138,7 +138,7 @@ private void scanJavadoc() { // scan javadoc comments, checking for references to imported types class DocTreeScanner extends DocTreePathScanner { @Override - public Void visitIdentifier(org.openjdk.source.doctree.IdentifierTree node, Void aVoid) { + public Void visitIdentifier(com.sun.source.doctree.IdentifierTree node, Void aVoid) { return null; } diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 6dfca5335..6bb63db3a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -26,6 +26,21 @@ import com.google.common.collect.Range; import com.google.common.collect.TreeRangeMap; import com.google.googlejavaformat.Newlines; +import com.sun.source.tree.BinaryTree; +import com.sun.source.tree.LiteralTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.Tree; +import com.sun.source.tree.Tree.Kind; +import com.sun.source.util.TreePath; +import com.sun.source.util.TreePathScanner; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.parser.JavacParser; +import com.sun.tools.javac.parser.ParserFactory; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Options; +import com.sun.tools.javac.util.Position; import java.io.IOException; import java.io.UncheckedIOException; import java.net.URI; @@ -37,27 +52,12 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; -import org.openjdk.javax.tools.Diagnostic; -import org.openjdk.javax.tools.DiagnosticCollector; -import org.openjdk.javax.tools.DiagnosticListener; -import org.openjdk.javax.tools.JavaFileObject; -import org.openjdk.javax.tools.SimpleJavaFileObject; -import org.openjdk.javax.tools.StandardLocation; -import org.openjdk.source.tree.BinaryTree; -import org.openjdk.source.tree.LiteralTree; -import org.openjdk.source.tree.MemberSelectTree; -import org.openjdk.source.tree.Tree; -import org.openjdk.source.tree.Tree.Kind; -import org.openjdk.source.util.TreePath; -import org.openjdk.source.util.TreePathScanner; -import org.openjdk.tools.javac.file.JavacFileManager; -import org.openjdk.tools.javac.parser.JavacParser; -import org.openjdk.tools.javac.parser.ParserFactory; -import org.openjdk.tools.javac.tree.JCTree; -import org.openjdk.tools.javac.util.Context; -import org.openjdk.tools.javac.util.Log; -import org.openjdk.tools.javac.util.Options; -import org.openjdk.tools.javac.util.Position; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.DiagnosticListener; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardLocation; /** Wraps string literals that exceed the column limit. */ public final class StringWrapper { diff --git a/core/src/main/java/com/google/googlejavaformat/java/Trees.java b/core/src/main/java/com/google/googlejavaformat/java/Trees.java index 69b954c4f..397dacae6 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Trees.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Trees.java @@ -14,21 +14,21 @@ package com.google.googlejavaformat.java; +import com.sun.source.tree.ClassTree; +import com.sun.source.tree.CompoundAssignmentTree; +import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.IdentifierTree; +import com.sun.source.tree.MemberSelectTree; +import com.sun.source.tree.MethodInvocationTree; +import com.sun.source.tree.ParenthesizedTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.TreePath; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.Pretty; +import com.sun.tools.javac.tree.TreeInfo; import java.io.IOError; import java.io.IOException; -import org.openjdk.javax.lang.model.element.Name; -import org.openjdk.source.tree.ClassTree; -import org.openjdk.source.tree.CompoundAssignmentTree; -import org.openjdk.source.tree.ExpressionTree; -import org.openjdk.source.tree.IdentifierTree; -import org.openjdk.source.tree.MemberSelectTree; -import org.openjdk.source.tree.MethodInvocationTree; -import org.openjdk.source.tree.ParenthesizedTree; -import org.openjdk.source.tree.Tree; -import org.openjdk.source.util.TreePath; -import org.openjdk.tools.javac.tree.JCTree; -import org.openjdk.tools.javac.tree.Pretty; -import org.openjdk.tools.javac.tree.TreeInfo; +import javax.lang.model.element.Name; /** Utilities for working with {@link Tree}s. */ class Trees { diff --git a/pom.xml b/pom.xml index edb5bbb86..a0952ec9d 100644 --- a/pom.xml +++ b/pom.xml @@ -96,7 +96,6 @@ UTF-8 1.8 28.1-jre - 9+181-r4173-1 1.0 2.0.0 @@ -109,11 +108,6 @@ guava ${guava.version} - - com.google.errorprone - javac-shaded - ${javac.version} - @@ -166,7 +160,7 @@ maven-javadoc-plugin - 3.0.0 + 3.1.1 maven-gpg-plugin @@ -189,6 +183,13 @@ -XDcompilePolicy=simple -Xplugin:ErrorProne + --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED @@ -248,29 +249,4 @@ - - - - - jdk8 - - 1.8 - - - - - org.apache.maven.plugins - maven-compiler-plugin - - true - - -J-Xbootclasspath/p:${settings.localRepository}/com/google/errorprone/javac/${javac.version}/javac-${javac.version}.jar - - - - - - - - From 20e38aa2442c9e1557320f45926e17c621eeadf1 Mon Sep 17 00:00:00 2001 From: cushon Date: Thu, 19 Mar 2020 09:34:26 -0700 Subject: [PATCH 026/379] Increase minimum required JDK version to 11 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=301832060 --- .travis.yml | 3 --- appveyor.yml | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 829f0fe06..048e3ed19 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,6 @@ notifications: on_failure: always jdk: - - openjdk8 - - openjdk9 - - openjdk10 - openjdk11 - openjdk-ea diff --git a/appveyor.yml b/appveyor.yml index a4c7ee9cb..3522155d1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,6 +9,7 @@ install: ) [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\maven-bin.zip", "C:\maven") } + - cmd: SET JAVA_HOME=C:\Program Files\Java\jdk11 - cmd: SET PATH=C:\maven\apache-maven-3.3.9\bin;%JAVA_HOME%\bin;%PATH% - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g From d6d0b4d45096b0387b427ccf1e35ddbc9571fd0e Mon Sep 17 00:00:00 2001 From: cushon Date: Fri, 20 Mar 2020 14:59:46 -0700 Subject: [PATCH 027/379] Use the default / latest supported language level Previously the shaded javac was defaulting to Java 8, which we needed to override to support Java 9. Now that we're using stock JDK 11 this is unnecessary. Also explicitly support `var`, instead of relying on it getting parsed as an actual type name. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=302105420 --- .../java/com/google/googlejavaformat/java/Formatter.java | 5 ----- .../google/googlejavaformat/java/JavaInputAstVisitor.java | 8 ++++++-- .../google/googlejavaformat/java/RemoveUnusedImports.java | 3 --- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index 59a1a5e29..4348506b8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -32,7 +32,6 @@ import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpsBuilder; import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.main.Option; import com.sun.tools.javac.parser.JavacParser; import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; @@ -116,10 +115,6 @@ static void format(final JavaInput javaInput, JavaOutput javaOutput, JavaFormatt DiagnosticCollector diagnostics = new DiagnosticCollector<>(); context.put(DiagnosticListener.class, diagnostics); Options.instance(context).put("allowStringFolding", "false"); - // TODO(cushon): this should default to the latest supported source level, remove this after - // backing out - // https://github.com/google/error-prone-javac/commit/c97f34ddd2308302587ce2de6d0c984836ea5b9f - Options.instance(context).put(Option.SOURCE, "9"); JCCompilationUnit unit; JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8); try { diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 06543598a..8edd68049 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -3251,7 +3251,9 @@ int declareOne( visitAndBreakModifiers( modifiers.get(), annotationsDirection, Optional.of(verticalAnnotationBreak)); } - builder.open(type != null ? plusFour : ZERO); + boolean isVar = builder.peekToken().get().equals("var"); + boolean hasType = type != null || isVar; + builder.open(hasType ? plusFour : ZERO); { builder.open(ZERO); { @@ -3264,13 +3266,15 @@ int declareOne( maybeAddDims(dims); builder.close(); baseDims = totalDims - dims.size(); + } else if (isVar) { + token("var"); } else { scan(type, null); } } builder.close(); - if (type != null) { + if (hasType) { builder.breakOp(Doc.FillMode.INDEPENDENT, " ", ZERO, Optional.of(typeBreak)); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index 8bc2f0541..9d0bb27d2 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -40,7 +40,6 @@ import com.sun.source.util.TreeScanner; import com.sun.tools.javac.api.JavacTrees; import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.main.Option; import com.sun.tools.javac.parser.JavacParser; import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.tree.DCTree; @@ -186,8 +185,6 @@ public Void visitIdentifier(IdentifierTree node, Void aVoid) { public static String removeUnusedImports(final String contents) throws FormatterException { Context context = new Context(); - // TODO(cushon): this should default to the latest supported source level, same as in Formatter - Options.instance(context).put(Option.SOURCE, "9"); JCCompilationUnit unit = parse(context, contents); if (unit == null) { // error handling is done during formatting From b810032a87f5db936481d7c3b36d8d6fee058d43 Mon Sep 17 00:00:00 2001 From: Andrew Reid Date: Thu, 26 Mar 2020 10:05:58 -0700 Subject: [PATCH 028/379] Preserve tabular arguments for mixed sign numeric lists. Treats unary minus literals (eg -4.0) as their underlying type when checking if all elements in a tabular list are of the same Tree.Kind. Fixes #400, #406 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=303137504 --- .../java/JavaInputAstVisitor.java | 8 +++++++- .../testdata/TabularMixedSignInitializer.input | 17 +++++++++++++++++ .../testdata/TabularMixedSignInitializer.output | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TabularMixedSignInitializer.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TabularMixedSignInitializer.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 8edd68049..6ece007c7 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -3192,7 +3192,13 @@ private static boolean expressionsAreParallel( if (column >= row.size()) { continue; } - nodeTypes.add(row.get(column).getKind()); + // Treat UnaryTree expressions as their underlying type for the comparison (so, for example + // -ve and +ve numeric literals are considered the same). + if (row.get(column) instanceof UnaryTree) { + nodeTypes.add(((UnaryTree) row.get(column)).getExpression().getKind()); + } else { + nodeTypes.add(row.get(column).getKind()); + } } for (Multiset.Entry nodeType : nodeTypes.entrySet()) { if (nodeType.getCount() >= atLeastM) { diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TabularMixedSignInitializer.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TabularMixedSignInitializer.input new file mode 100644 index 000000000..2715158b1 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TabularMixedSignInitializer.input @@ -0,0 +1,17 @@ +public class T { + private static final double[] f = { + 95.0, 75.0, -95.0, 75.0, + -95.0, 75.0, +95.0, 75.0 + }; + + private static final int[] g = { + x++, y, ++z, + x, y, ~z, + --x, ++y, z-- + }; + + private static final bool[] h = { + a, b, c, d, + !e, a, b, c + }; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TabularMixedSignInitializer.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TabularMixedSignInitializer.output new file mode 100644 index 000000000..2715158b1 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TabularMixedSignInitializer.output @@ -0,0 +1,17 @@ +public class T { + private static final double[] f = { + 95.0, 75.0, -95.0, 75.0, + -95.0, 75.0, +95.0, 75.0 + }; + + private static final int[] g = { + x++, y, ++z, + x, y, ~z, + --x, ++y, z-- + }; + + private static final bool[] h = { + a, b, c, d, + !e, a, b, c + }; +} From 4ddb9148c103b9c65768e519884b0c8ad5caaf39 Mon Sep 17 00:00:00 2001 From: cushon Date: Fri, 27 Mar 2020 11:14:18 -0700 Subject: [PATCH 029/379] Add initial support for Java 14 language features ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=303367644 --- .travis.yml | 1 + core/pom.xml | 28 +++ .../googlejavaformat/java/Formatter.java | 37 ++- .../googlejavaformat/java/JavaInput.java | 2 + .../java/JavaInputAstVisitor.java | 78 ++++--- .../java/RemoveUnusedImports.java | 1 + .../googlejavaformat/java/StringWrapper.java | 1 + .../java/java14/Java14InputAstVisitor.java | 219 ++++++++++++++++++ .../googlejavaformat/java/DiagnosticTest.java | 3 +- .../java/FormatterIntegrationTest.java | 24 ++ .../googlejavaformat/java/MainTest.java | 4 +- .../java/testdata/java14.input | 38 +++ .../java/testdata/java14.output | 39 ++++ 13 files changed, 439 insertions(+), 36 deletions(-) create mode 100644 core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output diff --git a/.travis.yml b/.travis.yml index 048e3ed19..b8a7c33af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ notifications: jdk: - openjdk11 + - openjdk14 - openjdk-ea matrix: diff --git a/core/pom.xml b/core/pom.xml index 6ec553fb0..c6f1e664b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -256,4 +256,32 @@ + + + + jdk11 + + (,14) + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + **/Java14InputAstVisitor.java + + + + + maven-javadoc-plugin + + com.google.googlejavaformat.java.java14 + + + + + + diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index 4348506b8..3e973958d 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -14,6 +14,8 @@ package com.google.googlejavaformat.java; +import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_VERSION; +import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.collect.ImmutableList; @@ -40,6 +42,7 @@ import com.sun.tools.javac.util.Options; import java.io.IOError; import java.io.IOException; +import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; import java.util.Collection; @@ -115,6 +118,7 @@ static void format(final JavaInput javaInput, JavaOutput javaOutput, JavaFormatt DiagnosticCollector diagnostics = new DiagnosticCollector<>(); context.put(DiagnosticListener.class, diagnostics); Options.instance(context).put("allowStringFolding", "false"); + Options.instance(context).put("--enable-preview", "true"); JCCompilationUnit unit; JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8); try { @@ -149,7 +153,21 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept } OpsBuilder builder = new OpsBuilder(javaInput, javaOutput); // Output the compilation unit. - new JavaInputAstVisitor(builder, options.indentationMultiplier()).scan(unit, null); + JavaInputAstVisitor visitor; + if (getMajor() >= 14) { + try { + visitor = + Class.forName("com.google.googlejavaformat.java.java14.Java14InputAstVisitor") + .asSubclass(JavaInputAstVisitor.class) + .getConstructor(OpsBuilder.class, int.class) + .newInstance(builder, options.indentationMultiplier()); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } else { + visitor = new JavaInputAstVisitor(builder, options.indentationMultiplier()); + } + visitor.scan(unit, null); builder.sync(javaInput.getText().length()); builder.drain(); Doc doc = new DocBuilder().withOps(builder.build()).build(); @@ -158,6 +176,23 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept javaOutput.flush(); } + // Runtime.Version was added in JDK 9, so use reflection to access it to preserve source + // compatibility with Java 8. + private static int getMajor() { + try { + Method versionMethod = Runtime.class.getMethod("version"); + Object version = versionMethod.invoke(null); + return (int) version.getClass().getMethod("major").invoke(version); + } catch (Exception e) { + // continue below + } + int version = (int) Double.parseDouble(JAVA_CLASS_VERSION.value()); + if (49 <= version && version <= 52) { + return version - (49 - 5); + } + throw new IllegalStateException("Unknown Java version: " + JAVA_SPECIFICATION_VERSION.value()); + } + static boolean errorDiagnostic(Diagnostic input) { if (input.getKind() != Diagnostic.Kind.ERROR) { return false; diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index e5e4f4580..17ae0fac0 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -39,6 +39,7 @@ import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler; +import com.sun.tools.javac.util.Options; import java.io.IOException; import java.net.URI; import java.util.ArrayList; @@ -347,6 +348,7 @@ static ImmutableList buildToks(String text, ImmutableSet stopTok throws FormatterException { stopTokens = ImmutableSet.builder().addAll(stopTokens).add(TokenKind.EOF).build(); Context context = new Context(); + Options.instance(context).put("--enable-preview", "true"); new JavacFileManager(context, true, UTF_8); DiagnosticCollector diagnosticCollector = new DiagnosticCollector<>(); context.put(DiagnosticListener.class, diagnosticCollector); diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 6ece007c7..11b9e3a0c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -134,6 +134,7 @@ import com.sun.source.util.TreePathScanner; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.TreeScanner; import java.util.ArrayDeque; import java.util.ArrayList; @@ -154,10 +155,10 @@ * An AST visitor that builds a stream of {@link Op}s to format from the given {@link * CompilationUnitTree}. */ -public final class JavaInputAstVisitor extends TreePathScanner { +public class JavaInputAstVisitor extends TreePathScanner { /** Direction for Annotations (usually VERTICAL). */ - enum Direction { + protected enum Direction { VERTICAL, HORIZONTAL; @@ -211,7 +212,7 @@ static AllowTrailingBlankLine valueOf(boolean b) { } /** Whether to include braces. */ - enum BracesOrNot { + protected enum BracesOrNot { YES, NO; @@ -259,7 +260,7 @@ boolean isYes() { } /** Whether these declarations are the first in the block. */ - enum FirstDeclarationsOrNot { + protected enum FirstDeclarationsOrNot { YES, NO; @@ -268,14 +269,14 @@ boolean isYes() { } } - private final OpsBuilder builder; + protected final OpsBuilder builder; - private static final Indent.Const ZERO = Indent.Const.ZERO; - private final int indentMultiplier; - private final Indent.Const minusTwo; - private final Indent.Const minusFour; - private final Indent.Const plusTwo; - private final Indent.Const plusFour; + protected static final Indent.Const ZERO = Indent.Const.ZERO; + protected final int indentMultiplier; + protected final Indent.Const minusTwo; + protected final Indent.Const minusFour; + protected final Indent.Const plusTwo; + protected final Indent.Const plusFour; private static final ImmutableList breakList(Optional breakTag) { return ImmutableList.of(Doc.Break.make(Doc.FillMode.UNIFIED, " ", ZERO, breakTag)); @@ -382,7 +383,7 @@ public Void visitCompilationUnit(CompilationUnitTree node, Void unused) { } /** Skips over extra semi-colons at the top-level, or in a class member declaration lists. */ - private void dropEmptyDeclarations() { + protected void dropEmptyDeclarations() { if (builder.peekToken().equals(Optional.of(";"))) { while (builder.peekToken().equals(Optional.of(";"))) { builder.forcedBreak(); @@ -1331,12 +1332,19 @@ public Void visitAnnotatedType(AnnotatedTypeTree node, Void unused) { return null; } + // TODO(cushon): Use Flags.COMPACT_RECORD_CONSTRUCTOR once if/when we drop support for Java 11 + protected static final long COMPACT_RECORD_CONSTRUCTOR = 1L << 51; + @Override public Void visitMethod(MethodTree node, Void unused) { sync(node); List annotations = node.getModifiers().getAnnotations(); List returnTypeAnnotations = ImmutableList.of(); + boolean isRecordConstructor = + (((JCMethodDecl) node).mods.flags & COMPACT_RECORD_CONSTRUCTOR) + == COMPACT_RECORD_CONSTRUCTOR; + if (!node.getTypeParameters().isEmpty() && !annotations.isEmpty()) { int typeParameterStart = getStartPosition(node.getTypeParameters().get(0)); for (int i = 0; i < annotations.size(); i++) { @@ -1406,7 +1414,9 @@ public Void visitMethod(MethodTree node, Void unused) { name = builder.peekToken().get(); } token(name); - token("("); + if (!isRecordConstructor) { + token("("); + } // end of name and type scope builder.close(); } @@ -1416,12 +1426,14 @@ public Void visitMethod(MethodTree node, Void unused) { builder.open(Indent.If.make(breakBeforeType, plusFour, ZERO)); builder.open(ZERO); { - if (!node.getParameters().isEmpty() || node.getReceiverParameter() != null) { - // Break before args. - builder.breakToFill(""); - visitFormals(Optional.ofNullable(node.getReceiverParameter()), node.getParameters()); + if (!isRecordConstructor) { + if (!node.getParameters().isEmpty() || node.getReceiverParameter() != null) { + // Break before args. + builder.breakToFill(""); + visitFormals(Optional.ofNullable(node.getReceiverParameter()), node.getParameters()); + } + token(")"); } - token(")"); if (dims != null) { maybeAddDims(dims); } @@ -1795,17 +1807,22 @@ public Void visitCase(CaseTree node, Void unused) { @Override public Void visitSwitch(SwitchTree node, Void unused) { sync(node); + visitSwitch(node.getExpression(), node.getCases()); + return null; + } + + protected void visitSwitch(ExpressionTree expression, List cases) { token("switch"); builder.space(); token("("); - scan(skipParen(node.getExpression()), null); + scan(skipParen(expression), null); token(")"); builder.space(); tokenBreakTrailingComment("{", plusTwo); builder.blankLineWanted(BlankLineWanted.NO); builder.open(plusTwo); boolean first = true; - for (CaseTree caseTree : node.getCases()) { + for (CaseTree caseTree : cases) { if (!first) { builder.blankLineWanted(BlankLineWanted.PRESERVE); } @@ -1816,7 +1833,6 @@ public Void visitSwitch(SwitchTree node, Void unused) { builder.forcedBreak(); builder.blankLineWanted(BlankLineWanted.NO); token("}", plusFour); - return null; } @Override @@ -2126,7 +2142,7 @@ private void visitStatement( } } - private void visitStatements(List statements) { + protected void visitStatements(List statements) { boolean first = true; PeekingIterator it = Iterators.peekingIterator(statements.iterator()); dropEmptyDeclarations(); @@ -2164,7 +2180,7 @@ public Void visitModifiers(ModifiersTree node, Void unused) { } /** Output combined modifiers and annotations and returns the trailing break. */ - private List visitModifiers( + protected List visitModifiers( ModifiersTree modifiersTree, Direction annotationsDirection, Optional declarationAnnotationBreak) { @@ -2172,7 +2188,7 @@ private List visitModifiers( modifiersTree.getAnnotations(), annotationsDirection, declarationAnnotationBreak); } - private List visitModifiers( + protected List visitModifiers( List annotationTrees, Direction annotationsDirection, Optional declarationAnnotationBreak) { @@ -2339,7 +2355,7 @@ private static void walkInfix( } } - private void visitFormals( + protected void visitFormals( Optional receiver, List parameters) { if (!receiver.isPresent() && parameters.isEmpty()) { return; @@ -2559,7 +2575,7 @@ private void visitToDeclare( } /** Does not omit the leading '<', which should be associated with the type name. */ - private void typeParametersRest( + protected void typeParametersRest( List typeParameters, Indent plusIndent) { builder.open(plusIndent); builder.breakOp(); @@ -3446,7 +3462,7 @@ private void declareMany(List fragments, Direction annotationDirec } /** Add a list of declarations. */ - void addBodyDeclarations( + protected void addBodyDeclarations( List bodyDeclarations, BracesOrNot braces, FirstDeclarationsOrNot first0) { if (bodyDeclarations.isEmpty()) { if (braces.isYes()) { @@ -3592,7 +3608,7 @@ private Direction fieldAnnotationDirection(ModifiersTree modifiers) { * * @param token the {@link String} to wrap in a {@link Doc.Token} */ - final void token(String token) { + protected final void token(String token) { builder.token( token, Doc.Token.RealOrImaginary.REAL, @@ -3606,7 +3622,7 @@ final void token(String token) { * @param token the {@link String} to wrap in a {@link Doc.Token} * @param plusIndentCommentsBefore extra indent for comments before this token */ - final void token(String token, Indent plusIndentCommentsBefore) { + protected final void token(String token, Indent plusIndentCommentsBefore) { builder.token( token, Doc.Token.RealOrImaginary.REAL, @@ -3620,7 +3636,7 @@ final void tokenBreakTrailingComment(String token, Indent breakAndIndentTrailing token, Doc.Token.RealOrImaginary.REAL, ZERO, Optional.of(breakAndIndentTrailingComment)); } - private void markForPartialFormat() { + protected void markForPartialFormat() { if (!inExpression()) { builder.markForPartialFormat(); } @@ -3632,7 +3648,7 @@ private void markForPartialFormat() { * * @param node the ASTNode holding the input position */ - final void sync(Tree node) { + protected final void sync(Tree node) { builder.sync(((JCTree) node).getStartPosition()); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index 9d0bb27d2..d93948082 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -200,6 +200,7 @@ private static JCCompilationUnit parse(Context context, String javaInput) throws FormatterException { DiagnosticCollector diagnostics = new DiagnosticCollector<>(); context.put(DiagnosticListener.class, diagnostics); + Options.instance(context).put("--enable-preview", "true"); Options.instance(context).put("allowStringFolding", "false"); JCCompilationUnit unit; JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8); diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 6bb63db3a..e41bb6663 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -372,6 +372,7 @@ private static JCTree.JCCompilationUnit parse(String source, boolean allowString DiagnosticCollector diagnostics = new DiagnosticCollector<>(); Context context = new Context(); context.put(DiagnosticListener.class, diagnostics); + Options.instance(context).put("--enable-preview", "true"); Options.instance(context).put("allowStringFolding", Boolean.toString(allowStringFolding)); JCTree.JCCompilationUnit unit; JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8); diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java new file mode 100644 index 000000000..f3dee6b67 --- /dev/null +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -0,0 +1,219 @@ +/* + * Copyright 2020 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java.java14; + +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.collect.MoreCollectors.onlyElement; + +import com.google.common.base.Verify; +import com.google.googlejavaformat.Op; +import com.google.googlejavaformat.OpsBuilder; +import com.google.googlejavaformat.java.JavaInputAstVisitor; +import com.sun.source.tree.BindingPatternTree; +import com.sun.source.tree.CaseTree; +import com.sun.source.tree.ClassTree; +import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.InstanceOfTree; +import com.sun.source.tree.MethodTree; +import com.sun.source.tree.SwitchExpressionTree; +import com.sun.source.tree.Tree; +import com.sun.source.tree.YieldTree; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.TreeInfo; +import java.util.List; +import java.util.Optional; + +/** + * Extends {@link JavaInputAstVisitor} with support for AST nodes that were added or modified for + * Java 14. + */ +public class Java14InputAstVisitor extends JavaInputAstVisitor { + + public Java14InputAstVisitor(OpsBuilder builder, int indentMultiplier) { + super(builder, indentMultiplier); + } + + @Override + public Void visitBindingPattern(BindingPatternTree node, Void unused) { + sync(node); + scan(node.getType(), null); + builder.breakOp(" "); + visit(node.getBinding()); + return null; + } + + @Override + public Void visitYield(YieldTree node, Void aVoid) { + sync(node); + return super.visitYield(node, aVoid); + } + + @Override + public Void visitSwitchExpression(SwitchExpressionTree node, Void aVoid) { + sync(node); + visitSwitch(node.getExpression(), node.getCases()); + return null; + } + + @Override + public Void visitClass(ClassTree tree, Void unused) { + switch (tree.getKind()) { + case ANNOTATION_TYPE: + visitAnnotationType(tree); + break; + case CLASS: + case INTERFACE: + visitClassDeclaration(tree); + break; + case ENUM: + visitEnumDeclaration(tree); + break; + case RECORD: + visitRecordDeclaration(tree); + break; + default: + throw new AssertionError(tree.getKind()); + } + return null; + } + + public void visitRecordDeclaration(ClassTree node) { + sync(node); + List breaks = + visitModifiers( + node.getModifiers(), + Direction.VERTICAL, + /* declarationAnnotationBreak= */ Optional.empty()); + Verify.verify(node.getExtendsClause() == null); + boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); + builder.addAll(breaks); + token("record"); + builder.space(); + visit(node.getSimpleName()); + if (!node.getTypeParameters().isEmpty()) { + token("<"); + } + builder.open(plusFour); + { + if (!node.getTypeParameters().isEmpty()) { + typeParametersRest(node.getTypeParameters(), hasSuperInterfaceTypes ? plusFour : ZERO); + } + MethodTree constructor = + node.getMembers().stream() + .filter(JCMethodDecl.class::isInstance) + .map(JCMethodDecl.class::cast) + .filter( + m -> (m.mods.flags & COMPACT_RECORD_CONSTRUCTOR) == COMPACT_RECORD_CONSTRUCTOR) + .collect(onlyElement()); + token("("); + if (!constructor.getParameters().isEmpty() || constructor.getReceiverParameter() != null) { + // Break before args. + builder.breakToFill(""); + } + visitFormals( + Optional.ofNullable(constructor.getReceiverParameter()), constructor.getParameters()); + token(")"); + if (hasSuperInterfaceTypes) { + builder.breakToFill(" "); + builder.open(node.getImplementsClause().size() > 1 ? plusFour : ZERO); + token("implements"); + builder.space(); + boolean first = true; + for (Tree superInterfaceType : node.getImplementsClause()) { + if (!first) { + token(","); + builder.breakOp(" "); + } + scan(superInterfaceType, null); + first = false; + } + builder.close(); + } + } + builder.close(); + if (node.getMembers() == null) { + token(";"); + } else { + List members = + node.getMembers().stream() + .filter(t -> (TreeInfo.flags((JCTree) t) & Flags.GENERATED_MEMBER) == 0) + .collect(toImmutableList()); + addBodyDeclarations(members, BracesOrNot.YES, FirstDeclarationsOrNot.YES); + } + dropEmptyDeclarations(); + } + + @Override + public Void visitInstanceOf(InstanceOfTree node, Void unused) { + sync(node); + builder.open(plusFour); + scan(node.getExpression(), null); + builder.breakOp(" "); + builder.open(ZERO); + token("instanceof"); + builder.breakOp(" "); + if (node.getPattern() != null) { + scan(node.getPattern(), null); + } else { + scan(node.getType(), null); + } + builder.close(); + builder.close(); + return null; + } + + @Override + public Void visitCase(CaseTree node, Void unused) { + sync(node); + markForPartialFormat(); + builder.forcedBreak(); + if (node.getExpressions().isEmpty()) { + token("default", plusTwo); + } else { + token("case", plusTwo); + builder.space(); + boolean first = true; + for (ExpressionTree expression : node.getExpressions()) { + if (!first) { + token(","); + builder.space(); + } + scan(expression, null); + first = false; + } + } + switch (node.getCaseKind()) { + case STATEMENT: + token(":"); + builder.open(plusTwo); + visitStatements(node.getStatements()); + builder.close(); + break; + case RULE: + builder.space(); + token("-"); + token(">"); + builder.space(); + scan(node.getBody(), null); + token(";"); + break; + default: + throw new AssertionError(node.getCaseKind()); + } + return null; + } +} diff --git a/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java b/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java index 58ea959fd..0b81ba6b4 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java @@ -143,8 +143,7 @@ public void oneFileParseErrorReplace() throws Exception { int result = main.format("-i", pathOne.toString(), pathTwo.toString()); assertThat(stdout.toString()).isEmpty(); - assertThat(stderr.toString()) - .contains("One.java:1:14: error: class, interface, or enum expected"); + assertThat(stderr.toString()).contains("One.java:1:14: error: class, interface"); assertThat(result).isEqualTo(1); // don't edit files with parse errors assertThat(Files.readAllLines(pathOne, UTF_8)).containsExactly("class One {}}"); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index bb722f2ea..289ea1baf 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -14,6 +14,8 @@ package com.google.googlejavaformat.java; +import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_VERSION; +import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION; import static com.google.common.io.Files.getFileExtension; import static com.google.common.io.Files.getNameWithoutExtension; import static java.nio.charset.StandardCharsets.UTF_8; @@ -21,6 +23,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableSet; import com.google.common.io.CharStreams; import com.google.common.reflect.ClassPath; import com.google.common.reflect.ClassPath.ResourceInfo; @@ -28,6 +31,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.lang.reflect.Method; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -43,6 +47,8 @@ @RunWith(Parameterized.class) public class FormatterIntegrationTest { + private static final ImmutableSet JAVA14_TESTS = ImmutableSet.of("java14"); + @Parameters(name = "{index}: {0}") public static Iterable data() throws IOException { Path testDataPath = Paths.get("com/google/googlejavaformat/java/testdata"); @@ -80,11 +86,29 @@ public static Iterable data() throws IOException { String input = inputs.get(fileName); assertTrue("unmatched input", outputs.containsKey(fileName)); String expectedOutput = outputs.get(fileName); + if (JAVA14_TESTS.contains(fileName) && getMajor() < 14) { + continue; + } testInputs.add(new Object[] {fileName, input, expectedOutput}); } return testInputs; } + private static int getMajor() { + try { + Method versionMethod = Runtime.class.getMethod("version"); + Object version = versionMethod.invoke(null); + return (int) version.getClass().getMethod("major").invoke(version); + } catch (Exception e) { + // continue below + } + int version = (int) Double.parseDouble(JAVA_CLASS_VERSION.value()); + if (49 <= version && version <= 52) { + return version - (49 - 5); + } + throw new IllegalStateException("Unknown Java version: " + JAVA_SPECIFICATION_VERSION.value()); + } + private final String name; private final String input; private final String expected; diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index 0d559440d..613d3912c 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -294,7 +294,7 @@ public void importRemoveErrorParseError() throws Exception { new PrintWriter(err, true), new ByteArrayInputStream(joiner.join(input).getBytes(UTF_8))); assertThat(main.format("-")).isEqualTo(1); - assertThat(err.toString()).contains(":4:3: error: class, interface, or enum expected"); + assertThat(err.toString()).contains(":4:3: error: class, interface"); } finally { Locale.setDefault(backupLocale); @@ -491,7 +491,7 @@ public void assumeFilename_error() throws Exception { new PrintWriter(err, true), new ByteArrayInputStream(joiner.join(input).getBytes(UTF_8))); assertThat(main.format("--assume-filename=Foo.java", "-")).isEqualTo(1); - assertThat(err.toString()).contains("Foo.java:1:15: error: class, interface, or enum expected"); + assertThat(err.toString()).contains("Foo.java:1:15: error: class, interface"); } @Test diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input new file mode 100644 index 000000000..ce9c1257c --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input @@ -0,0 +1,38 @@ +class Java14 { + void f() { + if (obj instanceof String s) { + } else { + } + } + + record Range(T lo, T hi) implements Comparable> { + + public Range {} + + Range(T lo) { + this(lo, lo); + } + + @Override + public int compareTo(Range other) { + throw new UnsupportedOperationException(); + } + } + + void g() { + var block = """ + hello + text + blocks + """.indent(6); + } + + void h() { + int numLetters = switch (day) { + case MONDAY, FRIDAY, SUNDAY -> 6; + case TUESDAY -> 7; + case THURSDAY, SATURDAY -> 8; + case WEDNESDAY -> 9; + }; + } +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output new file mode 100644 index 000000000..bddf08da7 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output @@ -0,0 +1,39 @@ +class Java14 { + void f() { + if (obj instanceof String s) { + } else { + } + } + + record Range(T lo, T hi) implements Comparable> { + + public Range {} + + Range(T lo) { + this(lo, lo); + } + + @Override + public int compareTo(Range other) { + throw new UnsupportedOperationException(); + } + } + + void g() { + var block = """ + hello + text + blocks + """.indent(6); + } + + void h() { + int numLetters = + switch (day) { + case MONDAY, FRIDAY, SUNDAY -> 6; + case TUESDAY -> 7; + case THURSDAY, SATURDAY -> 8; + case WEDNESDAY -> 9; + }; + } +} From 16b56a33b0019f83c22f5a8969410ded7ca1d2b0 Mon Sep 17 00:00:00 2001 From: cushon Date: Tue, 21 Apr 2020 15:32:49 -0700 Subject: [PATCH 030/379] Make re-parsing of var more robust to support uses of `var` as an identifier, with and without a type, e.g. in `var -> { ... }` and `int var x = 42`; and uses of `var ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=307693554 --- .../google/googlejavaformat/java/JavaInputAstVisitor.java | 4 +++- .../googlejavaformat/java/testdata/B154342628.input | 8 ++++++++ .../googlejavaformat/java/testdata/B154342628.output | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B154342628.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B154342628.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 11b9e3a0c..7370b668c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -3273,7 +3273,9 @@ int declareOne( visitAndBreakModifiers( modifiers.get(), annotationsDirection, Optional.of(verticalAnnotationBreak)); } - boolean isVar = builder.peekToken().get().equals("var"); + boolean isVar = + builder.peekToken().get().equals("var") + && (!name.contentEquals("var") || builder.peekToken(1).get().equals("var")); boolean hasType = type != null || isVar; builder.open(hasType ? plusFour : ZERO); { diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B154342628.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B154342628.input new file mode 100644 index 000000000..dbde8f724 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B154342628.input @@ -0,0 +1,8 @@ +class B154342628 { + void f() { + var var = 42; + return writtenVariables.stream() + .filter(var -> deletedVariableIds.contains(var.getId())) + .collect(toImmutableList()); + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B154342628.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B154342628.output new file mode 100644 index 000000000..dbde8f724 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B154342628.output @@ -0,0 +1,8 @@ +class B154342628 { + void f() { + var var = 42; + return writtenVariables.stream() + .filter(var -> deletedVariableIds.contains(var.getId())) + .collect(toImmutableList()); + } +} From 7ba82f7ccfff06136fe6bb41d7c718a7d2ffcaa9 Mon Sep 17 00:00:00 2001 From: plumpy Date: Mon, 27 Apr 2020 10:24:00 -0700 Subject: [PATCH 031/379] Update the open-source google-java-format plugin for 2020.1. I couldn't find any good way to make this backwards compatible. Oh well. FYI, It looks like in 2020.1, we can probably actually use the ExternalFormatProcessor extension point instead of doing all this hacky nonsense... they added a #format(PsiFile, TextRange) method you can override. But I'll leave that for later because 2020.1 is out now and people are mad. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=308647308 --- idea_plugin/build.gradle | 8 ++-- idea_plugin/resources/META-INF/plugin.xml | 23 +++++----- .../intellij/GoogleJavaFormatInstaller.java | 43 ++++++------------- ...lConfigurationProjectManagerListener.java} | 20 ++++----- 4 files changed, 34 insertions(+), 60 deletions(-) rename idea_plugin/src/com/google/googlejavaformat/intellij/{InitialConfigurationComponent.java => InitialConfigurationProjectManagerListener.java} (77%) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 23691f62a..7b2f389d9 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "0.4.11" + id "org.jetbrains.intellij" version "0.4.18" } repositories { @@ -31,14 +31,14 @@ apply plugin: 'java' intellij { pluginName = "google-java-format" - version = "193.4932.9-EAP-SNAPSHOT" + version = "2020.1" } patchPluginXml { pluginDescription = "Formats source code using the google-java-format tool. This version of " + "the plugin uses version ${googleJavaFormatVersion} of the tool." - version = "${googleJavaFormatVersion}.0.3" - sinceBuild = '173' + version = "${googleJavaFormatVersion}.0.5" + sinceBuild = '201' untilBuild = '' } diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index 8b4bb1f70..d633b4045 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -12,6 +12,10 @@ +
1.7.0.5
+
Added a version for 2020.1+ IDEs.
+
1.7.0.4
+
Marked the plugin as being incompatible with 2020.1+ IDEs.
1.7.0.3
Fixed the plugin on 2019.3 IDEs.
1.7.0.2
@@ -23,19 +27,12 @@ ]]>
- - - - com.google.googlejavaformat.intellij.GoogleJavaFormatInstaller - - - - - - com.google.googlejavaformat.intellij.InitialConfigurationComponent - - - + + + + = 193; + ComponentManagerImpl platformComponentManager = (ComponentManagerImpl) project; + IdeaPluginDescriptor plugin = PluginManagerCore.getPlugin(PluginId.getId("google-java-format")); + checkState(plugin != null, "Couldn't locate our own PluginDescriptor."); + platformComponentManager.registerServiceInstance(CodeStyleManager.class, newManager, plugin); } } diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationComponent.java b/idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java similarity index 77% rename from idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationComponent.java rename to idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java index 39bde1b29..da02310c7 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationComponent.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java @@ -20,32 +20,28 @@ import com.intellij.notification.NotificationDisplayType; import com.intellij.notification.NotificationGroup; import com.intellij.notification.NotificationType; -import com.intellij.openapi.components.ProjectComponent; import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManagerListener; +import org.jetbrains.annotations.NotNull; -final class InitialConfigurationComponent implements ProjectComponent { +final class InitialConfigurationProjectManagerListener implements ProjectManagerListener { private static final String NOTIFICATION_TITLE = "Enable google-java-format"; private static final NotificationGroup NOTIFICATION_GROUP = new NotificationGroup(NOTIFICATION_TITLE, NotificationDisplayType.STICKY_BALLOON, true); - private final Project project; - private final GoogleJavaFormatSettings settings; + @Override + public void projectOpened(@NotNull Project project) { - public InitialConfigurationComponent(Project project, GoogleJavaFormatSettings settings) { - this.project = project; - this.settings = settings; - } + GoogleJavaFormatSettings settings = GoogleJavaFormatSettings.getInstance(project); - @Override - public void projectOpened() { if (settings.isUninitialized()) { settings.setEnabled(false); - displayNewUserNotification(); + displayNewUserNotification(project, settings); } } - private void displayNewUserNotification() { + private void displayNewUserNotification(Project project, GoogleJavaFormatSettings settings) { Notification notification = new Notification( NOTIFICATION_GROUP.getDisplayId(), From ca529a291f766936da8ff70aaa706f4ccf2442b2 Mon Sep 17 00:00:00 2001 From: cushon Date: Mon, 27 Apr 2020 11:13:08 -0700 Subject: [PATCH 032/379] Fix formatting of records without an explicit constructor Fixes https://github.com/google/google-java-format/issues/460 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=308658958 --- .../java/JavaInputAstVisitor.java | 5 ++- .../java/java14/Java14InputAstVisitor.java | 38 +++++++++++++------ .../java/testdata/java14.input | 10 ++++- .../java/testdata/java14.output | 8 ++++ 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 7370b668c..ee211b500 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -1332,9 +1332,12 @@ public Void visitAnnotatedType(AnnotatedTypeTree node, Void unused) { return null; } - // TODO(cushon): Use Flags.COMPACT_RECORD_CONSTRUCTOR once if/when we drop support for Java 11 + // TODO(cushon): Use Flags if/when we drop support for Java 11 + protected static final long COMPACT_RECORD_CONSTRUCTOR = 1L << 51; + protected static final long RECORD = 1L << 61; + @Override public Void visitMethod(MethodTree node, Void unused) { sync(node); diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index f3dee6b67..28a110395 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -15,9 +15,10 @@ package com.google.googlejavaformat.java.java14; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.MoreCollectors.onlyElement; +import static com.google.common.collect.MoreCollectors.toOptional; import com.google.common.base.Verify; +import com.google.common.collect.ImmutableList; import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.java.JavaInputAstVisitor; @@ -26,13 +27,13 @@ import com.sun.source.tree.ClassTree; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.InstanceOfTree; -import com.sun.source.tree.MethodTree; import com.sun.source.tree.SwitchExpressionTree; import com.sun.source.tree.Tree; import com.sun.source.tree.YieldTree; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeInfo; import java.util.List; import java.util.Optional; @@ -112,20 +113,17 @@ public void visitRecordDeclaration(ClassTree node) { if (!node.getTypeParameters().isEmpty()) { typeParametersRest(node.getTypeParameters(), hasSuperInterfaceTypes ? plusFour : ZERO); } - MethodTree constructor = - node.getMembers().stream() - .filter(JCMethodDecl.class::isInstance) - .map(JCMethodDecl.class::cast) - .filter( - m -> (m.mods.flags & COMPACT_RECORD_CONSTRUCTOR) == COMPACT_RECORD_CONSTRUCTOR) - .collect(onlyElement()); + ImmutableList parameters = + compactRecordConstructor(node) + .map(m -> ImmutableList.copyOf(m.getParameters())) + .orElseGet(() -> recordVariables(node)); token("("); - if (!constructor.getParameters().isEmpty() || constructor.getReceiverParameter() != null) { + if (!parameters.isEmpty()) { // Break before args. builder.breakToFill(""); } - visitFormals( - Optional.ofNullable(constructor.getReceiverParameter()), constructor.getParameters()); + // record headers can't declare receiver parameters + visitFormals(/* receiver= */ Optional.empty(), parameters); token(")"); if (hasSuperInterfaceTypes) { builder.breakToFill(" "); @@ -157,6 +155,22 @@ public void visitRecordDeclaration(ClassTree node) { dropEmptyDeclarations(); } + private static Optional compactRecordConstructor(ClassTree node) { + return node.getMembers().stream() + .filter(JCMethodDecl.class::isInstance) + .map(JCMethodDecl.class::cast) + .filter(m -> (m.mods.flags & COMPACT_RECORD_CONSTRUCTOR) == COMPACT_RECORD_CONSTRUCTOR) + .collect(toOptional()); + } + + private static ImmutableList recordVariables(ClassTree node) { + return node.getMembers().stream() + .filter(JCVariableDecl.class::isInstance) + .map(JCVariableDecl.class::cast) + .filter(m -> (m.mods.flags & RECORD) == RECORD) + .collect(toImmutableList()); + } + @Override public Void visitInstanceOf(InstanceOfTree node, Void unused) { sync(node); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input index ce9c1257c..ecbea285b 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input @@ -19,6 +19,14 @@ class Java14 { } } + record Foo(int id) {} + + record Rcv(int id) { + public Rcv(Rcv this, int id) { + this.id = id; + } + } + void g() { var block = """ hello @@ -35,4 +43,4 @@ class Java14 { case WEDNESDAY -> 9; }; } -} \ No newline at end of file +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output index bddf08da7..c8c435bbd 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output @@ -19,6 +19,14 @@ class Java14 { } } + record Foo(int id) {} + + record Rcv(int id) { + public Rcv(Rcv this, int id) { + this.id = id; + } + } + void g() { var block = """ hello From e19b76376e54e3ce2822b74f8f4b9393259dc962 Mon Sep 17 00:00:00 2001 From: cushon Date: Tue, 28 Apr 2020 13:56:11 -0700 Subject: [PATCH 033/379] Support `var` in enhanced for loops Fixes https://github.com/google/google-java-format/issues/463 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=308891540 --- .../googlejavaformat/java/JavaInputAstVisitor.java | 14 +++++++++++--- .../googlejavaformat/java/testdata/java14.input | 4 ++++ .../googlejavaformat/java/testdata/java14.output | 4 ++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index ee211b500..4ff563ec2 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -2561,13 +2561,21 @@ private void visitToDeclare( String equals, Optional trailing) { sync(node); - TypeWithDims extractedDims = DimensionHelpers.extractDims(node.getType(), SortedDims.YES); - Optional typeWithDims = Optional.of(extractedDims); + Optional typeWithDims; + Tree type; + if (node.getType() != null) { + TypeWithDims extractedDims = DimensionHelpers.extractDims(node.getType(), SortedDims.YES); + typeWithDims = Optional.of(extractedDims); + type = extractedDims.node; + } else { + typeWithDims = Optional.empty(); + type = null; + } declareOne( kind, annotationsDirection, Optional.of(node.getModifiers()), - extractedDims.node, + type, node.getName(), "", equals, diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input index ecbea285b..10d45221b 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input @@ -43,4 +43,8 @@ class Java14 { case WEDNESDAY -> 9; }; } + + { + for (var arg : List.of()) {} + } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output index c8c435bbd..9779198b1 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output @@ -44,4 +44,8 @@ class Java14 { case WEDNESDAY -> 9; }; } + + { + for (var arg : List.of()) {} + } } From b53d614c06a583d8c47b03b73ba7892d8403eca1 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Thu, 30 Apr 2020 17:15:04 -0700 Subject: [PATCH 034/379] Minor Javadoc improvement. PiperOrigin-RevId: 309329483 --- .../main/java/com/google/googlejavaformat/java/JavaInput.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 17ae0fac0..999c8fb7f 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -562,7 +562,7 @@ private static boolean isParamComment(Tok tok) { * @param offset the {@code 0}-based offset in characters * @param length the length in characters * @return the {@code 0}-based {@link Range} of tokens - * @throws FormatterException + * @throws FormatterException if offset + length is outside the file */ Range characterRangeToTokenRange(int offset, int length) throws FormatterException { int requiredLength = offset + length; From d1c2aef1869b5d485a7fed9ad8a8b57f814dae19 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Thu, 30 Apr 2020 23:02:14 -0700 Subject: [PATCH 035/379] Fix javadoc syntax Fix javadoc syntax by wrap `<` into an inline code block. ``` [WARNING] ...\google-java-format\core\src\main\java\com\google\googlejavaformat\java\JavaInputAstVisitor.java:2577: warning - invalid usage of tag < ``` Fixes #454 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/454 from sormuras:patch-1 f5583c7cfea178a6475cd39510e366cc6694bb78 PiperOrigin-RevId: 309364827 --- .../com/google/googlejavaformat/java/JavaInputAstVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 4ff563ec2..6ce0f6680 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -2585,7 +2585,7 @@ private void visitToDeclare( typeWithDims); } - /** Does not omit the leading '<', which should be associated with the type name. */ + /** Does not omit the leading {@code "<"}, which should be associated with the type name. */ protected void typeParametersRest( List typeParameters, Indent plusIndent) { builder.open(plusIndent); From c525db0972cc25e71d33d314c61058580cbd89ee Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 1 May 2020 12:46:24 -0700 Subject: [PATCH 036/379] Pre-release javadoc fixes PiperOrigin-RevId: 309456095 --- core/pom.xml | 17 +++++++---------- pom.xml | 3 ++- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index c6f1e664b..88b3cf910 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -84,20 +84,17 @@ UTF-8 UTF-8 - https://docs.oracle.com/en/java/javase/11/docs/api - --add-exports=jdk.compiler/com.sun.tools.javac.file=com.google.googlejavaformat - --add-exports=jdk.compiler/com.sun.tools.javac.main=com.google.googlejavaformat - --add-exports=jdk.compiler/com.sun.tools.javac.parser=com.google.googlejavaformat - --add-exports=jdk.compiler/com.sun.tools.javac.tree=com.google.googlejavaformat - --add-exports=jdk.compiler/com.sun.tools.javac.util=com.google.googlejavaformat - --add-exports=jdk.compiler/com.sun.tools.javac.code=com.google.googlejavaformat - --add-exports=jdk.compiler/com.sun.tools.javac.api=com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED,com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED,com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED,com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED,com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED,com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED,com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,com.google.googlejavaformat diff --git a/pom.xml b/pom.xml index a0952ec9d..2ece22d5e 100644 --- a/pom.xml +++ b/pom.xml @@ -160,7 +160,7 @@ maven-javadoc-plugin - 3.1.1 + 3.2.0 maven-gpg-plugin @@ -226,6 +226,7 @@ org.apache.maven.plugins maven-javadoc-plugin + 3.2.0 none From 0354f029adc8b5828ef06becb94904b2f0985974 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 1 May 2020 13:49:49 -0700 Subject: [PATCH 037/379] Increment versions for 1.8 release PiperOrigin-RevId: 309467646 --- README.md | 6 +++--- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c5fdee230..07325b77d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and run it with: ``` -java -jar /path/to/google-java-format-1.7-all-deps.jar [files...] +java -jar /path/to/google-java-format-1.8-all-deps.jar [files...] ``` The formatter can act on whole files, on limited lines (`--lines`), on specific @@ -94,7 +94,7 @@ configuration. com.google.googlejavaformat google-java-format - 1.7 + 1.8 ``` @@ -102,7 +102,7 @@ configuration. ```groovy dependencies { - compile 'com.google.googlejavaformat:google-java-format:1.7' + compile 'com.google.googlejavaformat:google-java-format:1.8' } ``` diff --git a/core/pom.xml b/core/pom.xml index 88b3cf910..8e394756c 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -22,7 +22,7 @@ com.google.googlejavaformat google-java-format-parent - 1.8-SNAPSHOT + 1.9-SNAPSHOT google-java-format diff --git a/pom.xml b/pom.xml index 2ece22d5e..f0776d3d7 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ com.google.googlejavaformat google-java-format-parent pom - 1.8-SNAPSHOT + 1.9-SNAPSHOT core From f5a9280558d46f2a1bf269eeefa0f53d7ba3ebfe Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 11 May 2020 13:00:03 -0700 Subject: [PATCH 038/379] Fix a crash in expression switches `throws` statements are allows to occur in non-block expression switch cases, which was causing the trailing `;` to be printed twice. Fixes https://github.com/google/google-java-format/issues/477 PiperOrigin-RevId: 310974906 --- .../java/java14/Java14InputAstVisitor.java | 2 +- .../java/FormatterIntegrationTest.java | 2 +- .../googlejavaformat/java/testdata/I477.input | 17 +++++++++++++++++ .../googlejavaformat/java/testdata/I477.output | 17 +++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I477.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I477.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index 28a110395..6585c6f6e 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -223,7 +223,7 @@ public Void visitCase(CaseTree node, Void unused) { token(">"); builder.space(); scan(node.getBody(), null); - token(";"); + builder.guessToken(";"); break; default: throw new AssertionError(node.getCaseKind()); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 289ea1baf..0e0ab9f49 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -47,7 +47,7 @@ @RunWith(Parameterized.class) public class FormatterIntegrationTest { - private static final ImmutableSet JAVA14_TESTS = ImmutableSet.of("java14"); + private static final ImmutableSet JAVA14_TESTS = ImmutableSet.of("java14", "I477"); @Parameters(name = "{index}: {0}") public static Iterable data() throws IOException { diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I477.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I477.input new file mode 100644 index 000000000..ecd8658b3 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I477.input @@ -0,0 +1,17 @@ +class I477 { + public static String foo(int in) { + return switch (in) { + case 1 -> "A"; + case 2 -> "B"; + default -> throw new IllegalStateException("Unknown input " + in); + }; + } + + public static String foo(int in) { + return switch (in) { + case 1 -> "A"; + case 2 -> "B"; + default -> "C"; + }; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I477.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I477.output new file mode 100644 index 000000000..ecd8658b3 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I477.output @@ -0,0 +1,17 @@ +class I477 { + public static String foo(int in) { + return switch (in) { + case 1 -> "A"; + case 2 -> "B"; + default -> throw new IllegalStateException("Unknown input " + in); + }; + } + + public static String foo(int in) { + return switch (in) { + case 1 -> "A"; + case 2 -> "B"; + default -> "C"; + }; + } +} From 98c8525593e206225d92c76dd3f05513be18d699 Mon Sep 17 00:00:00 2001 From: cpovirk Date: Wed, 13 May 2020 09:34:40 -0700 Subject: [PATCH 039/379] Split up the string "M" + "OE:(begin|end)_intracomment_stripping," as the full string will trigger stripping under Copybara. Also, avoid reference to an internal link shortener, as we are making references to it an error. Looking to the future: When we migrate to use proper Copybara stripping directives, we could consider removing support for the old directives. Then the problem would mostly go away. However, we might end up having the same problem with Copybara directives when google-java-format's strings and method names start mentioning *them*. PiperOrigin-RevId: 311344956 --- .../java/javadoc/JavadocLexer.java | 4 +- .../java/JavadocFormattingTest.java | 50 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java index 108d4a7bf..cc707ae7e 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java @@ -507,9 +507,9 @@ private static boolean hasMultipleNewlines(String s) { // Match "@param " specially in case the is a

or other HTML tag we treat specially. private static final Pattern FOOTER_TAG_PATTERN = compile("^@(param\\s+<\\w+>|[a-z]\\w*)"); private static final Pattern MOE_BEGIN_STRIP_COMMENT_PATTERN = - compile("^"); + compile("^"); private static final Pattern MOE_END_STRIP_COMMENT_PATTERN = - compile("^"); + compile("^"); private static final Pattern HTML_COMMENT_PATTERN = fullCommentPattern(); private static final Pattern PRE_OPEN_PATTERN = openTagPattern("pre"); private static final Pattern PRE_CLOSE_PATTERN = closeTagPattern("pre"); diff --git a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java index 411699765..f5103d9b5 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java @@ -115,48 +115,48 @@ public void moeComments() { String[] input = { "/**", " * Deatomizes the given user.", - " * ", - " * See go/deatomizer-v5 for the design doc.", - " * ", + " * ", + " * See deatomizer-v5 for the design doc.", + " * ", " * To reatomize, call {@link reatomize}.", " *", - " * ", + " * ", " *

This method is used in the Google teleporter.", " *", " *

Yes, we have a teleporter.", - " * ", + " * ", " *", " * @param user the person to teleport.", - " * ", - " * Users must sign go/deatomize-waiver ahead of time.", - " * ", - " * ", + " * ", + " * Users must sign deatomize-waiver ahead of time.", + " * ", + " * ", " * @deprecated Sometimes turns the user into a goat.", - " * ", + " * ", " */", "class Test {}", }; String[] expected = { "/**", " * Deatomizes the given user.", - " * ", - " * See go/deatomizer-v5 for the design doc.", - " * ", + " * ", + " * See deatomizer-v5 for the design doc.", + " * ", " * To reatomize, call {@link reatomize}.", " *", - " * ", + " * ", " *

This method is used in the Google teleporter.", " *", " *

Yes, we have a teleporter.", - " * ", + " * ", " *", " * @param user the person to teleport.", - " * ", - " * Users must sign go/deatomize-waiver ahead of time.", - " * ", - " * ", + " * ", + " * Users must sign deatomize-waiver ahead of time.", + " * ", + " * ", " * @deprecated Sometimes turns the user into a goat.", - " * ", + " * ", " */", "class Test {}", }; @@ -169,7 +169,7 @@ public void moeCommentBeginOnlyInMiddleOfDoc() { String[] input = { "/**", // " * Foo.", - " * ", + " * ", " * Bar.", " */", "class Test {}", @@ -177,7 +177,7 @@ public void moeCommentBeginOnlyInMiddleOfDoc() { String[] expected = { "/**", // " * Foo.", - " * ", + " * ", " * Bar.", " */", "class Test {}", @@ -192,7 +192,7 @@ public void moeCommentBeginOnlyAtEndOfDoc() { String[] input = { "/**", // " * Foo.", - " * ", + " * ", " */", "class Test {}", }; @@ -209,14 +209,14 @@ public void moeCommentEndOnly() { String[] input = { "/**", // " * Foo.", - " * ", + " * ", " */", "class Test {}", }; String[] expected = { "/**", // " * Foo.", - " * ", + " * ", " */", "class Test {}", }; From 2ddcfd392cc5e45eaa5fb30c723b7e024f5caabb Mon Sep 17 00:00:00 2001 From: Avi Mimoun <36456709+av1m@users.noreply.github.com> Date: Tue, 26 May 2020 19:24:57 -0700 Subject: [PATCH 040/379] Addition of a third party: Github Actions - Add the possibility of formatting your code from Github directly (taking all the events of Github Actions) - Addition of the word "old" for the eclipse plugin, since it is 1.6 release Fixes #487 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/487 from av1m:master 351b737be5580c2f3320605668c218882624a3fc PiperOrigin-RevId: 313312689 --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 07325b77d..c12ca348e 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ and import it into File→Settings→Editor→Code Style. ### Eclipse -A +Version 1.6 of the [google-java-format Eclipse plugin](https://github.com/google/google-java-format/releases/download/google-java-format-1.6/google-java-format-eclipse-plugin_1.6.0.jar) can be downloaded from the releases page. Drop it into the Eclipse [drop-ins folder](http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fp2_dropins_format.html) @@ -81,6 +81,9 @@ Implementation`. * [maltzj/google-style-precommit-hook](https://github.com/maltzj/google-style-precommit-hook): A pre-commit (pre-commit.com) hook that will automatically run GJF whenever you commit code to your repository +* [Github Actions](https://github.com/features/actions) + * [googlejavaformat-action](https://github.com/axel-op/googlejavaformat-action): + Automatically format your Java files when you push on github ### as a library From 22d8c55fb4699cf08e4c9728dc6ccc9360becd5a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 3 Jun 2020 11:14:53 -0700 Subject: [PATCH 041/379] Java 14 integration tests PiperOrigin-RevId: 314566781 --- .../java/FormatterIntegrationTest.java | 3 +- .../java/testdata/ExpressionSwitch.input | 9 ++++ .../java/testdata/ExpressionSwitch.output | 9 ++++ .../googlejavaformat/java/testdata/RSLs.input | 6 +++ .../java/testdata/RSLs.output | 6 +++ .../java/testdata/Records.input | 29 +++++++++++ .../java/testdata/Records.output | 29 +++++++++++ .../googlejavaformat/java/testdata/Var.input | 5 ++ .../googlejavaformat/java/testdata/Var.output | 5 ++ .../java/testdata/java14.input | 50 ------------------ .../java/testdata/java14.output | 51 ------------------- 11 files changed, 100 insertions(+), 102 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/Records.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/Records.output create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/Var.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/Var.output delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 0e0ab9f49..44ba63925 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -47,7 +47,8 @@ @RunWith(Parameterized.class) public class FormatterIntegrationTest { - private static final ImmutableSet JAVA14_TESTS = ImmutableSet.of("java14", "I477"); + private static final ImmutableSet JAVA14_TESTS = + ImmutableSet.of("I477", "Records", "RSLs", "Var", "ExpressionSwitch"); @Parameters(name = "{index}: {0}") public static Iterable data() throws IOException { diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input new file mode 100644 index 000000000..381d5d17d --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input @@ -0,0 +1,9 @@ +class ExpressionSwitch { + boolean odd(int x) { + return switch (x) { + case 0 -> true; + case 1 -> false; + default -> odd(x - 1); + }; + } +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output new file mode 100644 index 000000000..38eca1b2d --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output @@ -0,0 +1,9 @@ +class ExpressionSwitch { + boolean odd(int x) { + return switch (x) { + case 0 -> true; + case 1 -> false; + default -> odd(x - 1); + }; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input new file mode 100644 index 000000000..9c18f0def --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input @@ -0,0 +1,6 @@ +class RSLs { + String s = """ + lorem + ipsum + """; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output new file mode 100644 index 000000000..9c18f0def --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output @@ -0,0 +1,6 @@ +class RSLs { + String s = """ + lorem + ipsum + """; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Records.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Records.input new file mode 100644 index 000000000..03a3c06b0 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Records.input @@ -0,0 +1,29 @@ +class Records { + record R1() {} + + private record R2() {} + + @Deprecated + private record R3() {} + + record R4() {} + + record R5(int x) {} + + record R6(@Deprecated int x) {} + + record R7(@Deprecated int x, int... y) {} + + record R8() implements Comparable> { + @Override + public int compareTo(R8 other) { + return 0; + } + } + + record R9(int x) { + R9(int x) { + this.x = x; + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Records.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Records.output new file mode 100644 index 000000000..03a3c06b0 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Records.output @@ -0,0 +1,29 @@ +class Records { + record R1() {} + + private record R2() {} + + @Deprecated + private record R3() {} + + record R4() {} + + record R5(int x) {} + + record R6(@Deprecated int x) {} + + record R7(@Deprecated int x, int... y) {} + + record R8() implements Comparable> { + @Override + public int compareTo(R8 other) { + return 0; + } + } + + record R9(int x) { + R9(int x) { + this.x = x; + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Var.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Var.input new file mode 100644 index 000000000..2633632d6 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Var.input @@ -0,0 +1,5 @@ +class Var { + void f() { + for (var x : ImmutableList.of(42)) {} + } +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Var.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Var.output new file mode 100644 index 000000000..95d436ab5 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Var.output @@ -0,0 +1,5 @@ +class Var { + void f() { + for (var x : ImmutableList.of(42)) {} + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input deleted file mode 100644 index 10d45221b..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.input +++ /dev/null @@ -1,50 +0,0 @@ -class Java14 { - void f() { - if (obj instanceof String s) { - } else { - } - } - - record Range(T lo, T hi) implements Comparable> { - - public Range {} - - Range(T lo) { - this(lo, lo); - } - - @Override - public int compareTo(Range other) { - throw new UnsupportedOperationException(); - } - } - - record Foo(int id) {} - - record Rcv(int id) { - public Rcv(Rcv this, int id) { - this.id = id; - } - } - - void g() { - var block = """ - hello - text - blocks - """.indent(6); - } - - void h() { - int numLetters = switch (day) { - case MONDAY, FRIDAY, SUNDAY -> 6; - case TUESDAY -> 7; - case THURSDAY, SATURDAY -> 8; - case WEDNESDAY -> 9; - }; - } - - { - for (var arg : List.of()) {} - } -} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output deleted file mode 100644 index 9779198b1..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/java14.output +++ /dev/null @@ -1,51 +0,0 @@ -class Java14 { - void f() { - if (obj instanceof String s) { - } else { - } - } - - record Range(T lo, T hi) implements Comparable> { - - public Range {} - - Range(T lo) { - this(lo, lo); - } - - @Override - public int compareTo(Range other) { - throw new UnsupportedOperationException(); - } - } - - record Foo(int id) {} - - record Rcv(int id) { - public Rcv(Rcv this, int id) { - this.id = id; - } - } - - void g() { - var block = """ - hello - text - blocks - """.indent(6); - } - - void h() { - int numLetters = - switch (day) { - case MONDAY, FRIDAY, SUNDAY -> 6; - case TUESDAY -> 7; - case THURSDAY, SATURDAY -> 8; - case WEDNESDAY -> 9; - }; - } - - { - for (var arg : List.of()) {} - } -} From 5202af98006d744aafc2ba7cba2fa19a14e9b7b1 Mon Sep 17 00:00:00 2001 From: Tim Koopman Date: Wed, 3 Jun 2020 17:07:38 -0700 Subject: [PATCH 042/379] Add support for yield statement Implement visitYield. Fixes #489 from ntkoopman:yield b46d1f0f2526044676e7ed5cca07a6f745772c0d COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/489 PiperOrigin-RevId: 314633394 --- .../java/java14/Java14InputAstVisitor.java | 6 ++++- .../java/testdata/ExpressionSwitch.input | 21 +++++++++++++++- .../java/testdata/ExpressionSwitch.output | 25 +++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index 6585c6f6e..78cfd66b1 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -60,7 +60,11 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { @Override public Void visitYield(YieldTree node, Void aVoid) { sync(node); - return super.visitYield(node, aVoid); + token("yield"); + builder.space(); + scan(node.getValue(), null); + token(";"); + return null; } @Override diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input index 381d5d17d..1e4db164d 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input @@ -6,4 +6,23 @@ class ExpressionSwitch { default -> odd(x - 1); }; } -} \ No newline at end of file + + { + int f = switch (i) { + case 0 -> 0; + default -> { + yield n / i; + } + }; + + int g = switch (i) { + case 0: yield 0; + default: yield n/i; + }; + + switch (i) { + case 0 -> { System.out.println("0"); } + default -> System.out.println("default"); + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output index 38eca1b2d..6458aa09d 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output @@ -6,4 +6,29 @@ class ExpressionSwitch { default -> odd(x - 1); }; } + + { + int f = + switch (i) { + case 0 -> 0; + default -> { + yield n / i; + } + }; + + int g = + switch (i) { + case 0: + yield 0; + default: + yield n / i; + }; + + switch (i) { + case 0 -> { + System.out.println("0"); + } + default -> System.out.println("default"); + } + } } From 1e4f14f65703e9771dcdc8db90a7d27597559164 Mon Sep 17 00:00:00 2001 From: "taesu82.lee" <66580975+taesu82@users.noreply.github.com> Date: Tue, 9 Jun 2020 14:28:27 -0700 Subject: [PATCH 043/379] Support --skip-removing-unused-imports in google-java-format-diff.py Fixes #495 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/495 from taesu82:patch-1 91e32d443cf8159a72f05a38146dd9b5d4bf550c PiperOrigin-RevId: 315560436 --- scripts/google-java-format-diff.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/google-java-format-diff.py b/scripts/google-java-format-diff.py index 4c6724b90..1abd037d3 100755 --- a/scripts/google-java-format-diff.py +++ b/scripts/google-java-format-diff.py @@ -57,6 +57,8 @@ def main(): help='use AOSP style instead of Google Style (4-space indentation)') parser.add_argument('--skip-sorting-imports', action='store_true', help='do not fix the import order') + parser.add_argument('--skip-removing-unused-imports', action='store_true', + help='do not remove ununsed imports') parser.add_argument('-b', '--binary', help='path to google-java-format binary') parser.add_argument('--google-java-format-jar', metavar='ABSOLUTE_PATH', default=None, help='use a custom google-java-format jar') @@ -112,6 +114,8 @@ def main(): command.append('--aosp') if args.skip_sorting_imports: command.append('--skip-sorting-imports') + if args.skip_removing_unused_imports: + command.append('--skip-removing-unused-imports') command.extend(lines) command.append(filename) p = subprocess.Popen(command, stdout=subprocess.PIPE, From c2c8a517c92fbf3553e53524057cd2ad8ae62962 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Fri, 26 Jun 2020 10:20:09 -0700 Subject: [PATCH 044/379] Update the IDEA plugin to use google-java-format 1.8. PiperOrigin-RevId: 318495968 --- idea_plugin/build.gradle | 6 +++--- idea_plugin/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 7b2f389d9..f7b54f18b 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "0.4.18" + id "org.jetbrains.intellij" version "0.4.21" } repositories { @@ -23,7 +23,7 @@ repositories { } ext { - googleJavaFormatVersion = '1.7' + googleJavaFormatVersion = '1.8' } apply plugin: 'org.jetbrains.intellij' @@ -37,7 +37,7 @@ intellij { patchPluginXml { pluginDescription = "Formats source code using the google-java-format tool. This version of " + "the plugin uses version ${googleJavaFormatVersion} of the tool." - version = "${googleJavaFormatVersion}.0.5" + version = "${googleJavaFormatVersion}.0.0" sinceBuild = '201' untilBuild = '' } diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index d633b4045..cb7d716c7 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -12,6 +12,8 @@ +

1.8.0.0
+
Updated to use google-java-format 1.8.
1.7.0.5
Added a version for 2020.1+ IDEs.
1.7.0.4
From 02a072f296802e4ca771ce4b6ad97b62af665573 Mon Sep 17 00:00:00 2001 From: Eddie Aftandilian Date: Fri, 10 Jul 2020 23:21:35 -0700 Subject: [PATCH 045/379] Add missing license headers. PiperOrigin-RevId: 320733285 --- eclipse_plugin/plugin.xml | 16 ++++++++++++++++ idea_plugin/resources/META-INF/plugin.xml | 16 ++++++++++++++++ scripts/mvn-deploy.sh | 15 +++++++++++++++ util/publish-snapshot-on-commit.sh | 14 ++++++++++++++ util/settings.xml | 16 ++++++++++++++++ 5 files changed, 77 insertions(+) diff --git a/eclipse_plugin/plugin.xml b/eclipse_plugin/plugin.xml index 5d0bbf92b..b832a1e21 100644 --- a/eclipse_plugin/plugin.xml +++ b/eclipse_plugin/plugin.xml @@ -1,3 +1,19 @@ + + diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index cb7d716c7..938a02f53 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -1,3 +1,19 @@ + + google-java-format google-java-format diff --git a/scripts/mvn-deploy.sh b/scripts/mvn-deploy.sh index f6db09338..0133e3612 100755 --- a/scripts/mvn-deploy.sh +++ b/scripts/mvn-deploy.sh @@ -1,4 +1,19 @@ #!/bin/bash + +# Copyright 2020 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + if [ $# -lt 1 ]; then echo "usage $0 [ ...]" exit 1; diff --git a/util/publish-snapshot-on-commit.sh b/util/publish-snapshot-on-commit.sh index 6da8da446..c14368da1 100755 --- a/util/publish-snapshot-on-commit.sh +++ b/util/publish-snapshot-on-commit.sh @@ -1,3 +1,17 @@ +# Copyright 2020 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # https://github.com/google/dagger/blob/master/util/publish-snapshot-on-commit.sh if [ "$TRAVIS_REPO_SLUG" == "google/google-java-format" ] && \ diff --git a/util/settings.xml b/util/settings.xml index 91f444b22..aea3d4ef7 100644 --- a/util/settings.xml +++ b/util/settings.xml @@ -1,3 +1,19 @@ + + From 1715884a46b0953b0491039b668fdc23bb2e7788 Mon Sep 17 00:00:00 2001 From: Eddie Aftandilian Date: Fri, 10 Jul 2020 23:38:23 -0700 Subject: [PATCH 046/379] Disable Appveyor builds on branches. Our account for Appveyor allows only 1 concurrent build. Our current Appveyor config builds every commit to a PR twice -- once as the PR and once as the branch. This CL updates our Appveyor config to disable builds on branches, so we get only one build per PR commit. PiperOrigin-RevId: 320734870 --- appveyor.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 3522155d1..ac535c9a6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,10 @@ +# Don't build branches that are not PRs, to avoid double builds. +branches: + only: + - master + os: Visual Studio 2015 + install: - ps: | Add-Type -AssemblyName System.IO.Compression.FileSystem From 45fb41a7bac3dfe0726601ceb87d1c17bbf494ec Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Mon, 13 Jul 2020 06:41:23 -0700 Subject: [PATCH 047/379] Fix the google-java-format IDEA plugin for 2020.2 IDEs. PiperOrigin-RevId: 320945302 --- idea_plugin/build.gradle | 4 ++-- idea_plugin/resources/META-INF/plugin.xml | 2 ++ .../googlejavaformat/intellij/CodeStyleManagerDecorator.java | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index f7b54f18b..d74957d66 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -31,13 +31,13 @@ apply plugin: 'java' intellij { pluginName = "google-java-format" - version = "2020.1" + version = "202.6250.13-EAP-SNAPSHOT" } patchPluginXml { pluginDescription = "Formats source code using the google-java-format tool. This version of " + "the plugin uses version ${googleJavaFormatVersion} of the tool." - version = "${googleJavaFormatVersion}.0.0" + version = "${googleJavaFormatVersion}.0.1" sinceBuild = '201' untilBuild = '' } diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index 938a02f53..5b313cf62 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -28,6 +28,8 @@ +
1.8.0.1
+
Fixed support for 2020.2 IDEs.
1.8.0.0
Updated to use google-java-format 1.8.
1.7.0.5
diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java index ee28e1bc8..c70ba1751 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java @@ -231,4 +231,9 @@ public int adjustLineIndent(final Document document, final int offset, Formattin } return offset; } + + @Override + public void scheduleReformatWhenSettingsComputed(PsiFile file) { + delegate.scheduleReformatWhenSettingsComputed(file); + } } From 062e5d2e150abee4de6640b25db963e5de4d4f13 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 23 Jul 2020 11:48:48 -0700 Subject: [PATCH 048/379] Update links to Spotless' new documentation layout Also included the Spotless maven plugin (2+ years old, but not well marketed) Fixes #509 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/509 from nedtwigg:patch-2 546c758cc5be91141118cc1b9c560b082ea191cd PiperOrigin-RevId: 322832707 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c12ca348e..9ce399838 100644 --- a/README.md +++ b/README.md @@ -68,9 +68,10 @@ Implementation`. ### Third-party integrations * Gradle plugins - * [Spotless](https://github.com/diffplug/spotless/tree/master/plugin-gradle#applying-to-java-source-google-java-format): + * [spotless](https://github.com/diffplug/spotless/tree/main/plugin-gradle#google-java-format) * [sherter/google-java-format-gradle-plugin](https://github.com/sherter/google-java-format-gradle-plugin) * Apache Maven plugins + * [spotless](https://github.com/diffplug/spotless/tree/main/plugin-maven#google-java-format) * [coveo/fmt-maven-plugin](https://github.com/coveo/fmt-maven-plugin) * [talios/googleformatter-maven-plugin](https://github.com/talios/googleformatter-maven-plugin) * [Cosium/maven-git-code-format](https://github.com/Cosium/maven-git-code-format): From 1c45fa55b1a483314f8cb52bd0a0b21838c2bc32 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 24 Aug 2020 10:04:28 -0700 Subject: [PATCH 049/379] Bump versions to 1.9 PiperOrigin-RevId: 328160170 --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 8e394756c..e5eab9cc0 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -22,7 +22,7 @@ com.google.googlejavaformat google-java-format-parent - 1.9-SNAPSHOT + 1.9 google-java-format diff --git a/pom.xml b/pom.xml index f0776d3d7..35bba263b 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ com.google.googlejavaformat google-java-format-parent pom - 1.9-SNAPSHOT + 1.9 core From 1614b6a348a82dcb78bbe9f68c2eb4ede9330c32 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 24 Aug 2020 14:52:24 -0700 Subject: [PATCH 050/379] Increment versions after 1.10 release PiperOrigin-RevId: 328214914 --- README.md | 6 +++--- core/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9ce399838..6f7d5c654 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and run it with: ``` -java -jar /path/to/google-java-format-1.8-all-deps.jar [files...] +java -jar /path/to/google-java-format-1.9-all-deps.jar [files...] ``` The formatter can act on whole files, on limited lines (`--lines`), on specific @@ -98,7 +98,7 @@ configuration. com.google.googlejavaformat google-java-format - 1.8 + 1.9 ``` @@ -106,7 +106,7 @@ configuration. ```groovy dependencies { - compile 'com.google.googlejavaformat:google-java-format:1.8' + compile 'com.google.googlejavaformat:google-java-format:1.9' } ``` diff --git a/core/pom.xml b/core/pom.xml index e5eab9cc0..e2d015316 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -22,7 +22,7 @@ com.google.googlejavaformat google-java-format-parent - 1.9 + 1.10-SNAPSHOT google-java-format diff --git a/pom.xml b/pom.xml index 35bba263b..a8cb645fb 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ com.google.googlejavaformat google-java-format-parent pom - 1.9 + 1.10-SNAPSHOT core From 6bde01e0880586518efad4cc5fd5a00916f41bb5 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 15 Sep 2020 12:38:43 -0700 Subject: [PATCH 051/379] Bump checker-qual from 2.0.0 to 3.6.1 Fixes #519 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/519 from mernst:checker-qual-361 ca54cb9c65d4b1aeffdef3ddbd81f9948ed40bb8 PiperOrigin-RevId: 331830590 --- .../com/google/googlejavaformat/java/JavaInputAstVisitor.java | 4 ++-- .../java/com/google/googlejavaformat/java/JavaOutput.java | 2 +- .../com/google/googlejavaformat/java/testdata/A.input | 4 ++-- .../com/google/googlejavaformat/java/testdata/A.output | 4 ++-- .../com/google/googlejavaformat/java/testdata/B20844369.input | 2 +- .../google/googlejavaformat/java/testdata/B20844369.output | 2 +- .../com/google/googlejavaformat/java/testdata/C.input | 2 +- .../com/google/googlejavaformat/java/testdata/C.output | 2 +- .../com/google/googlejavaformat/java/testdata/D.input | 2 +- .../com/google/googlejavaformat/java/testdata/D.output | 2 +- .../com/google/googlejavaformat/java/testdata/E.input | 2 +- .../com/google/googlejavaformat/java/testdata/E.output | 2 +- .../com/google/googlejavaformat/java/testdata/L.input | 2 +- .../com/google/googlejavaformat/java/testdata/L.output | 2 +- .../com/google/googlejavaformat/java/testdata/S.input | 2 +- .../com/google/googlejavaformat/java/testdata/S.output | 2 +- .../com/google/googlejavaformat/java/testdata/T.input | 2 +- .../com/google/googlejavaformat/java/testdata/T.output | 2 +- pom.xml | 2 +- 19 files changed, 22 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 6ce0f6680..672d8b74b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -2366,7 +2366,7 @@ protected void visitFormals( builder.open(ZERO); boolean first = true; if (receiver.isPresent()) { - // TODO(jdd): Use builders. + // TODO(user): Use builders. declareOne( DeclarationKind.PARAMETER, Direction.HORIZONTAL, @@ -2906,7 +2906,7 @@ private void dotExpressionUpToArgs(ExpressionTree expression, Optional if (!methodInvocation.getTypeArguments().isEmpty()) { builder.open(plusFour); addTypeArguments(methodInvocation.getTypeArguments(), ZERO); - // TODO(jdd): Should indent the name -4. + // TODO(user): Should indent the name -4. builder.breakOp(Doc.FillMode.UNIFIED, "", ZERO, tyargTag); builder.close(); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java index c059318e8..9564a225a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java @@ -89,7 +89,7 @@ public void markForPartialFormat(Token start, Token end) { partialFormatRanges.add(Range.closed(lo, hi)); } - // TODO(jdd): Add invariant. + // TODO(user): Add invariant. @Override public void append(String text, Range range) { if (!range.isEmpty()) { diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/A.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/A.input index 81d13aa1d..c6586300e 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/A.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/A.input @@ -17,13 +17,13 @@ class A { @X(x = 1) private @interface Y {} - // TODO(jdd): Add annotation declaration with empty body. + // TODO(user): Add annotation declaration with empty body. @X(x = 1) @Y protected @interface Z {} - // TODO(jdd): Include type annotations once we can include a higher language level. + // TODO(user): Include type annotations once we can include a higher language level. int[] array1 = new int[5]; int[] array2 = diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/A.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/A.output index 3eff456df..5d5d88f01 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/A.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/A.output @@ -17,13 +17,13 @@ class A { @X(x = 1) private @interface Y {} - // TODO(jdd): Add annotation declaration with empty body. + // TODO(user): Add annotation declaration with empty body. @X(x = 1) @Y protected @interface Z {} - // TODO(jdd): Include type annotations once we can include a higher language level. + // TODO(user): Include type annotations once we can include a higher language level. int[] array1 = new int[5]; int[] array2 = diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.input index 86e46d50e..7317f17b9 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.input @@ -1,6 +1,6 @@ public class B20844369 { private static final String ID_PATTERN = - // TODO(daw): add min/max lengths for the numbers here, e.g. android ID + // TODO(user): add min/max lengths for the numbers here, e.g. android ID "(?:(?\\d+)\\+)?" // optional Android ID + "(?\\d+)" // type + ":" diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.output index 982dc2b5d..62f9721b6 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.output @@ -1,6 +1,6 @@ public class B20844369 { private static final String ID_PATTERN = - // TODO(daw): add min/max lengths for the numbers here, e.g. android ID + // TODO(user): add min/max lengths for the numbers here, e.g. android ID "(?:(?\\d+)\\+)?" // optional Android ID + "(?\\d+)" // type + ":" diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/C.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/C.input index 7baed6cfe..31bf3b8f4 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/C.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/C.input @@ -6,7 +6,7 @@ package com.google.googlejavaformat.java.test; * CreationReferences. */ class C { - // TODO(jdd): Test higher-language-level constructs. + // TODO(user): Test higher-language-level constructs. C() { this( diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/C.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/C.output index fcf773ec0..c62c7ae29 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/C.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/C.output @@ -6,7 +6,7 @@ package com.google.googlejavaformat.java.test; * CreationReferences. */ class C { - // TODO(jdd): Test higher-language-level constructs. + // TODO(user): Test higher-language-level constructs. C() { this( diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/D.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/D.input index daca973b6..d69ed1e14 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/D.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/D.input @@ -2,7 +2,7 @@ package com.google.googlejavaformat.java.test; /** Tests for Dimensions and DoStatements. */ class D { - // TODO(jdd): Test higher-language-level features. + // TODO(user): Test higher-language-level features. int[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [][][][] diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/D.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/D.output index daca973b6..d69ed1e14 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/D.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/D.output @@ -2,7 +2,7 @@ package com.google.googlejavaformat.java.test; /** Tests for Dimensions and DoStatements. */ class D { - // TODO(jdd): Test higher-language-level features. + // TODO(user): Test higher-language-level features. int[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][] [][][][] diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/E.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/E.input index 0e98139a6..479466ace 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/E.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/E.input @@ -9,7 +9,7 @@ import com.google.common.collect.Lists; */ @MarkerAnnotation class E { - // TODO(jdd): Test higher language-level features. + // TODO(user): Test higher language-level features. enum Enum1 { A, B, C, D; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/E.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/E.output index 4dd603a39..fb4f2fae5 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/E.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/E.output @@ -9,7 +9,7 @@ import com.google.common.collect.Lists; */ @MarkerAnnotation class E { - // TODO(jdd): Test higher language-level features. + // TODO(user): Test higher language-level features. enum Enum1 { A, diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/L.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/L.input index f0b3e6681..eda543d0c 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/L.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/L.input @@ -2,7 +2,7 @@ package com.google.googlejavaformat.java.test; /** Tests for LabeledStatements and LambdaExpressions. */ class L { - // TODO(jdd): Include high language-level tests. + // TODO(user): Include high language-level tests. void f() { LABEL: diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/L.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/L.output index f0b3e6681..eda543d0c 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/L.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/L.output @@ -2,7 +2,7 @@ package com.google.googlejavaformat.java.test; /** Tests for LabeledStatements and LambdaExpressions. */ class L { - // TODO(jdd): Include high language-level tests. + // TODO(user): Include high language-level tests. void f() { LABEL: diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/S.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/S.input index a1e07d1c8..15fc1b2c0 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/S.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/S.input @@ -7,7 +7,7 @@ package com.google.googlejavaformat.java.test; * SynchronizedStatements. */ class S { - // TODO(jdd): Add tests for higher language levels. + // TODO(user): Add tests for higher language levels. int x = 0; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/S.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/S.output index a1e07d1c8..15fc1b2c0 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/S.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/S.output @@ -7,7 +7,7 @@ package com.google.googlejavaformat.java.test; * SynchronizedStatements. */ class S { - // TODO(jdd): Add tests for higher language levels. + // TODO(user): Add tests for higher language levels. int x = 0; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/T.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/T.input index c8cd29316..fc9bc0978 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/T.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/T.input @@ -5,7 +5,7 @@ package com.google.googlejavaformat.java.test; * TypeDeclarations, TypeLiterals, TypeMethodReferences, TypeParameters, and Types. */ class T { - // TODO(jdd): Add tests for higher language levels. + // TODO(user): Add tests for higher language levels. T f(int x) throws Exception { class TT {} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/T.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/T.output index c8cd29316..fc9bc0978 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/T.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/T.output @@ -5,7 +5,7 @@ package com.google.googlejavaformat.java.test; * TypeDeclarations, TypeLiterals, TypeMethodReferences, TypeParameters, and Types. */ class T { - // TODO(jdd): Add tests for higher language levels. + // TODO(user): Add tests for higher language levels. T f(int x) throws Exception { class TT {} diff --git a/pom.xml b/pom.xml index a8cb645fb..0b2000415 100644 --- a/pom.xml +++ b/pom.xml @@ -97,7 +97,7 @@ 1.8 28.1-jre 1.0 - 2.0.0 + 3.6.1 From f77e9270b187c4a013e4826dff6bba1c33363347 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Thu, 17 Sep 2020 15:01:02 -0700 Subject: [PATCH 052/379] Update the IntelliJ plugin to google-java-format 1.9. PiperOrigin-RevId: 332323928 --- idea_plugin/build.gradle | 8 ++++---- idea_plugin/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index d74957d66..6ec1c210d 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "0.4.21" + id "org.jetbrains.intellij" version "0.4.22" } repositories { @@ -23,7 +23,7 @@ repositories { } ext { - googleJavaFormatVersion = '1.8' + googleJavaFormatVersion = '1.9' } apply plugin: 'org.jetbrains.intellij' @@ -31,13 +31,13 @@ apply plugin: 'java' intellij { pluginName = "google-java-format" - version = "202.6250.13-EAP-SNAPSHOT" + version = "2020.2.2" } patchPluginXml { pluginDescription = "Formats source code using the google-java-format tool. This version of " + "the plugin uses version ${googleJavaFormatVersion} of the tool." - version = "${googleJavaFormatVersion}.0.1" + version = "${googleJavaFormatVersion}.0.0" sinceBuild = '201' untilBuild = '' } diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index 5b313cf62..5996dba68 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -28,6 +28,8 @@ +
1.9.0.0
+
Updated to use google-java-format 1.9.
1.8.0.1
Fixed support for 2020.2 IDEs.
1.8.0.0
From ea4828aaa4498949f179b9bf87fd5a4b8afe31dd Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 13 Oct 2020 15:20:33 -0700 Subject: [PATCH 053/379] Upgrade junit dependency to 4.13.1 PiperOrigin-RevId: 336966883 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0b2000415..82b0a3ba2 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ junit junit - 4.12 + 4.13.1 test From b769e812a052d7cff4a2d86eff4981a5d358ee2d Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 14 Oct 2020 16:03:01 -0700 Subject: [PATCH 054/379] Tolerate extra semi-colons in import lists even if they're own their own line (which g-j-f does if it runs with import cleanup disabled). PiperOrigin-RevId: 337192414 --- .../googlejavaformat/java/ImportOrderer.java | 4 ++++ .../java/ImportOrdererTest.java | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java b/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java index a82715e0a..dcbaea172 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java @@ -346,6 +346,10 @@ private ImportsAndIndex scanImports(int i) throws FormatterException { i++; } } + while (tokenAt(i).equals(";")) { + // Extra semicolons are not allowed by the JLS but are accepted by javac. + i++; + } imports.add(new Import(importedName, trailing.toString(), isStatic)); // Remember the position just after the import we just saw, before skipping blank lines. // If the next thing after the blank lines is not another import then we don't want to diff --git a/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java b/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java index 5a6b1f906..1a03c743d 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java @@ -800,6 +800,27 @@ public static Collection parameters() { "public class Blim {}", }, }, + { + { + "package p;", + "", + "import java.lang.Bar;", + "import java.lang.Baz;", + ";", + "import java.lang.Foo;", + "", + "interface Test {}", + }, + { + "package p;", + "", + "import java.lang.Bar;", + "import java.lang.Baz;", + "import java.lang.Foo;", + "", + "interface Test {}", + } + } }; ImmutableList.Builder builder = ImmutableList.builder(); Arrays.stream(inputsOutputs).forEach(input -> builder.add(createRow(input))); From 93d649d0fbc07fc604f7b47b3098cf6e1df521de Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 16 Oct 2020 08:38:42 -0700 Subject: [PATCH 055/379] Move import ordering tests out of the AOSP section follow-up to https://github.com/google/google-java-format/commit/b769e812a052d7cff4a2d86eff4981a5d358ee2d PiperOrigin-RevId: 337511552 --- .../java/ImportOrdererTest.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java b/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java index 1a03c743d..f40fa3821 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java @@ -527,6 +527,27 @@ public static Collection parameters() { "class Test {}", } }, + { + { + "package p;", + "", + "import java.lang.Bar;", + "import java.lang.Baz;", + ";", + "import java.lang.Foo;", + "", + "interface Test {}", + }, + { + "package p;", + "", + "import java.lang.Bar;", + "import java.lang.Baz;", + "import java.lang.Foo;", + "", + "interface Test {}", + } + } }; ImmutableList.Builder builder = ImmutableList.builder(); @@ -799,27 +820,6 @@ public static Collection parameters() { "", "public class Blim {}", }, - }, - { - { - "package p;", - "", - "import java.lang.Bar;", - "import java.lang.Baz;", - ";", - "import java.lang.Foo;", - "", - "interface Test {}", - }, - { - "package p;", - "", - "import java.lang.Bar;", - "import java.lang.Baz;", - "import java.lang.Foo;", - "", - "interface Test {}", - } } }; ImmutableList.Builder builder = ImmutableList.builder(); From 3ce093515ad0bc1458e8965fdf71f78482f87968 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Fri, 20 Nov 2020 12:53:43 -0800 Subject: [PATCH 056/379] Remove typo period in flags documentation. I *think* they are typoes? Apologies if this is intended. PiperOrigin-RevId: 343547804 --- .../java/com/google/googlejavaformat/java/UsageException.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/UsageException.java b/core/src/main/java/com/google/googlejavaformat/java/UsageException.java index 82c0843dc..a10f2d076 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/UsageException.java +++ b/core/src/main/java/com/google/googlejavaformat/java/UsageException.java @@ -46,9 +46,9 @@ final class UsageException extends Exception { " Do not fix the import order. Unused imports will still be removed.", " --skip-removing-unused-imports", " Do not remove unused imports. Imports will still be sorted.", - " . --skip-reflowing-long-strings", + " --skip-reflowing-long-strings", " Do not reflow string literals that exceed the column limit.", - " . --skip-javadoc-formatting", + " --skip-javadoc-formatting", " Do not reformat javadoc.", " --dry-run, -n", " Prints the paths of the files whose contents would change if the formatter were run" From c1dd08d349b098f4bceb5b71aa1d6c2251de4f6d Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Wed, 25 Nov 2020 10:47:19 -0800 Subject: [PATCH 057/379] Introduce GitHub Actions based CI workflow This PR introduces a CI workflow using GitHub Actions and removes the Travis CI configuration file. Find new workflow runs for this PR here: https://github.com/sormuras/google-java-format/actions #### TODO - [x] Email [Notifications](https://docs.github.com/en/free-pro-team@latest/github/managing-subscriptions-and-notifications-on-github/configuring-notifications) -- register `google-java-format-dev+ci@google.com` as a watcher or let each interested use register themself? - [ ] Test publish snapshot job on `google:master` -- after storing credential [secrets](https://github.com/google/google-java-format/settings/secrets/actions). - [ ] Remove AppVeyor [integration](https://github.com/google/google-java-format/settings/installations) and delete `appveyor.yml` configuration file. Closes #543 Fixes #544 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/544 from sormuras:github-action a689f6234aed2e32bd7aca093b92e391ac6c8170 PiperOrigin-RevId: 344280060 --- .github/workflows/ci.yml | 58 ++++++++++++++++++++++++++++++++++++++++ .travis.yml | 42 ----------------------------- 2 files changed, 58 insertions(+), 42 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..c3e53dd5e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,58 @@ +name: CI + +on: [ push, pull_request ] + +jobs: + test: + name: "JDK ${{ matrix.java }} on ${{ matrix.os }}" + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest, macos-latest, windows-latest ] + java: [ 15, 11 ] + runs-on: ${{ matrix.os }} + steps: + - name: 'Check out repository' + uses: actions/checkout@v2 + - name: 'Cache local Maven repository' + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: 'Set up JDK ${{ matrix.java }}' + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + - name: 'Install' + shell: bash + run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V + - name: 'Test' + shell: bash + run: mvn test -B + + publish_snapshot: + name: 'Publish snapshot' + needs: test + if: github.event_name == 'push' && github.repository == 'google/google-java-format' && github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + steps: + - name: 'Check out repository' + uses: actions/checkout@v2 + - name: 'Cache local Maven repository' + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: 'Set up JDK 15' + uses: actions/setup-java@v1 + with: + java-version: 15 + server-id: sonatype-nexus-snapshots + server-username: CI_DEPLOY_USERNAME + server-password: CI_DEPLOY_PASSWORD + - name: 'Publish' + run: mvn source:jar deploy -B -DskipTests=true -Dinvoker.skip=true -Dmaven.javadoc.skip=true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b8a7c33af..000000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -language: java - -notifications: - email: - recipients: - - google-java-format-dev+ci@google.com - on_success: change - on_failure: always - -jdk: - - openjdk11 - - openjdk14 - - openjdk-ea - -matrix: - allow_failures: - - jdk: openjdk-ea - -# see https://github.com/travis-ci/travis-ci/issues/8408 -before_install: -- unset _JAVA_OPTIONS - -install: echo "The default Travis install script is being skipped!" - -# use travis-ci docker based infrastructure -sudo: false - -cache: - directories: - - $HOME/.m2 - -script: -- mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -- mvn test -B - -env: - global: - - secure: KkUX74NDDk95WR60zwN6x6pz49KAfR0zUu1thxl8Kke0+WVoIv1EBo7/e4ZXTdBKxlzQCX9Aa0OlIyUlhGJeuNIGtX16lcNyZNmKSacfrT68MpZqi+nAiYp8tnOyW/zuI+shSKHkGQOFq6c9KTtR9vG8kjr1Q9dNl/H5QjGaG1ZMiU/mGH9ompf+0nQTMDLKaEWV+SpKGjK5U1Zs2p08I9KKePbZoi9L2oAw5cH9wW8Q3pQJds6Rkwy9aecxRd4xmTza7Lb04dmByjqY8gsIjrTN0onOndBmLKTHiH5NVLKf0ilEVGiMQ1x4eCQolcRpGzxdTTKI0ahiWS59UABVoy1sXYqkIbZjpmMuGhHvbRir7YEXaG8LRUAxdWd9drJfvKQeBphQlIJKwajHSiMAdc9zisQg1UW75HSGKoPDHpzq+P7YBil2PUjk+5yUy5OytX6IebFT4KdeCO2ayu338yqb2t8q98elMoD5jwFVD0tpkLQ6xsYodClSGfMCVfP2zTkB7c4sHZV7tJS68CiNt7sCwz9CTNApFiSWMBxLKkKQ7VSBTy9bAn+phvW0u/maGsrRnehmsV3PVPtEsMlrqeMGwaPqIwx1l6otVQCnGRt3e8z3HoxY6AaBPaX0Z8lH2y+BxYhWTYzGhRxyyV666u/9yekTXmH53c7at7mau6Q= - - secure: VWnZcPA4esdaMJgh0Mui7K5O++AGZY3AYswufd0UUbAmnK60O6cDBOSelnr7hImDgZ09L2RWMXIVCt4b+UFXoIhqrvZKVitUXPldS6uNJeGT9p6quFf36o8Wf0ppKWnPd66AY6ECnE75Ujn1Maw899kb3zY2SvIvzA7HlXqtmowHCVGoJ4ou6LQxJpVEJ4hjvS2gQMF9W31uOzRzMI1JhdZioYmqe6eq9sGmRZZiYON7jBqX8f4XW0tTZoK+dVRNwYQcwyqcvQpxeI15VWDq5cqjBw3ps5XSEYTNIFUXREnEEi+vLdCuw/YRZp1ij7LiQKp6bcb2KROXaWii4VpUNWxIAflm4Nvn/8pa/3CUwqIbxTSAL+Qkb2iEzuYuNPGLr72mQgGEnlSpaqzUx0miwjJ41x3Q8mf72ihIME7YQGMDJL7TA7/GjXFeSxroPk65tbssAGmbjwGGJX67NHUzeQPW2QPA2cohCHyopKB9GqhKgKwKjenkCUaBGCaZReZz9XkSkHTXlxxSakMTmgJnA9To9d2lPOy0nppUvrd/0uAbPuxxCZqXElRvOvHKzpV1ZpKpqSxvjh63mCQRTi2rFiPn8uFaajai9mHaPoGmNwQwIUbAviNqifuIEPpc6cOuyV0MWJwdFLo1SKamJya/MwQz+IwXuY2TX7Fmv9HovdM= - -after_success: -- util/publish-snapshot-on-commit.sh From fcf767116e3f478a17dd28c22a25e509b2cabbab Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Mon, 30 Nov 2020 08:38:04 -0800 Subject: [PATCH 058/379] Check build with JDK 16-ea Addresses https://github.com/google/google-java-format/issues/538#issuecomment-733522202 Fixes #548 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/548 from sormuras:jdk-ea 0ee3f7c62c75a4f05b54ed088e3fefa8d40c650c PiperOrigin-RevId: 344818484 --- .github/workflows/ci.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3e53dd5e..468d9e99f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,31 @@ jobs: shell: bash run: mvn test -B + early_access: + name: 'JDK Early-Access' + continue-on-error: true + runs-on: ubuntu-latest + steps: + - name: 'Check out repository' + uses: actions/checkout@v2 + - name: 'Cache local Maven repository' + uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: 'Set up JDK ${{ matrix.java }}' + uses: actions/setup-java@v1 + with: + java-version: 16-ea + - name: 'Install' + shell: bash + run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V + - name: 'Test' + shell: bash + run: mvn test -B + publish_snapshot: name: 'Publish snapshot' needs: test From d25a84487dd5b32ebba5112a7d51081162b6ab26 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 30 Nov 2020 15:41:51 -0800 Subject: [PATCH 059/379] Fix GitHub Actions-based snapshot deployment Fixes https://github.com/google/google-java-format/issues/547 PiperOrigin-RevId: 344903246 --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 468d9e99f..a14629ff8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,4 +80,7 @@ jobs: server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD - name: 'Publish' + env: + CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} + CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} run: mvn source:jar deploy -B -DskipTests=true -Dinvoker.skip=true -Dmaven.javadoc.skip=true From cc58ed36614b10e97e74d69daeb02c093a03885e Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 2 Dec 2020 13:29:13 -0800 Subject: [PATCH 060/379] Delete google-java-format appveyor and travis configs PiperOrigin-RevId: 345300707 --- .github/workflows/ci.yml | 14 ++++++++++++++ appveyor.yml | 39 --------------------------------------- 2 files changed, 14 insertions(+), 39 deletions(-) delete mode 100644 appveyor.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a14629ff8..2b3134c10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,3 +1,17 @@ +# Copyright 2020 The Error Prone Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + name: CI on: [ push, pull_request ] diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index ac535c9a6..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,39 +0,0 @@ -# Don't build branches that are not PRs, to avoid double builds. -branches: - only: - - master - -os: Visual Studio 2015 - -install: - - ps: | - Add-Type -AssemblyName System.IO.Compression.FileSystem - if (!(Test-Path -Path "C:\maven" )) { - (new-object System.Net.WebClient).DownloadFile( - 'http://www.us.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.zip', - 'C:\maven-bin.zip' - ) - [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\maven-bin.zip", "C:\maven") - } - - cmd: SET JAVA_HOME=C:\Program Files\Java\jdk11 - - cmd: SET PATH=C:\maven\apache-maven-3.3.9\bin;%JAVA_HOME%\bin;%PATH% - - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - -build_script: - - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V - -test_script: - - mvn test -B - -cache: - - C:\maven\ - - C:\Users\appveyor\.m2 - -notifications: - - provider: Email - to: - - google-java-format-dev+ci@google.com - on_build_success: false - on_build_failure: true - on_build_status_changed: true From 8ba2b05955fb7d3b40bf15bcc942e9cddddf617d Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 4 Dec 2020 11:23:28 -0800 Subject: [PATCH 061/379] Miscellaneous cleanups Startblock: cl-status copybara contains unknown commit in live PiperOrigin-RevId: 345718768 --- .../java/com/google/googlejavaformat/Doc.java | 3 +- .../google/googlejavaformat/OpsBuilder.java | 9 +++-- .../java/CommandLineOptionsParser.java | 2 +- .../java/FormatterException.java | 5 +-- .../java/JavaInputAstVisitor.java | 4 +-- .../googlejavaformat/java/JavaOutput.java | 8 ++--- .../google/googlejavaformat/java/Main.java | 7 ++-- .../java/ModifierOrderer.java | 2 +- .../java/RemoveUnusedImports.java | 3 +- .../googlejavaformat/java/StringWrapper.java | 2 +- .../java/javadoc/JavadocWriter.java | 5 ++- .../java/CommandLineOptionsParserTest.java | 6 ++-- .../googlejavaformat/java/DiagnosticTest.java | 9 +++-- .../googlejavaformat/java/FormatterTest.java | 16 ++++----- .../googlejavaformat/java/MainTest.java | 20 ++++++----- .../java/PartialFormattingTest.java | 33 +++++++++---------- .../java/RemoveUnusedImportsTest.java | 2 +- .../java/StringWrapperIntegrationTest.java | 4 +-- .../java/filer/FormattingFilerTest.java | 8 ++--- pom.xml | 2 +- 20 files changed, 77 insertions(+), 73 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Doc.java b/core/src/main/java/com/google/googlejavaformat/Doc.java index e663c9603..35acca367 100644 --- a/core/src/main/java/com/google/googlejavaformat/Doc.java +++ b/core/src/main/java/com/google/googlejavaformat/Doc.java @@ -15,6 +15,7 @@ package com.google.googlejavaformat; import static com.google.common.collect.Iterables.getLast; +import static java.lang.Math.max; import com.google.common.base.MoreObjects; import com.google.common.collect.DiscreteDomain; @@ -653,7 +654,7 @@ public State computeBreaks(State state, int lastIndent, boolean broken) { if (broken) { this.broken = true; - this.newIndent = Math.max(lastIndent + plusIndent.eval(), 0); + this.newIndent = max(lastIndent + plusIndent.eval(), 0); return state.withColumn(newIndent); } else { this.broken = false; diff --git a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java index e8e100f3f..36e038adf 100644 --- a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java +++ b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java @@ -14,6 +14,9 @@ package com.google.googlejavaformat; +import static java.lang.Math.max; +import static java.lang.Math.min; + import com.google.common.base.MoreObjects; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; @@ -39,14 +42,14 @@ public int actualSize(int position, int length) { int start = startToken.getTok().getPosition(); for (Tok tok : startToken.getToksBefore()) { if (tok.isComment()) { - start = Math.min(start, tok.getPosition()); + start = min(start, tok.getPosition()); } } Token endToken = input.getPositionTokenMap().get(position + length - 1); int end = endToken.getTok().getPosition() + endToken.getTok().length(); for (Tok tok : endToken.getToksAfter()) { if (tok.isComment()) { - end = Math.max(end, tok.getPosition() + tok.length()); + end = max(end, tok.getPosition() + tok.length()); } } return end - start; @@ -62,7 +65,7 @@ public Integer actualStartColumn(int position) { return start; } if (tok.isComment()) { - start = Math.min(start, tok.getPosition()); + start = min(start, tok.getPosition()); } } return start; diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java index 202382640..f7c3dec95 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java @@ -54,7 +54,7 @@ static CommandLineOptions parse(Iterable options) { int idx = option.indexOf('='); if (idx >= 0) { flag = option.substring(0, idx); - value = option.substring(idx + 1, option.length()); + value = option.substring(idx + 1); } else { flag = option; value = null; diff --git a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java index 3ccb44a46..808916c2c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java +++ b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java @@ -26,7 +26,7 @@ /** Checked exception class for formatter errors. */ public final class FormatterException extends Exception { - private ImmutableList diagnostics; + private final ImmutableList diagnostics; public FormatterException(String message) { this(FormatterDiagnostic.create(message)); @@ -47,7 +47,8 @@ public List diagnostics() { public static FormatterException fromJavacDiagnostics( Iterable> diagnostics) { - return new FormatterException(Iterables.transform(diagnostics, d -> toFormatterDiagnostic(d))); + return new FormatterException( + Iterables.transform(diagnostics, FormatterException::toFormatterDiagnostic)); } private static FormatterDiagnostic toFormatterDiagnostic(Diagnostic input) { diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 672d8b74b..f84e228f1 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -139,7 +139,6 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Deque; import java.util.LinkedHashSet; import java.util.List; @@ -3270,8 +3269,7 @@ int declareOne( } Deque> dims = - new ArrayDeque<>( - typeWithDims.isPresent() ? typeWithDims.get().dims : Collections.emptyList()); + new ArrayDeque<>(typeWithDims.isPresent() ? typeWithDims.get().dims : ImmutableList.of()); int baseDims = 0; builder.open( diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java index 9564a225a..c43a91ad1 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java @@ -14,6 +14,7 @@ package com.google.googlejavaformat.java; +import static java.lang.Math.min; import static java.util.Comparator.comparing; import com.google.common.base.CharMatcher; @@ -261,8 +262,7 @@ public ImmutableList getFormatReplacements(RangeSet iRange } } - int replaceTo = - Math.min(endTok.getPosition() + endTok.length(), javaInput.getText().length()); + int replaceTo = min(endTok.getPosition() + endTok.length(), javaInput.getText().length()); // If the formatted ranged ended in the trailing trivia of the last token before EOF, // format all the way up to EOF to deal with trailing whitespace correctly. if (endTok.getIndex() == javaInput.getkN() - 1) { @@ -304,7 +304,7 @@ public ImmutableList getFormatReplacements(RangeSet iRange } else { if (newline == -1) { // If there wasn't a trailing newline in the input, indent the next line. - replacement.append(after.substring(0, idx)); + replacement.append(after, 0, idx); } break; } @@ -352,7 +352,7 @@ public static String applyReplacements(String input, List replaceme public static int startPosition(Token token) { int min = token.getTok().getPosition(); for (Input.Tok tok : token.getToksBefore()) { - min = Math.min(min, tok.getPosition()); + min = min(min, tok.getPosition()); } return min; } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 9231bdae4..451bc697c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -14,6 +14,7 @@ package com.google.googlejavaformat.java; +import static java.lang.Math.min; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.io.ByteStreams; @@ -109,7 +110,7 @@ public int format(String... args) throws UsageException { } private int formatFiles(CommandLineOptions parameters, JavaFormatterOptions options) { - int numThreads = Math.min(MAX_THREADS, parameters.files().size()); + int numThreads = min(MAX_THREADS, parameters.files().size()); ExecutorService executorService = Executors.newFixedThreadPool(numThreads); Map inputs = new LinkedHashMap<>(); @@ -146,7 +147,7 @@ private int formatFiles(CommandLineOptions parameters, JavaFormatterOptions opti } catch (ExecutionException e) { if (e.getCause() instanceof FormatterException) { for (FormatterDiagnostic diagnostic : ((FormatterException) e.getCause()).diagnostics()) { - errWriter.println(path + ":" + diagnostic.toString()); + errWriter.println(path + ":" + diagnostic); } } else { errWriter.println(path + ": error: " + e.getCause().getMessage()); @@ -205,7 +206,7 @@ private int formatStdin(CommandLineOptions parameters, JavaFormatterOptions opti } } catch (FormatterException e) { for (FormatterDiagnostic diagnostic : e.diagnostics()) { - errWriter.println(stdinFilename + ":" + diagnostic.toString()); + errWriter.println(stdinFilename + ":" + diagnostic); } ok = false; // TODO(cpovirk): Catch other types of exception (as we do in the formatFiles case). diff --git a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java index f7f610be7..42eaf45f3 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java @@ -130,7 +130,7 @@ static JavaInput reorderModifiers(JavaInput javaInput, Collection if (i > 0) { addTrivia(replacement, modifierTokens.get(i).getToksBefore()); } - replacement.append(mods.get(i).toString()); + replacement.append(mods.get(i)); if (i < (modifierTokens.size() - 1)) { addTrivia(replacement, modifierTokens.get(i).getToksAfter()); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index d93948082..b2b484adc 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -16,6 +16,7 @@ package com.google.googlejavaformat.java; +import static java.lang.Math.max; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.CharMatcher; @@ -247,7 +248,7 @@ private static RangeMap buildReplacements( } // delete the import int endPosition = importTree.getEndPosition(unit.endPositions); - endPosition = Math.max(CharMatcher.isNot(' ').indexIn(contents, endPosition), endPosition); + endPosition = max(CharMatcher.isNot(' ').indexIn(contents, endPosition), endPosition); String sep = Newlines.guessLineSeparator(contents); if (endPosition + sep.length() < contents.length() && contents.subSequence(endPosition, endPosition + sep.length()).toString().equals(sep)) { diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index e41bb6663..063843622 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -259,7 +259,7 @@ private static String reflow( while (!input.isEmpty()) { int length = 0; List line = new ArrayList<>(); - if (input.stream().mapToInt(x -> x.length()).sum() <= width) { + if (input.stream().mapToInt(String::length).sum() <= width) { width -= trailing; } while (!input.isEmpty() && (length <= 4 || (length + input.peekFirst().length()) < width)) { diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java index c2431c456..9c5838aeb 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java @@ -15,6 +15,7 @@ package com.google.googlejavaformat.java.javadoc; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Comparators.max; import static com.google.common.collect.Sets.immutableEnumSet; import static com.google.googlejavaformat.java.javadoc.JavadocWriter.AutoIndent.AUTO_INDENT; import static com.google.googlejavaformat.java.javadoc.JavadocWriter.AutoIndent.NO_AUTO_INDENT; @@ -28,7 +29,6 @@ import com.google.common.base.Strings; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Ordering; import com.google.googlejavaformat.java.javadoc.Token.Type; /** @@ -270,8 +270,7 @@ private void requestNewline() { } private void requestWhitespace(RequestedWhitespace requestedWhitespace) { - this.requestedWhitespace = - Ordering.natural().max(requestedWhitespace, this.requestedWhitespace); + this.requestedWhitespace = max(requestedWhitespace, this.requestedWhitespace); } /** diff --git a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java index 8d71f4dd6..1a4ed09b4 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java @@ -19,12 +19,12 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; -import java.util.Collections; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -39,7 +39,7 @@ public class CommandLineOptionsParserTest { @Test public void defaults() { - CommandLineOptions options = CommandLineOptionsParser.parse(Collections.emptyList()); + CommandLineOptions options = CommandLineOptionsParser.parse(ImmutableList.of()); assertThat(options.files()).isEmpty(); assertThat(options.stdin()).isFalse(); assertThat(options.aosp()).isFalse(); @@ -159,7 +159,7 @@ public void illegalLines() { CommandLineOptionsParser.parse(Arrays.asList("-lines=1:1", "-lines=1:1")); fail(); } catch (IllegalArgumentException e) { - assertThat(e.getMessage()).contains("overlap"); + assertThat(e).hasMessageThat().contains("overlap"); } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java b/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java index 0b81ba6b4..6e48dfc5e 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java @@ -23,7 +23,6 @@ import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Locale; @@ -156,7 +155,7 @@ public void parseError2() throws FormatterException, IOException, UsageException Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("A.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -173,7 +172,7 @@ public void parseError2() throws FormatterException, IOException, UsageException public void parseErrorStdin() throws FormatterException, IOException, UsageException { String input = "class Foo { void f() {\n g() } }"; - InputStream inStream = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)); + InputStream inStream = new ByteArrayInputStream(input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), inStream); @@ -190,7 +189,7 @@ public void lexError2() throws FormatterException, IOException, UsageException { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("A.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -206,7 +205,7 @@ public void lexError2() throws FormatterException, IOException, UsageException { @Test public void lexErrorStdin() throws FormatterException, IOException, UsageException { String input = "class Foo { void f() {\n g('foo'); } }"; - InputStream inStream = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)); + InputStream inStream = new ByteArrayInputStream(input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), inStream); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java index 3f6e974d1..9859245c7 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java @@ -16,6 +16,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.fail; import com.google.common.base.Joiner; @@ -27,7 +28,6 @@ import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import org.junit.Rule; @@ -63,7 +63,7 @@ public void testFormatAosp() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("A.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -94,7 +94,7 @@ public void testFormatStdinStdoutWithDashFlag() throws Exception { String input = "class Foo{\n" + "void f\n" + "() {\n" + "}\n" + "}\n"; String expectedOutput = "class Foo {\n" + " void f() {}\n" + "}\n"; - InputStream in = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)); + InputStream in = new ByteArrayInputStream(input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -115,7 +115,7 @@ public void testFormatLengthUpToEOF() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -132,7 +132,7 @@ public void testFormatLengthOutOfRange() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -302,7 +302,7 @@ private void importOrdering(String sortArg, String outputResourceName) String inputResourceName = "com/google/googlejavaformat/java/testimports/A.input"; String input = getResource(inputResourceName); String expectedOutput = getResource(outputResourceName); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -315,14 +315,14 @@ private void importOrdering(String sortArg, String outputResourceName) assertThat(err.toString()).isEmpty(); assertThat(out.toString()).isEmpty(); - String output = new String(Files.readAllBytes(path), StandardCharsets.UTF_8); + String output = new String(Files.readAllBytes(path), UTF_8); assertThat(output).isEqualTo(expectedOutput); } private String getResource(String resourceName) throws IOException { try (InputStream stream = getClass().getClassLoader().getResourceAsStream(resourceName)) { assertWithMessage("Missing resource: " + resourceName).that(stream).isNotNull(); - return CharStreams.toString(new InputStreamReader(stream, StandardCharsets.UTF_8)); + return CharStreams.toString(new InputStreamReader(stream, UTF_8)); } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index 613d3912c..fa23486fd 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -14,6 +14,8 @@ package com.google.googlejavaformat.java; +import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_PATH; +import static com.google.common.base.StandardSystemProperty.JAVA_HOME; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static java.nio.charset.StandardCharsets.UTF_8; @@ -108,9 +110,9 @@ public void testMain() throws Exception { Process process = new ProcessBuilder( ImmutableList.of( - Paths.get(System.getProperty("java.home")).resolve("bin/java").toString(), + Paths.get(JAVA_HOME.value()).resolve("bin/java").toString(), "-cp", - System.getProperty("java.class.path"), + JAVA_CLASS_PATH.value(), Main.class.getName())) .redirectError(Redirect.PIPE) .redirectOutput(Redirect.PIPE) @@ -388,9 +390,9 @@ public void dryRunFiles() throws Exception { assertThat(out.toString()) .isEqualTo( - b.toAbsolutePath().toString() + b.toAbsolutePath() + System.lineSeparator() - + c.toAbsolutePath().toString() + + c.toAbsolutePath() + System.lineSeparator()); assertThat(err.toString()).isEmpty(); } @@ -434,9 +436,9 @@ public void exitIfChangedStdin() throws Exception { Process process = new ProcessBuilder( ImmutableList.of( - Paths.get(System.getProperty("java.home")).resolve("bin/java").toString(), + Paths.get(JAVA_HOME.value()).resolve("bin/java").toString(), "-cp", - System.getProperty("java.class.path"), + JAVA_CLASS_PATH.value(), Main.class.getName(), "-n", "--set-exit-if-changed", @@ -460,9 +462,9 @@ public void exitIfChangedFiles() throws Exception { Process process = new ProcessBuilder( ImmutableList.of( - Paths.get(System.getProperty("java.home")).resolve("bin/java").toString(), + Paths.get(JAVA_HOME.value()).resolve("bin/java").toString(), "-cp", - System.getProperty("java.class.path"), + JAVA_CLASS_PATH.value(), Main.class.getName(), "-n", "--set-exit-if-changed", @@ -474,7 +476,7 @@ public void exitIfChangedFiles() throws Exception { String err = new String(ByteStreams.toByteArray(process.getErrorStream()), UTF_8); String out = new String(ByteStreams.toByteArray(process.getInputStream()), UTF_8); assertThat(err).isEmpty(); - assertThat(out).isEqualTo(path.toAbsolutePath().toString() + System.lineSeparator()); + assertThat(out).isEqualTo(path.toAbsolutePath() + System.lineSeparator()); assertThat(process.exitValue()).isEqualTo(1); } diff --git a/core/src/test/java/com/google/googlejavaformat/java/PartialFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/PartialFormattingTest.java index 57d55d707..b1142b3b2 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/PartialFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/PartialFormattingTest.java @@ -25,7 +25,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -397,7 +396,7 @@ public void testLength() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -429,7 +428,7 @@ public void testLengthRange() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -475,7 +474,7 @@ public void statementAndComments() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -521,7 +520,7 @@ public void statementAndComments2() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -567,7 +566,7 @@ public void statementAndComments3() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -714,7 +713,7 @@ public void noTokensOnLine() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("FormatterException.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -957,7 +956,7 @@ public void lineWithTrailingComment() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -1081,7 +1080,7 @@ public void outOfRangeStartLine() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -1108,7 +1107,7 @@ public void outOfRangeEndLine() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -1133,7 +1132,7 @@ public void testOutOfRangeLines() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -1156,7 +1155,7 @@ public void testEmptyFirstLine() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -1177,7 +1176,7 @@ public void testEmptyLastLine() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -1429,7 +1428,7 @@ public void partialEnum() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, lines(input).getBytes(StandardCharsets.UTF_8)); + Files.write(path, lines(input).getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -1459,7 +1458,7 @@ public void partialModifierOrder() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, lines(input).getBytes(StandardCharsets.UTF_8)); + Files.write(path, lines(input).getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -1505,7 +1504,7 @@ public void endOfLine() throws Exception { private String formatMain(String input, String... args) throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Test.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -1655,7 +1654,7 @@ public void b21668189() throws Exception { private String runFormatter(String input, String[] args) throws IOException, UsageException { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(StandardCharsets.UTF_8)); + Files.write(path, input.getBytes(UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsTest.java b/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsTest.java index 1965febef..675bc8884 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsTest.java @@ -258,7 +258,7 @@ public static Collection parameters() { }; ImmutableList.Builder builder = ImmutableList.builder(); for (String[][] inputAndOutput : inputsOutputs) { - assertThat(inputAndOutput.length).isEqualTo(2); + assertThat(inputAndOutput).hasLength(2); String[] input = inputAndOutput[0]; String[] output = inputAndOutput[1]; String[] parameters = { diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java index 89c94ea30..53fb54d91 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java @@ -395,8 +395,8 @@ public void test() throws Exception { @Test public void testCR() throws Exception { - assertThat(StringWrapper.wrap(40, formatter.formatSource(input.replace("\n", "\r")), formatter)) - .isEqualTo(output.replace("\n", "\r")); + assertThat(StringWrapper.wrap(40, formatter.formatSource(input.replace('\n', '\r')), formatter)) + .isEqualTo(output.replace('\n', '\r')); } @Test diff --git a/core/src/test/java/com/google/googlejavaformat/java/filer/FormattingFilerTest.java b/core/src/test/java/com/google/googlejavaformat/java/filer/FormattingFilerTest.java index 4fef2076b..38cac3550 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/filer/FormattingFilerTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/filer/FormattingFilerTest.java @@ -52,7 +52,7 @@ public void invalidSyntaxDoesNotThrowError() throws IOException { new Messager() { @Override public void printMessage(javax.tools.Diagnostic.Kind kind, CharSequence msg) { - logMessages.add(kind.toString() + ";" + msg); + logMessages.add(kind + ";" + msg); } @Override @@ -73,9 +73,9 @@ public void printMessage( String file = Joiner.on('\n').join("package foo;", "public class Bar {"); FormattingFiler formattingFiler = new FormattingFiler(new FakeFiler(), messager); - Writer writer = formattingFiler.createSourceFile("foo.Bar").openWriter(); - writer.write(file); - writer.close(); + try (Writer writer = formattingFiler.createSourceFile("foo.Bar").openWriter()) { + writer.write(file); + } assertThat(logMessages).containsExactly("NOTE;Error formatting foo.Bar"); } diff --git a/pom.xml b/pom.xml index 82b0a3ba2..87049dec4 100644 --- a/pom.xml +++ b/pom.xml @@ -95,7 +95,7 @@ UTF-8 1.8 - 28.1-jre + 30.0-jre 1.0 3.6.1 From 0a2f8647929e361304db5d1360896152e76a7e21 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sun, 13 Dec 2020 22:13:09 -0800 Subject: [PATCH 062/379] Prepare google-java-format for JDK 16 ea * Work around change to tokenization in JDK-8254073 * Access refactored expression pattern getters reflectively * Relax a check on a diagnostic whose position changed PiperOrigin-RevId: 347318664 --- .../googlejavaformat/java/JavacTokens.java | 20 ++++++++++++++- .../java/java14/Java14InputAstVisitor.java | 25 ++++++++++++++++--- .../googlejavaformat/java/DiagnosticTest.java | 3 +-- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java index a8c9efd2c..ba7e3b774 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java @@ -128,10 +128,28 @@ static class CommentSavingTokenizer extends JavaTokenizer { @Override protected Comment processComment(int pos, int endPos, CommentStyle style) { - char[] buf = reader.getRawCharacters(pos, endPos); + char[] buf = getRawCharactersReflectively(pos, endPos); return new CommentWithTextAndPosition( pos, endPos, new AccessibleReader(fac, buf, buf.length), style); } + + private char[] getRawCharactersReflectively(int beginIndex, int endIndex) { + Object instance; + try { + instance = JavaTokenizer.class.getDeclaredField("reader").get(this); + } catch (ReflectiveOperationException e) { + instance = this; + } + try { + return (char[]) + instance + .getClass() + .getMethod("getRawCharacters", int.class, int.class) + .invoke(instance, beginIndex, endIndex); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } } /** A {@link Comment} that saves its text and start position. */ diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index 78cfd66b1..2a90b939d 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -29,6 +29,7 @@ import com.sun.source.tree.InstanceOfTree; import com.sun.source.tree.SwitchExpressionTree; import com.sun.source.tree.Tree; +import com.sun.source.tree.VariableTree; import com.sun.source.tree.YieldTree; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; @@ -37,6 +38,7 @@ import com.sun.tools.javac.tree.TreeInfo; import java.util.List; import java.util.Optional; +import javax.lang.model.element.Name; /** * Extends {@link JavaInputAstVisitor} with support for AST nodes that were added or modified for @@ -51,12 +53,29 @@ public Java14InputAstVisitor(OpsBuilder builder, int indentMultiplier) { @Override public Void visitBindingPattern(BindingPatternTree node, Void unused) { sync(node); - scan(node.getType(), null); - builder.breakOp(" "); - visit(node.getBinding()); + try { + VariableTree variableTree = + (VariableTree) BindingPatternTree.class.getMethod("getVariable").invoke(node); + visitBindingPattern(variableTree.getType(), variableTree.getName()); + } catch (ReflectiveOperationException e1) { + try { + Tree type = (Tree) BindingPatternTree.class.getMethod("getType").invoke(node); + Name name = (Name) BindingPatternTree.class.getMethod("getName").invoke(node); + visitBindingPattern(type, name); + } catch (ReflectiveOperationException e2) { + e2.addSuppressed(e1); + throw new LinkageError(e2.getMessage(), e2); + } + } return null; } + private void visitBindingPattern(Tree type, Name name) { + scan(type, null); + builder.breakOp(" "); + visit(name); + } + @Override public Void visitYield(YieldTree node, Void aVoid) { sync(node); diff --git a/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java b/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java index 6e48dfc5e..fc966fac3 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java @@ -97,8 +97,7 @@ public void lexError() throws Exception { int result = main.format(path.toString()); assertThat(stdout.toString()).isEmpty(); - assertThat(stderr.toString()) - .contains("InvalidSyntax.java:1:35: error: illegal unicode escape"); + assertThat(stderr.toString()).contains("error: illegal unicode escape"); assertThat(result).isEqualTo(1); } From 94a154097a2252482ec01e56f39ec9482b2c7661 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 1 Jan 2021 13:54:24 -0800 Subject: [PATCH 063/379] Refactor google-java-format CI Only test with 15 on windows and macos PiperOrigin-RevId: 349787620 --- .github/workflows/ci.yml | 41 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b3134c10..14d29b090 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,23 @@ jobs: strategy: fail-fast: false matrix: - os: [ ubuntu-latest, macos-latest, windows-latest ] + os: [ ubuntu-latest ] java: [ 15, 11 ] + experimental: [ false ] + include: + # Only test on macos and windows with a single recent JDK to avoid a + # combinatorial explosion of test configurations. + - os: macos-latest + java: 15 + experimental: false + - os: windows-latest + java: 15 + experimental: false + - os: ubuntu-latest + java: 16-ea + experimental: true runs-on: ${{ matrix.os }} + continue-on-error: ${{ matrix.experimental }} steps: - name: 'Check out repository' uses: actions/checkout@v2 @@ -46,31 +60,6 @@ jobs: shell: bash run: mvn test -B - early_access: - name: 'JDK Early-Access' - continue-on-error: true - runs-on: ubuntu-latest - steps: - - name: 'Check out repository' - uses: actions/checkout@v2 - - name: 'Cache local Maven repository' - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: 'Set up JDK ${{ matrix.java }}' - uses: actions/setup-java@v1 - with: - java-version: 16-ea - - name: 'Install' - shell: bash - run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V - - name: 'Test' - shell: bash - run: mvn test -B - publish_snapshot: name: 'Publish snapshot' needs: test From 24ec96c942a04b89c181df24d80b27c44128b2bf Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 22 Jan 2021 10:48:11 -0800 Subject: [PATCH 064/379] Use more inclusive language in tests https://developers.google.com/style/inclusive-documentation PiperOrigin-RevId: 353273794 --- .../com/google/googlejavaformat/java/testdata/B20535125.input | 2 +- .../google/googlejavaformat/java/testdata/B20535125.output | 2 +- .../com/google/googlejavaformat/java/testdata/B20701054.input | 4 ++-- .../google/googlejavaformat/java/testdata/B20701054.output | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20535125.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20535125.input index 30c232b56..9408235da 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20535125.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20535125.input @@ -5,7 +5,7 @@ class Test { if (!metadata.ignoreOutputTransformations() && Producers.isListenableFutureMapKey(outputKey)) { ImmutableList> nodes = createMapNodes((ProducerNode) node); - checkCollectionNodesAgainstWhitelist(nodes, whitelist); + checkCollectionNodesAgainstAllowlist(nodes, allowlist); return nodes; } else if (!metadata.ignoreOutputTransformations() diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20535125.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20535125.output index 950f4eb0a..aeb36b82c 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20535125.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20535125.output @@ -4,7 +4,7 @@ class Test { void m() { if (!metadata.ignoreOutputTransformations() && Producers.isListenableFutureMapKey(outputKey)) { ImmutableList> nodes = createMapNodes((ProducerNode) node); - checkCollectionNodesAgainstWhitelist(nodes, whitelist); + checkCollectionNodesAgainstAllowlist(nodes, allowlist); return nodes; } else if (!metadata.ignoreOutputTransformations() diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20701054.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20701054.input index 957c2df57..de746bb77 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20701054.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20701054.input @@ -1,8 +1,8 @@ class B20701054 { void m() { ImmutableList x = ImmutableList.builder().add(1).build(); - OptionalBinder.newOptionalBinder(binder(), InputWhitelist.class).setBinding().to( - AllInputWhitelist.class); + OptionalBinder.newOptionalBinder(binder(), InputAllowlist.class).setBinding().to( + AllInputAllowlist.class); Foo z = Foo.INSTANCE.field; Foo z = Foo.INSTANCE.field.field; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20701054.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20701054.output index 7ce6fdad7..2fd9a9af7 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20701054.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20701054.output @@ -1,9 +1,9 @@ class B20701054 { void m() { ImmutableList x = ImmutableList.builder().add(1).build(); - OptionalBinder.newOptionalBinder(binder(), InputWhitelist.class) + OptionalBinder.newOptionalBinder(binder(), InputAllowlist.class) .setBinding() - .to(AllInputWhitelist.class); + .to(AllInputAllowlist.class); Foo z = Foo.INSTANCE.field; Foo z = Foo.INSTANCE.field.field; From 69ba30fd9242eb52446edf18655d190e653348b6 Mon Sep 17 00:00:00 2001 From: David Momenso Date: Wed, 27 Jan 2021 09:06:53 -0800 Subject: [PATCH 065/379] Fixes before commit reformatting option for IntelliJ IDEA Runs the plugin formatter instead of the default IDE Code Style formatting when "Reformat Code" is enabled in the Before Commit options. Fixes #228. Fixes #557 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/557 from momenso:bugfix-228 bd995d9360c29a54aebd2895e338ac1f637a2ea4 PiperOrigin-RevId: 354103277 --- .../intellij/GoogleJavaFormatCodeStyleManager.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java index 52424c2c8..73e981384 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java @@ -30,10 +30,12 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.ChangedRangesInfo; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.CheckUtil; import com.intellij.util.IncorrectOperationException; import java.util.Collection; +import java.util.Collections; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; @@ -69,6 +71,12 @@ public void reformatText(PsiFile file, Collection ranges) } } + @Override + public void reformatTextWithContext(PsiFile file, ChangedRangesInfo changedRangesInfo) + throws IncorrectOperationException { + reformatTextWithContext(file, Collections.singletonList(file.getTextRange())); + } + @Override public void reformatTextWithContext(PsiFile file, Collection ranges) { if (overrideFormatterForFile(file)) { From b9fd8d2242869ea7c9efd10cbbe7278c4b6611b1 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Wed, 10 Feb 2021 03:16:08 -0800 Subject: [PATCH 066/379] Fix an off-by-one issue on the reflowing of string literals. During the initial width calculation, it seems we are off by one. The existing tests where actually also wrong (wrapped at 99). PiperOrigin-RevId: 356697501 --- .../googlejavaformat/java/StringWrapper.java | 14 +++-- .../java/FormatterIntegrationTest.java | 4 +- .../googlejavaformat/java/MainTest.java | 4 +- .../java/testdata/B173808510.input | 8 +++ .../java/testdata/B173808510.output | 9 +++ .../java/testdata/LiteralReflow.input | 44 +++++++++++++++ .../java/testdata/LiteralReflow.output | 55 +++++++++++++++++++ 7 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B173808510.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B173808510.output create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/LiteralReflow.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/LiteralReflow.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 063843622..c0f16e9b5 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -239,9 +239,10 @@ static int hasEscapedNewlineAt(String input, int idx) { * @param separator the line separator * @param columnLimit the number of columns to wrap at * @param startColumn the column position of the beginning of the original text - * @param trailing extra space to leave after the last line - * @param components the text to reflow - * @param first0 true if the text includes the beginning of its enclosing concat chain, i.e. a + * @param trailing extra space to leave after the last line, to accommodate a ; or ) + * @param components the text to reflow. This is a list of “words” of a single literal. Its first + * and last quotes have been stripped + * @param first0 true if the text includes the beginning of its enclosing concat chain */ private static String reflow( String separator, @@ -251,7 +252,7 @@ private static String reflow( ImmutableList components, boolean first0) { // We have space between the start column and the limit to output the first line. - // Reserve two spaces for the quotes. + // Reserve two spaces for the start and end quotes. int width = columnLimit - startColumn - 2; Deque input = new ArrayDeque<>(components); List lines = new ArrayList<>(); @@ -259,10 +260,13 @@ private static String reflow( while (!input.isEmpty()) { int length = 0; List line = new ArrayList<>(); + // If we know this is going to be the last line, then remove a bit of width to account for the + // trailing characters. if (input.stream().mapToInt(String::length).sum() <= width) { + // This isn’t quite optimal, but arguably good enough. See b/179561701 width -= trailing; } - while (!input.isEmpty() && (length <= 4 || (length + input.peekFirst().length()) < width)) { + while (!input.isEmpty() && (length <= 4 || (length + input.peekFirst().length()) <= width)) { String text = input.removeFirst(); line.add(text); length += text.length(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 44ba63925..fdcf6f8a8 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -125,7 +125,9 @@ public FormatterIntegrationTest(String name, String input, String expected) { @Test public void format() { try { - String output = new Formatter().formatSource(input); + Formatter formatter = new Formatter(); + String output = formatter.formatSource(input); + output = StringWrapper.wrap(output, formatter); assertEquals("bad output for " + name, expected, output); } catch (FormatterException e) { fail(String.format("Formatter crashed on %s: %s", name, e.getMessage())); diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index fa23486fd..a7e10fee7 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -525,8 +525,8 @@ public void reflowLongStrings() throws Exception { "class T {", " String s =", " \"one long incredibly unbroken sentence moving from topic to topic so that no one had" - + " a\"", - " + \" chance to interrupt\";", + + " a chance\"", + " + \" to interrupt\";", "}", "", }; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B173808510.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B173808510.input new file mode 100644 index 000000000..e3e849399 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B173808510.input @@ -0,0 +1,8 @@ +class B173808510 { + // b/173808510 + @FlagSpec( + name = "myFlag", + help = + "areallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyloongword word1 word2") + Flag dummy = null; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B173808510.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B173808510.output new file mode 100644 index 000000000..45a939efb --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B173808510.output @@ -0,0 +1,9 @@ +class B173808510 { + // b/173808510 + @FlagSpec( + name = "myFlag", + help = + "areallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyloongword word1" + + " word2") + Flag dummy = null; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/LiteralReflow.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/LiteralReflow.input new file mode 100644 index 000000000..2aa4de330 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/LiteralReflow.input @@ -0,0 +1,44 @@ +class LiteralReflow { + static class TestLineBreak { + String doesNotBreakAt100 = "A very long long long long long long long long long loong sentence"; + String breaksAt101 = "A very long long long long long long long long long long loooong sentence"; + } + + static class TestReflowLimit { + String doesNotReflowAt100 = + "A very long long long long long long long long long long long long long looooong sentence"; + String reflowsWhenLongerThan100 = + "A very long long long long long long long long long long long long long long long sentence"; + } + + static class TestReflowLocation { + String accommodatesWordsUpTo100 = + "A very long long long long long long long long long long long long long long long looooong sentence"; + String breaksBeforeWordsReach101 = + "A very long long long long long long long long long long long long long long long loooooong sentence"; + } + + static class Test2LineReflowLimit { + String doesNotReflowEitherLinesAt100 = + "A very long long long long long long long long long long long long long looooong sentence. And a second very long long long long long long long long long long loong sentence"; + String reflowsLastLineAt101 = + "A very long long long long long long long long long long long long long looooong sentence. And a second very long long long long long long long long long long looong sentence"; + } + + static class TestWithTrailingCharacters { + String fitsLastLineUpTo100WithTrailingCharacters = + f( + f( + "A very long long long long long long long long long long long long loong sentence. And a second very long long long long long long long long loong sentence")); + String reflowsLastLineToAccommodateTrailingCharacters = + f( + f( + "A very long long long long long long long long long long long long loong sentence. And a second very long long long long long long long long looong sentence")); + // Tests an off-by-one issue, but see b/179561701 for a similar issue that is not yet fixed + String doesNotOverTriggerLastLineReflow = + f( + f( + "A very long long long long long long long long long long long long loong sentence." + + " And a second very loong sentence with trailing a a a a a a a a a a a a a a a")); + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/LiteralReflow.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/LiteralReflow.output new file mode 100644 index 000000000..50ed7bda1 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/LiteralReflow.output @@ -0,0 +1,55 @@ +class LiteralReflow { + static class TestLineBreak { + String doesNotBreakAt100 = "A very long long long long long long long long long loong sentence"; + String breaksAt101 = + "A very long long long long long long long long long long loooong sentence"; + } + + static class TestReflowLimit { + String doesNotReflowAt100 = + "A very long long long long long long long long long long long long long looooong sentence"; + String reflowsWhenLongerThan100 = + "A very long long long long long long long long long long long long long long long" + + " sentence"; + } + + static class TestReflowLocation { + String accommodatesWordsUpTo100 = + "A very long long long long long long long long long long long long long long long looooong" + + " sentence"; + String breaksBeforeWordsReach101 = + "A very long long long long long long long long long long long long long long long" + + " loooooong sentence"; + } + + static class Test2LineReflowLimit { + String doesNotReflowEitherLinesAt100 = + "A very long long long long long long long long long long long long long looooong sentence." + + " And a second very long long long long long long long long long long loong sentence"; + String reflowsLastLineAt101 = + "A very long long long long long long long long long long long long long looooong sentence." + + " And a second very long long long long long long long long long long looong" + + " sentence"; + } + + static class TestWithTrailingCharacters { + String fitsLastLineUpTo100WithTrailingCharacters = + f( + f( + "A very long long long long long long long long long long long long loong sentence." + + " And a second very long long long long long long long long loong sentence")); + String reflowsLastLineToAccommodateTrailingCharacters = + f( + f( + "A very long long long long long long long long long long long long loong sentence." + + " And a second very long long long long long long long long looong" + + " sentence")); + // Tests an off-by-one issue, but see b/179561701 for a similar issue that is not yet fixed + String doesNotOverTriggerLastLineReflow = + f( + f( + "A very long long long long long long long long long long long long loong sentence." + + " And a second very loong sentence with trailing a a a a a a a a a a a a a a" + + " a")); + } +} From 506875dc3f0f1018676c764e5fe58c9a8c216900 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 16 Feb 2021 21:53:15 -0800 Subject: [PATCH 067/379] Update Error Prone version and get tests passing with latest JDK 16 EA. https://github.com/google/google-java-format/issues/538 PiperOrigin-RevId: 357875378 --- .../googlejavaformat/java/MainTest.java | 58 ++++++++++++------- pom.xml | 20 ++++++- 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index a7e10fee7..575153efe 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -52,6 +52,16 @@ public class MainTest { // PrintWriter instances used below are hard-coded to use system-default line separator. private final Joiner joiner = Joiner.on(System.lineSeparator()); + private static final ImmutableList ADD_EXPORTS = + ImmutableList.of( + "--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED"); + @Test public void testUsageOutput() { StringWriter out = new StringWriter(); @@ -109,11 +119,13 @@ public void preserveOriginalFile() throws Exception { public void testMain() throws Exception { Process process = new ProcessBuilder( - ImmutableList.of( - Paths.get(JAVA_HOME.value()).resolve("bin/java").toString(), - "-cp", - JAVA_CLASS_PATH.value(), - Main.class.getName())) + ImmutableList.builder() + .add(Paths.get(JAVA_HOME.value()).resolve("bin/java").toString()) + .addAll(ADD_EXPORTS) + .add("-cp") + .add(JAVA_CLASS_PATH.value()) + .add(Main.class.getName()) + .build()) .redirectError(Redirect.PIPE) .redirectOutput(Redirect.PIPE) .start(); @@ -435,14 +447,16 @@ public void exitIfChangedStdin() throws Exception { Files.write(path, "class Test {\n}\n".getBytes(UTF_8)); Process process = new ProcessBuilder( - ImmutableList.of( - Paths.get(JAVA_HOME.value()).resolve("bin/java").toString(), - "-cp", - JAVA_CLASS_PATH.value(), - Main.class.getName(), - "-n", - "--set-exit-if-changed", - "-")) + ImmutableList.builder() + .add(Paths.get(JAVA_HOME.value()).resolve("bin/java").toString()) + .addAll(ADD_EXPORTS) + .add("-cp") + .add(JAVA_CLASS_PATH.value()) + .add(Main.class.getName()) + .add("-n") + .add("--set-exit-if-changed") + .add("-") + .build()) .redirectInput(path.toFile()) .redirectError(Redirect.PIPE) .redirectOutput(Redirect.PIPE) @@ -461,14 +475,16 @@ public void exitIfChangedFiles() throws Exception { Files.write(path, "class Test {\n}\n".getBytes(UTF_8)); Process process = new ProcessBuilder( - ImmutableList.of( - Paths.get(JAVA_HOME.value()).resolve("bin/java").toString(), - "-cp", - JAVA_CLASS_PATH.value(), - Main.class.getName(), - "-n", - "--set-exit-if-changed", - path.toAbsolutePath().toString())) + ImmutableList.builder() + .add(Paths.get(JAVA_HOME.value()).resolve("bin/java").toString()) + .addAll(ADD_EXPORTS) + .add("-cp") + .add(JAVA_CLASS_PATH.value()) + .add(Main.class.getName()) + .add("-n") + .add("--set-exit-if-changed") + .add(path.toAbsolutePath().toString()) + .build()) .redirectError(Redirect.PIPE) .redirectOutput(Redirect.PIPE) .start(); diff --git a/pom.xml b/pom.xml index 87049dec4..42f5f86f5 100644 --- a/pom.xml +++ b/pom.xml @@ -118,7 +118,7 @@ com.google.errorprone error_prone_annotations - 2.0.8 + 2.5.1 @@ -180,7 +180,21 @@ ${java.version} ${java.version} + UTF-8 + true + + -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED + -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED + -XDcompilePolicy=simple -Xplugin:ErrorProne --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED @@ -195,7 +209,7 @@ com.google.errorprone error_prone_core - 2.3.2 + 2.5.1 @@ -245,7 +259,7 @@ 2.18 - -Xmx1024m + -Xmx1024m --illegal-access=permit
From 189c381d7f2c4a9e6f5a5d698a006da22a774c56 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 12 Mar 2021 14:21:14 -0800 Subject: [PATCH 068/379] Improve GitHub Actions hygiene context: unknown commit, https://github.com/google/go-github/pull/1821 PiperOrigin-RevId: 362600035 --- .github/workflows/ci.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14d29b090..f5fced4bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,13 @@ name: CI -on: [ push, pull_request ] +on: + push: + branches: + - master + pull_request: + branches: + - master jobs: test: @@ -40,6 +46,10 @@ jobs: runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} steps: + - name: Cancel previous + uses: styfle/cancel-workflow-action@0.8.0 + with: + access_token: ${{ github.token }} - name: 'Check out repository' uses: actions/checkout@v2 - name: 'Cache local Maven repository' From 6da736d786ac71a134ed6cc43e9cd825c83de0fd Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 25 Mar 2021 10:00:51 -0700 Subject: [PATCH 069/379] Add a space between unary minus and negative literals PiperOrigin-RevId: 365063449 --- .../java/JavaInputAstVisitor.java | 29 ++++++++++++++----- .../java/testdata/B183431894.input | 4 +++ .../java/testdata/B183431894.output | 4 +++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B183431894.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B183431894.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index f84e228f1..89f33fa06 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -1599,11 +1599,7 @@ public Void visitMemberSelect(MemberSelectTree node, Void unused) { public Void visitLiteral(LiteralTree node, Void unused) { sync(node); String sourceForNode = getSourceForNode(node, getCurrentPath()); - // A negative numeric literal -n is usually represented as unary minus on n, - // but that doesn't work for integer or long MIN_VALUE. The parser works - // around that by representing it directly as a signed literal (with no - // unary minus), but the lexer still expects two tokens. - if (sourceForNode.startsWith("-")) { + if (isUnaryMinusLiteral(sourceForNode)) { token("-"); sourceForNode = sourceForNode.substring(1).trim(); } @@ -1611,6 +1607,14 @@ public Void visitLiteral(LiteralTree node, Void unused) { return null; } + // A negative numeric literal -n is usually represented as unary minus on n, + // but that doesn't work for integer or long MIN_VALUE. The parser works + // around that by representing it directly as a signed literal (with no + // unary minus), but the lexer still expects two tokens. + private static boolean isUnaryMinusLiteral(String literalTreeSource) { + return literalTreeSource.startsWith("-"); + } + private void visitPackage( ExpressionTree packageName, List packageAnnotations) { if (!packageAnnotations.isEmpty()) { @@ -1696,10 +1700,10 @@ private boolean ambiguousUnaryOperator(UnaryTree node, String operatorName) { default: return false; } - if (!(node.getExpression() instanceof UnaryTree)) { + JCTree.Tag tag = unaryTag(node.getExpression()); + if (tag == null) { return false; } - JCTree.Tag tag = ((JCTree) node.getExpression()).getTag(); if (tag.isPostUnaryOp()) { return false; } @@ -1709,6 +1713,17 @@ private boolean ambiguousUnaryOperator(UnaryTree node, String operatorName) { return true; } + private JCTree.Tag unaryTag(ExpressionTree expression) { + if (expression instanceof UnaryTree) { + return ((JCTree) expression).getTag(); + } + if (expression instanceof LiteralTree + && isUnaryMinusLiteral(getSourceForNode(expression, getCurrentPath()))) { + return JCTree.Tag.MINUS; + } + return null; + } + @Override public Void visitPrimitiveType(PrimitiveTypeTree node, Void unused) { sync(node); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B183431894.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B183431894.input new file mode 100644 index 000000000..7c220d519 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B183431894.input @@ -0,0 +1,4 @@ +class B183431894 { + int a = - -1; + int d = + +1; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B183431894.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B183431894.output new file mode 100644 index 000000000..7c220d519 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B183431894.output @@ -0,0 +1,4 @@ +class B183431894 { + int a = - -1; + int d = + +1; +} From cc7bd81df738f95249bc881c5dbcc11447432ce6 Mon Sep 17 00:00:00 2001 From: Cameron Samak Date: Thu, 25 Mar 2021 17:13:32 -0700 Subject: [PATCH 070/379] Fix getToken(int k) javadoc to clarify that k is the Tok, not Token, index. Now it's consistent with the comment on kToToken PiperOrigin-RevId: 365156881 --- core/src/main/java/com/google/googlejavaformat/Input.java | 2 +- .../main/java/com/google/googlejavaformat/java/JavaInput.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Input.java b/core/src/main/java/com/google/googlejavaformat/Input.java index 9e17c2bf6..4bc75dc33 100644 --- a/core/src/main/java/com/google/googlejavaformat/Input.java +++ b/core/src/main/java/com/google/googlejavaformat/Input.java @@ -121,7 +121,7 @@ public interface Token { /** * Get the Token by index. * - * @param k the token index + * @param k the Tok index */ public abstract Token getToken(int k); diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 999c8fb7f..9956c856e 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -604,7 +604,7 @@ public int getkN() { /** * Get the Token by index. * - * @param k the token index + * @param k the Tok index */ @Override public Token getToken(int k) { From 5fc0c82a6e43c795d5be567c609b7cfa5c54f070 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Wed, 31 Mar 2021 15:45:33 -0700 Subject: [PATCH 071/379] Update javadoc for getkN to specify that it excludes, not includes, the EOF tok The comment on the kN field directly contradicted the getkN javadoc. kN is the index of the EOF tok, so kN refers to the count excluding the EOF tok PiperOrigin-RevId: 366132866 --- core/src/main/java/com/google/googlejavaformat/Input.java | 2 +- .../main/java/com/google/googlejavaformat/java/JavaInput.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Input.java b/core/src/main/java/com/google/googlejavaformat/Input.java index 4bc75dc33..fb71e047c 100644 --- a/core/src/main/java/com/google/googlejavaformat/Input.java +++ b/core/src/main/java/com/google/googlejavaformat/Input.java @@ -114,7 +114,7 @@ public interface Token { /** * Get the number of toks. * - * @return the number of toks, including the EOF tok + * @return the number of toks, excluding the EOF tok */ public abstract int getkN(); diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 9956c856e..d07d003ef 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -594,7 +594,7 @@ Range characterRangeToTokenRange(int offset, int length) throws Formatt /** * Get the number of toks. * - * @return the number of toks, including the EOF tok + * @return the number of toks, excluding the EOF tok */ @Override public int getkN() { From 8044120cdb2172abc5df7af01264f6af6132f9a0 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 31 Mar 2021 16:26:05 -0700 Subject: [PATCH 072/379] Use `HEAD-SNAPSHOT` versions for `g-j-f` development and update release instructions to push tagged commits with release versions, instead of committing them to master, as we're doing for other projects. PiperOrigin-RevId: 366140430 --- core/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index e2d015316..faa94d627 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -22,7 +22,7 @@ com.google.googlejavaformat google-java-format-parent - 1.10-SNAPSHOT + HEAD-SNAPSHOT google-java-format diff --git a/pom.xml b/pom.xml index 42f5f86f5..396d7c0f9 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ com.google.googlejavaformat google-java-format-parent pom - 1.10-SNAPSHOT + HEAD-SNAPSHOT core From d8fd4cf0351eb4284e6d6eafaca9a8994c99d7f8 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 1 Apr 2021 15:03:53 -0700 Subject: [PATCH 073/379] Rev version numbers in README PiperOrigin-RevId: 366338635 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6f7d5c654..5645e27bc 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and run it with: ``` -java -jar /path/to/google-java-format-1.9-all-deps.jar [files...] +java -jar /path/to/google-java-format-1.10-all-deps.jar [files...] ``` The formatter can act on whole files, on limited lines (`--lines`), on specific @@ -98,7 +98,7 @@ configuration. com.google.googlejavaformat google-java-format - 1.9 + 1.10 ``` @@ -106,7 +106,7 @@ configuration. ```groovy dependencies { - compile 'com.google.googlejavaformat:google-java-format:1.9' + compile 'com.google.googlejavaformat:google-java-format:1.10' } ``` From 7b74047c8f721cd91d1c09f29d3a42ec8ef2acca Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 2 Apr 2021 12:25:11 -0700 Subject: [PATCH 074/379] Fix version numbers and add a note about JDK 16 flags. fixes https://github.com/google/google-java-format/issues/581 PiperOrigin-RevId: 366491372 --- README.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5645e27bc..5bbf5e5a1 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and run it with: ``` -java -jar /path/to/google-java-format-1.10-all-deps.jar [files...] +java -jar /path/to/google-java-format-1.10.0-all-deps.jar [files...] ``` The formatter can act on whole files, on limited lines (`--lines`), on specific @@ -27,6 +27,21 @@ To reformat changed lines in a specific patch, use formatting. This is a deliberate design decision to unify our code formatting on a single format.* +#### JDK 16 + +The following flags are required when running on JDK 16, due to +[JEP 396: Strongly Encapsulate JDK Internals by Default](https://openjdk.java.net/jeps/396): + +``` +java \ + --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ + --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ + -jar google-java-format-1.10.0-all-deps.jar [files...] +``` + ### IntelliJ, Android Studio, and other JetBrains IDEs A @@ -98,7 +113,7 @@ configuration. com.google.googlejavaformat google-java-format - 1.10 + 1.10.0 ``` @@ -106,7 +121,7 @@ configuration. ```groovy dependencies { - compile 'com.google.googlejavaformat:google-java-format:1.10' + compile 'com.google.googlejavaformat:google-java-format:1.10.0' } ``` From 8a3b882f2cf29becc3eeb2c0839b09bcb627bea0 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Tue, 6 Apr 2021 10:32:11 -0700 Subject: [PATCH 075/379] Update the IntelliJ plugin to gjf 1.10.0. Also, compile against 2021.1, which just adds wildcards to a few `Collection` parameters. And mark the plugin as requiring a restart. Probably I need to fix up `GoogleJavaFormatInstaller` to make it work without restarting, but I'm not going to investigate that right now. PiperOrigin-RevId: 367035081 --- idea_plugin/build.gradle | 8 ++++---- idea_plugin/resources/META-INF/plugin.xml | 4 +++- .../intellij/CodeStyleManagerDecorator.java | 4 ++-- .../google/googlejavaformat/intellij/FormatterUtil.java | 4 ++-- .../intellij/GoogleJavaFormatCodeStyleManager.java | 8 ++++---- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 6ec1c210d..3d807af01 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "0.4.22" + id "org.jetbrains.intellij" version "0.7.2" } repositories { @@ -23,7 +23,7 @@ repositories { } ext { - googleJavaFormatVersion = '1.9' + googleJavaFormatVersion = '1.10.0' } apply plugin: 'org.jetbrains.intellij' @@ -31,13 +31,13 @@ apply plugin: 'java' intellij { pluginName = "google-java-format" - version = "2020.2.2" + version = "211.6693.65-EAP-SNAPSHOT" } patchPluginXml { pluginDescription = "Formats source code using the google-java-format tool. This version of " + "the plugin uses version ${googleJavaFormatVersion} of the tool." - version = "${googleJavaFormatVersion}.0.0" + version = "${googleJavaFormatVersion}.0" sinceBuild = '201' untilBuild = '' } diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index 5996dba68..9b75eda40 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -14,7 +14,7 @@ limitations under the License. --> - + google-java-format google-java-format @@ -28,6 +28,8 @@ +
1.10.0.0
+
Updated to use google-java-format 1.10.
1.9.0.0
Updated to use google-java-format 1.9.
1.8.0.1
diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java index c70ba1751..fc335ad63 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java @@ -89,7 +89,7 @@ public void reformatText(PsiFile file, int startOffset, int endOffset) } @Override - public void reformatText(PsiFile file, Collection ranges) + public void reformatText(PsiFile file, Collection ranges) throws IncorrectOperationException { delegate.reformatText(file, ranges); } @@ -101,7 +101,7 @@ public void reformatTextWithContext(PsiFile psiFile, ChangedRangesInfo changedRa } @Override - public void reformatTextWithContext(PsiFile file, Collection ranges) + public void reformatTextWithContext(PsiFile file, Collection ranges) throws IncorrectOperationException { delegate.reformatTextWithContext(file, ranges); } diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java b/idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java index b6e21f78b..9939bbade 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java @@ -33,7 +33,7 @@ final class FormatterUtil { private FormatterUtil() {} static Map getReplacements( - Formatter formatter, String text, Collection ranges) { + Formatter formatter, String text, Collection ranges) { try { ImmutableMap.Builder replacements = ImmutableMap.builder(); formatter @@ -49,7 +49,7 @@ static Map getReplacements( } } - private static Collection> toRanges(Collection textRanges) { + private static Collection> toRanges(Collection textRanges) { return textRanges .stream() .map(textRange -> Range.closedOpen(textRange.getStartOffset(), textRange.getEndOffset())) diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java index 73e981384..be0eac4a2 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java @@ -62,7 +62,7 @@ public void reformatText(PsiFile file, int startOffset, int endOffset) } @Override - public void reformatText(PsiFile file, Collection ranges) + public void reformatText(PsiFile file, Collection ranges) throws IncorrectOperationException { if (overrideFormatterForFile(file)) { formatInternal(file, ranges); @@ -78,7 +78,7 @@ public void reformatTextWithContext(PsiFile file, ChangedRangesInfo changedRange } @Override - public void reformatTextWithContext(PsiFile file, Collection ranges) { + public void reformatTextWithContext(PsiFile file, Collection ranges) { if (overrideFormatterForFile(file)) { formatInternal(file, ranges); } else { @@ -107,7 +107,7 @@ private boolean overrideFormatterForFile(PsiFile file) { && GoogleJavaFormatSettings.getInstance(getProject()).isEnabled(); } - private void formatInternal(PsiFile file, Collection ranges) { + private void formatInternal(PsiFile file, Collection ranges) { ApplicationManager.getApplication().assertWriteAccessAllowed(); PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject()); documentManager.commitAllDocuments(); @@ -133,7 +133,7 @@ private void formatInternal(PsiFile file, Collection ranges) { *

Overriding methods will need to modify the document with the result of the external * formatter (usually using {@link #performReplacements(Document, Map)}. */ - private void format(Document document, Collection ranges) { + private void format(Document document, Collection ranges) { Style style = GoogleJavaFormatSettings.getInstance(getProject()).getStyle(); Formatter formatter = new Formatter(JavaFormatterOptions.builder().style(style).build()); performReplacements( From 5defb58fca4bc29b73d33a8aaae1d65e02a4591d Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Wed, 7 Apr 2021 14:50:49 -0700 Subject: [PATCH 076/379] Fix the HTML markup in the release notes. PiperOrigin-RevId: 367302861 --- idea_plugin/resources/META-INF/plugin.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index 9b75eda40..b089ad603 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -29,13 +29,13 @@

1.10.0.0
-
Updated to use google-java-format 1.10.
+
Updated to use google-java-format 1.10.
1.9.0.0
-
Updated to use google-java-format 1.9.
+
Updated to use google-java-format 1.9.
1.8.0.1
-
Fixed support for 2020.2 IDEs.
+
Fixed support for 2020.2 IDEs.
1.8.0.0
-
Updated to use google-java-format 1.8.
+
Updated to use google-java-format 1.8.
1.7.0.5
Added a version for 2020.1+ IDEs.
1.7.0.4
From 2396d08437672d3c1c79093d1ffd039b7be4fd34 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 12 Apr 2021 16:51:14 -0700 Subject: [PATCH 077/379] Update google-java-format CI JDK 16 is now released, so mark it non-experimental and add a build for JDK 17-EA. Also add a JDK 14 build back, to prevent regressions in some Java >= 14 features that are handled differently between 14 and 16. PiperOrigin-RevId: 368111853 --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5fced4bd..6e73bdb0e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,19 +29,19 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest ] - java: [ 15, 11 ] + java: [ 16, 14, 11 ] experimental: [ false ] include: # Only test on macos and windows with a single recent JDK to avoid a # combinatorial explosion of test configurations. - os: macos-latest - java: 15 + java: 16 experimental: false - os: windows-latest - java: 15 + java: 16 experimental: false - os: ubuntu-latest - java: 16-ea + java: 17-ea experimental: true runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} From fe5ac46e6741ae66fea51ac892f20d7a2bdbac79 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 12 Apr 2021 17:22:50 -0700 Subject: [PATCH 078/379] Handle `final` variables in `instanceof` patterns Fixes https://github.com/google/google-java-format/issues/588 PiperOrigin-RevId: 368117115 --- .../java/java14/Java14InputAstVisitor.java | 11 ++++++++--- .../java/FormatterIntegrationTest.java | 7 ++++++- .../google/googlejavaformat/java/testdata/I588.input | 8 ++++++++ .../google/googlejavaformat/java/testdata/I588.output | 8 ++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I588.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I588.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index 2a90b939d..a9273ce7b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -27,6 +27,7 @@ import com.sun.source.tree.ClassTree; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.InstanceOfTree; +import com.sun.source.tree.ModifiersTree; import com.sun.source.tree.SwitchExpressionTree; import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; @@ -56,12 +57,13 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { try { VariableTree variableTree = (VariableTree) BindingPatternTree.class.getMethod("getVariable").invoke(node); - visitBindingPattern(variableTree.getType(), variableTree.getName()); + visitBindingPattern( + variableTree.getModifiers(), variableTree.getType(), variableTree.getName()); } catch (ReflectiveOperationException e1) { try { Tree type = (Tree) BindingPatternTree.class.getMethod("getType").invoke(node); Name name = (Name) BindingPatternTree.class.getMethod("getName").invoke(node); - visitBindingPattern(type, name); + visitBindingPattern(/* modifiers= */ null, type, name); } catch (ReflectiveOperationException e2) { e2.addSuppressed(e1); throw new LinkageError(e2.getMessage(), e2); @@ -70,7 +72,10 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { return null; } - private void visitBindingPattern(Tree type, Name name) { + private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) { + if (modifiers != null) { + builder.addAll(visitModifiers(modifiers, Direction.HORIZONTAL, Optional.empty())); + } scan(type, null); builder.breakOp(" "); visit(name); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index fdcf6f8a8..39f31e484 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -50,6 +50,8 @@ public class FormatterIntegrationTest { private static final ImmutableSet JAVA14_TESTS = ImmutableSet.of("I477", "Records", "RSLs", "Var", "ExpressionSwitch"); + private static final ImmutableSet JAVA16_TESTS = ImmutableSet.of("I588"); + @Parameters(name = "{index}: {0}") public static Iterable data() throws IOException { Path testDataPath = Paths.get("com/google/googlejavaformat/java/testdata"); @@ -76,7 +78,7 @@ public static Iterable data() throws IOException { case "output": outputs.put(baseName, contents); break; - default: + default: // fall out } } } @@ -90,6 +92,9 @@ public static Iterable data() throws IOException { if (JAVA14_TESTS.contains(fileName) && getMajor() < 14) { continue; } + if (JAVA16_TESTS.contains(fileName) && getMajor() < 16) { + continue; + } testInputs.add(new Object[] {fileName, input, expectedOutput}); } return testInputs; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I588.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I588.input new file mode 100644 index 000000000..9c8f992ea --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I588.input @@ -0,0 +1,8 @@ +class T { + int f(Object x) { + if (x instanceof final Integer i) { + return i; + } + return -1; + } +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I588.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I588.output new file mode 100644 index 000000000..37ff2f50d --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I588.output @@ -0,0 +1,8 @@ +class T { + int f(Object x) { + if (x instanceof final Integer i) { + return i; + } + return -1; + } +} From 5104d0b27888f3bfab7113f5606374cda5632102 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 12 Apr 2021 18:14:28 -0700 Subject: [PATCH 079/379] Fix handling of annotations in compact record constructors Fixes https://github.com/google/google-java-format/issues/574 PiperOrigin-RevId: 368124032 --- .../java/java14/Java14InputAstVisitor.java | 15 +-------------- .../java/FormatterIntegrationTest.java | 2 +- .../googlejavaformat/java/testdata/I574.input | 6 ++++++ .../googlejavaformat/java/testdata/I574.output | 6 ++++++ 4 files changed, 14 insertions(+), 15 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I574.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I574.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index a9273ce7b..3517c3511 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -15,7 +15,6 @@ package com.google.googlejavaformat.java.java14; import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.MoreCollectors.toOptional; import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; @@ -34,7 +33,6 @@ import com.sun.source.tree.YieldTree; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeInfo; import java.util.List; @@ -141,10 +139,7 @@ public void visitRecordDeclaration(ClassTree node) { if (!node.getTypeParameters().isEmpty()) { typeParametersRest(node.getTypeParameters(), hasSuperInterfaceTypes ? plusFour : ZERO); } - ImmutableList parameters = - compactRecordConstructor(node) - .map(m -> ImmutableList.copyOf(m.getParameters())) - .orElseGet(() -> recordVariables(node)); + ImmutableList parameters = recordVariables(node); token("("); if (!parameters.isEmpty()) { // Break before args. @@ -183,14 +178,6 @@ public void visitRecordDeclaration(ClassTree node) { dropEmptyDeclarations(); } - private static Optional compactRecordConstructor(ClassTree node) { - return node.getMembers().stream() - .filter(JCMethodDecl.class::isInstance) - .map(JCMethodDecl.class::cast) - .filter(m -> (m.mods.flags & COMPACT_RECORD_CONSTRUCTOR) == COMPACT_RECORD_CONSTRUCTOR) - .collect(toOptional()); - } - private static ImmutableList recordVariables(ClassTree node) { return node.getMembers().stream() .filter(JCVariableDecl.class::isInstance) diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 39f31e484..b6549f4a8 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -48,7 +48,7 @@ public class FormatterIntegrationTest { private static final ImmutableSet JAVA14_TESTS = - ImmutableSet.of("I477", "Records", "RSLs", "Var", "ExpressionSwitch"); + ImmutableSet.of("I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574"); private static final ImmutableSet JAVA16_TESTS = ImmutableSet.of("I588"); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I574.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I574.input new file mode 100644 index 000000000..27d23d040 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I574.input @@ -0,0 +1,6 @@ +public record Record(@NotNull Object o) { + + public Record { + this.o = o; + } +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I574.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I574.output new file mode 100644 index 000000000..b0deb2d10 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I574.output @@ -0,0 +1,6 @@ +public record Record(@NotNull Object o) { + + public Record { + this.o = o; + } +} From 32b63aa2e4675cb03fb853ea84cbc37792e442a4 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 15 Apr 2021 14:41:27 -0700 Subject: [PATCH 080/379] Fix a crash in `instanceof` pattern handling Fixes https://github.com/google/google-java-format PiperOrigin-RevId: 368720966 --- .../java/java14/Java14InputAstVisitor.java | 2 +- .../googlejavaformat/java/FormatterIntegrationTest.java | 2 +- .../com/google/googlejavaformat/java/testdata/I594.input | 7 +++++++ .../com/google/googlejavaformat/java/testdata/I594.output | 7 +++++++ 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I594.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I594.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index 3517c3511..8293fd4b0 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -60,7 +60,7 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { } catch (ReflectiveOperationException e1) { try { Tree type = (Tree) BindingPatternTree.class.getMethod("getType").invoke(node); - Name name = (Name) BindingPatternTree.class.getMethod("getName").invoke(node); + Name name = (Name) BindingPatternTree.class.getMethod("getBinding").invoke(node); visitBindingPattern(/* modifiers= */ null, type, name); } catch (ReflectiveOperationException e2) { e2.addSuppressed(e1); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index b6549f4a8..31d59f171 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -48,7 +48,7 @@ public class FormatterIntegrationTest { private static final ImmutableSet JAVA14_TESTS = - ImmutableSet.of("I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574"); + ImmutableSet.of("I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574", "I594"); private static final ImmutableSet JAVA16_TESTS = ImmutableSet.of("I588"); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I594.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I594.input new file mode 100644 index 000000000..98f667e39 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I594.input @@ -0,0 +1,7 @@ +public class I594 { + public void thisIsNotFormattedCorrectly(Object something){ + if(something instanceof String somethingAsString){ + return; + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I594.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I594.output new file mode 100644 index 000000000..7c519a2d9 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I594.output @@ -0,0 +1,7 @@ +public class I594 { + public void thisIsNotFormattedCorrectly(Object something) { + if (something instanceof String somethingAsString) { + return; + } + } +} From 72672b071b0d8c92bbaa7ced49a11418565a4156 Mon Sep 17 00:00:00 2001 From: Fabian Windheuser Date: Tue, 20 Apr 2021 13:54:15 -0700 Subject: [PATCH 081/379] Wrap multiple values in switch expression case Closes https://github.com/google/google-java-format/issues/540 * Wrap multiple values covered in a switch expression case if they exceed the max line length. ```diff switch (e) { - case SOME_RATHER_LONG_NAME_1, SOME_RATHER_LONG_NAME_2, SOME_RATHER_LONG_NAME_3 -> {} + case SOME_RATHER_LONG_NAME_1, + SOME_RATHER_LONG_NAME_2, + SOME_RATHER_LONG_NAME_3 -> {} } ``` * Also collapse empty case blocks in switch expressions. ```diff switch (e) { - case CASE_A -> { - } + case CASE_A -> {} } ``` Fixes #558 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/558 from fawind:fw/wrap-case-arguments ff60675a0c7780375b7c6e25eeca4ffecaa6bfb2 PiperOrigin-RevId: 369513714 --- .../java/JavaInputAstVisitor.java | 8 ++++---- .../java/java14/Java14InputAstVisitor.java | 16 ++++++++++++++-- .../java/testdata/ExpressionSwitch.input | 13 +++++++++++++ .../java/testdata/ExpressionSwitch.output | 19 +++++++++++++++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 89f33fa06..89ec1f86e 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -177,7 +177,7 @@ boolean isYes() { } /** Whether to collapse empty blocks. */ - enum CollapseEmptyOrNot { + protected enum CollapseEmptyOrNot { YES, NO; @@ -191,7 +191,7 @@ boolean isYes() { } /** Whether to allow leading blank lines in blocks. */ - enum AllowLeadingBlankLine { + protected enum AllowLeadingBlankLine { YES, NO; @@ -201,7 +201,7 @@ static AllowLeadingBlankLine valueOf(boolean b) { } /** Whether to allow trailing blank lines in blocks. */ - enum AllowTrailingBlankLine { + protected enum AllowTrailingBlankLine { YES, NO; @@ -2097,7 +2097,7 @@ void visitAnnotations( } /** Helper method for blocks. */ - private void visitBlock( + protected void visitBlock( BlockTree node, CollapseEmptyOrNot collapseEmptyOrNot, AllowLeadingBlankLine allowLeadingBlankLine, diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index 8293fd4b0..96312c2de 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -22,6 +22,7 @@ import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.java.JavaInputAstVisitor; import com.sun.source.tree.BindingPatternTree; +import com.sun.source.tree.BlockTree; import com.sun.source.tree.CaseTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.ExpressionTree; @@ -214,16 +215,18 @@ public Void visitCase(CaseTree node, Void unused) { token("default", plusTwo); } else { token("case", plusTwo); + builder.open(plusFour); builder.space(); boolean first = true; for (ExpressionTree expression : node.getExpressions()) { if (!first) { token(","); - builder.space(); + builder.breakOp(" "); } scan(expression, null); first = false; } + builder.close(); } switch (node.getCaseKind()) { case STATEMENT: @@ -237,7 +240,16 @@ public Void visitCase(CaseTree node, Void unused) { token("-"); token(">"); builder.space(); - scan(node.getBody(), null); + if (node.getBody().getKind() == Tree.Kind.BLOCK) { + // Explicit call with {@link CollapseEmptyOrNot.YES} to handle empty case blocks. + visitBlock( + (BlockTree) node.getBody(), + CollapseEmptyOrNot.YES, + AllowLeadingBlankLine.NO, + AllowTrailingBlankLine.NO); + } else { + scan(node.getBody(), null); + } builder.guessToken(";"); break; default: diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input index 1e4db164d..5590f742a 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.input @@ -25,4 +25,17 @@ class ExpressionSwitch { default -> System.out.println("default"); } } + + String breakLongCaseArgs(MyEnum e) { + return switch (e) { + case SOME_RATHER_LONG_NAME_1, SOME_RATHER_LONG_NAME_2, SOME_RATHER_LONG_NAME_3, SOME_RATHER_LONG_NAME_4, SOME_RATHER_LONG_NAME_5, SOME_RATHER_LONG_NAME_6, SOME_RATHER_LONG_NAME_7 -> {} + case SOME_RATHER_LONG_NAME_8 -> {} + }; + } + + String dontBreakShortCaseArgs(MyEnum e) { + return switch (e) { + case CASE_A, CASE_B -> {} + }; + } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output index 6458aa09d..00ae892d4 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ExpressionSwitch.output @@ -31,4 +31,23 @@ class ExpressionSwitch { default -> System.out.println("default"); } } + + String breakLongCaseArgs(MyEnum e) { + return switch (e) { + case SOME_RATHER_LONG_NAME_1, + SOME_RATHER_LONG_NAME_2, + SOME_RATHER_LONG_NAME_3, + SOME_RATHER_LONG_NAME_4, + SOME_RATHER_LONG_NAME_5, + SOME_RATHER_LONG_NAME_6, + SOME_RATHER_LONG_NAME_7 -> {} + case SOME_RATHER_LONG_NAME_8 -> {} + }; + } + + String dontBreakShortCaseArgs(MyEnum e) { + return switch (e) { + case CASE_A, CASE_B -> {} + }; + } } From 84997ac0b680b66d0f1c76704557e3ba207f0a90 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 12 May 2021 13:50:36 -0700 Subject: [PATCH 082/379] Only format changed regions in 'before commit' mode Related: https://github.com/facebookincubator/ktfmt/issues/228 Follow-up to https://github.com/google/google-java-format/commit/69ba30fd9242eb52446edf18655d190e653348b6 PiperOrigin-RevId: 373443663 --- .../intellij/GoogleJavaFormatCodeStyleManager.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java index be0eac4a2..550d0a93c 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java @@ -34,8 +34,9 @@ import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.CheckUtil; import com.intellij.util.IncorrectOperationException; +import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; @@ -72,9 +73,14 @@ public void reformatText(PsiFile file, Collection ranges) } @Override - public void reformatTextWithContext(PsiFile file, ChangedRangesInfo changedRangesInfo) + public void reformatTextWithContext(PsiFile file, ChangedRangesInfo info) throws IncorrectOperationException { - reformatTextWithContext(file, Collections.singletonList(file.getTextRange())); + List ranges = new ArrayList<>(); + if (info.insertedRanges != null) { + ranges.addAll(info.insertedRanges); + } + ranges.addAll(info.allChangedRanges); + reformatTextWithContext(file, ranges); } @Override From dd405014fe16a1317cac26f3833d7b784bbcabe5 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 14 May 2021 16:36:17 -0700 Subject: [PATCH 083/379] Update Error Prone and maven versions PiperOrigin-RevId: 373889180 --- pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 396d7c0f9..523806946 100644 --- a/pom.xml +++ b/pom.xml @@ -98,6 +98,7 @@ 30.0-jre 1.0 3.6.1 + 2.7.1 @@ -118,7 +119,7 @@ com.google.errorprone error_prone_annotations - 2.5.1 + ${errorprone.version} @@ -209,7 +210,7 @@ com.google.errorprone error_prone_core - 2.5.1 + ${errorprone.version} From 0da99c5363afd39e2c2184b47c467ab67332d755 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Mon, 17 May 2021 07:17:22 -0700 Subject: [PATCH 084/379] Remove the IDEA module file. With any recent version of IntelliJ, it's better to just let the Gradle integration handle everything. PiperOrigin-RevId: 374189998 --- idea_plugin/google-java-format.iml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 idea_plugin/google-java-format.iml diff --git a/idea_plugin/google-java-format.iml b/idea_plugin/google-java-format.iml deleted file mode 100644 index 568c04fb2..000000000 --- a/idea_plugin/google-java-format.iml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - From fbade77ff2d04007983685d91870439631c9c115 Mon Sep 17 00:00:00 2001 From: Cameron Samak Date: Tue, 25 May 2021 07:46:51 -0700 Subject: [PATCH 085/379] Simplify characterRangeToTokenRange by taking a Range instead of an offset + length. It had some extra logic (e.g. logic to check length < 0, which was already impossible since ranges were already created). Leaving the error message the same since the cli options include "offset" and "length" PiperOrigin-RevId: 375702715 --- .../googlejavaformat/java/JavaInput.java | 42 ++++++++----------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index d07d003ef..e671ad012 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -557,33 +557,28 @@ private static boolean isParamComment(Tok tok) { } /** - * Convert from an offset and length flag pair to a token range. + * Convert from a character range to a token range. * - * @param offset the {@code 0}-based offset in characters - * @param length the length in characters + * @param characterRange the {@code 0}-based {@link Range} of characters * @return the {@code 0}-based {@link Range} of tokens - * @throws FormatterException if offset + length is outside the file + * @throws FormatterException if the upper endpoint of the range is outside the file */ - Range characterRangeToTokenRange(int offset, int length) throws FormatterException { - int requiredLength = offset + length; - if (requiredLength > text.length()) { + Range characterRangeToTokenRange(Range characterRange) + throws FormatterException { + if (characterRange.upperEndpoint() > text.length()) { throw new FormatterException( String.format( "error: invalid length %d, offset + length (%d) is outside the file", - length, requiredLength)); - } - if (length < 0) { - return EMPTY_RANGE; - } - if (length == 0) { - // 0 stands for "format the line under the cursor" - length = 1; - } + characterRange.upperEndpoint() - characterRange.lowerEndpoint(), + characterRange.upperEndpoint())); + } + // empty range stands for "format the line under the cursor" + Range nonEmptyRange = + characterRange.isEmpty() + ? Range.closedOpen(characterRange.lowerEndpoint(), characterRange.lowerEndpoint() + 1) + : characterRange; ImmutableCollection enclosed = - getPositionTokenMap() - .subRangeMap(Range.closedOpen(offset, offset + length)) - .asMapOfRanges() - .values(); + getPositionTokenMap().subRangeMap(nonEmptyRange).asMapOfRanges().values(); if (enclosed.isEmpty()) { return EMPTY_RANGE; } @@ -664,12 +659,9 @@ public void setCompilationUnit(JCCompilationUnit unit) { public RangeSet characterRangesToTokenRanges(Collection> characterRanges) throws FormatterException { RangeSet tokenRangeSet = TreeRangeSet.create(); - for (Range characterRange0 : characterRanges) { - Range characterRange = characterRange0.canonical(DiscreteDomain.integers()); + for (Range characterRange : characterRanges) { tokenRangeSet.add( - characterRangeToTokenRange( - characterRange.lowerEndpoint(), - characterRange.upperEndpoint() - characterRange.lowerEndpoint())); + characterRangeToTokenRange(characterRange.canonical(DiscreteDomain.integers()))); } return tokenRangeSet; } From dc55a82a40e74782a6745f8c1da23df36e8da824 Mon Sep 17 00:00:00 2001 From: Matthew Weigel Date: Wed, 9 Jun 2021 06:17:20 -0700 Subject: [PATCH 086/379] Emacs integration: correct signature for executable custom variable predicate. Per https://www.gnu.org/software/emacs/manual/html_node/elisp/Type-Keywords.html the predicate for :match "should be a function that accepts two arguments...." Without this fix, when you try to customize google-java-format-executable you see a very confused Easy Customization buffer and the error message "widget-apply: Invalid function: #'file-executable-p" Fixes #600 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/600 from bsdcat:main a0b2656900d3e477e3cb1867858525795fbf78c1 PiperOrigin-RevId: 378389716 --- core/src/main/scripts/google-java-format.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scripts/google-java-format.el b/core/src/main/scripts/google-java-format.el index f9e8d2a34..f269ab361 100644 --- a/core/src/main/scripts/google-java-format.el +++ b/core/src/main/scripts/google-java-format.el @@ -46,7 +46,7 @@ A string containing the name or the full path of the executable." :group 'google-java-format - :type '(file :must-match t :match #'file-executable-p) + :type '(file :must-match t :match (lambda (widget file) (file-executable-p file))) :risky t) ;;;###autoload From 26adad01f05fd42fd49ba24428f5229ea42b4610 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 9 Jun 2021 18:13:05 -0700 Subject: [PATCH 087/379] Fix formatting of module trees after https://bugs.openjdk.java.net/browse/JDK-8255464 PiperOrigin-RevId: 378545281 --- .../java/JavaInputAstVisitor.java | 3 +++ .../java/java14/Java14InputAstVisitor.java | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 89ec1f86e..e22dae5d5 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -376,11 +376,14 @@ public Void visitCompilationUnit(CompilationUnitTree node, Void unused) { first = false; dropEmptyDeclarations(); } + handleModule(first, node); // set a partial format marker at EOF to make sure we can format the entire file markForPartialFormat(); return null; } + protected void handleModule(boolean first, CompilationUnitTree node) {} + /** Skips over extra semi-colons at the top-level, or in a class member declaration lists. */ protected void dropEmptyDeclarations() { if (builder.peekToken().equals(Optional.of(";"))) { diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index 96312c2de..eff127ede 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -20,14 +20,17 @@ import com.google.common.collect.ImmutableList; import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpsBuilder; +import com.google.googlejavaformat.OpsBuilder.BlankLineWanted; import com.google.googlejavaformat.java.JavaInputAstVisitor; import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.BlockTree; import com.sun.source.tree.CaseTree; import com.sun.source.tree.ClassTree; +import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.InstanceOfTree; import com.sun.source.tree.ModifiersTree; +import com.sun.source.tree.ModuleTree; import com.sun.source.tree.SwitchExpressionTree; import com.sun.source.tree.Tree; import com.sun.source.tree.VariableTree; @@ -50,6 +53,24 @@ public Java14InputAstVisitor(OpsBuilder builder, int indentMultiplier) { super(builder, indentMultiplier); } + @Override + protected void handleModule(boolean first, CompilationUnitTree node) { + try { + ModuleTree module = + (ModuleTree) CompilationUnitTree.class.getMethod("getModule").invoke(node); + if (module != null) { + if (!first) { + builder.blankLineWanted(BlankLineWanted.YES); + } + markForPartialFormat(); + visitModule(module, null); + builder.forcedBreak(); + } + } catch (ReflectiveOperationException e) { + // Java < 17, see https://bugs.openjdk.java.net/browse/JDK-8255464 + } + } + @Override public Void visitBindingPattern(BindingPatternTree node, Void unused) { sync(node); From 5c69d8ea2ede974765f3d0815258a88fbf9dcce5 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 15 Jun 2021 18:24:42 -0700 Subject: [PATCH 088/379] Stop passing --illegal-access= to tests since it's going away in 17 PiperOrigin-RevId: 379619714 --- pom.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 523806946..fca4cc766 100644 --- a/pom.xml +++ b/pom.xml @@ -260,7 +260,19 @@ 2.18 - -Xmx1024m --illegal-access=permit + + -Xmx1024m + --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + --add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED + --add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED +
From cad842ca56af042f9f11d0906264d3bc7a866174 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 21 Jun 2021 17:16:23 -0700 Subject: [PATCH 089/379] Remove obsolete parent per https://github.com/sonatype/oss-parents PiperOrigin-RevId: 380698526 --- pom.xml | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index fca4cc766..33af14e8a 100644 --- a/pom.xml +++ b/pom.xml @@ -19,11 +19,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - - org.sonatype.oss - oss-parent - 7 - com.google.googlejavaformat google-java-format-parent @@ -99,6 +94,8 @@ 1.0 3.6.1 2.7.1 + 3.1.0 + 3.2.1 @@ -277,4 +274,67 @@
+ + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + + sonatype-nexus-staging + Nexus Release Repository + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + sonatype-oss-release + + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + + From 135f5e9943af0c1aff41661e568366429d9cf725 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Mon, 28 Jun 2021 08:15:16 -0700 Subject: [PATCH 090/379] Fix typo in comment for Input.Tok#isSlashStarComment. It appears the comment may have been copied from Input.Tok#isSlashSlashComment. PiperOrigin-RevId: 381866447 --- core/src/main/java/com/google/googlejavaformat/Input.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Input.java b/core/src/main/java/com/google/googlejavaformat/Input.java index fb71e047c..66a392190 100644 --- a/core/src/main/java/com/google/googlejavaformat/Input.java +++ b/core/src/main/java/com/google/googlejavaformat/Input.java @@ -63,7 +63,7 @@ public interface Tok { /** Is the {@code Tok} a "//" comment? */ boolean isSlashSlashComment(); - /** Is the {@code Tok} a "//" comment? */ + /** Is the {@code Tok} a "/*" comment? */ boolean isSlashStarComment(); /** Is the {@code Tok} a javadoc comment? */ From 89b06cb3cbb87fc51f87f2197d3167535181cec1 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 14 Jul 2021 11:52:04 -0700 Subject: [PATCH 091/379] Update to setup-java v2, and use adopt builds https://github.com/actions/setup-java/blob/main/docs/switching-to-v2.md PiperOrigin-RevId: 384750269 --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e73bdb0e..cfd9cf37b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,9 +60,10 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - name: 'Set up JDK ${{ matrix.java }}' - uses: actions/setup-java@v1 + uses: actions/setup-java@v2 with: java-version: ${{ matrix.java }} + distribution: 'adopt' - name: 'Install' shell: bash run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V @@ -86,9 +87,10 @@ jobs: restore-keys: | ${{ runner.os }}-maven- - name: 'Set up JDK 15' - uses: actions/setup-java@v1 + uses: actions/setup-java@v2 with: java-version: 15 + distribution: 'adopt' server-id: sonatype-nexus-snapshots server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD From 165c106aeac31a0bac3698195383e30e0ad3f3fd Mon Sep 17 00:00:00 2001 From: Michael Genereux Date: Tue, 20 Jul 2021 10:30:08 -0700 Subject: [PATCH 092/379] Change deprecated Gradle command "compile" is now "compileOnly" in Gradle 7 Fixes #627 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/627 from mgenereu:patch-1 6826440d5848bc1fbc2927fec5d0345ba0a021a0 PiperOrigin-RevId: 385817949 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5bbf5e5a1..41ab0806f 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ configuration. ```groovy dependencies { - compile 'com.google.googlejavaformat:google-java-format:1.10.0' + implementation 'com.google.googlejavaformat:google-java-format:1.10.0' } ``` From bf5ef1c5de94fd623025e24b99ceadf18e83d8a5 Mon Sep 17 00:00:00 2001 From: Dmytro Sych Date: Fri, 23 Jul 2021 16:34:11 -0700 Subject: [PATCH 093/379] Allowing to turn off java doc formatting `google-java-format-diff.py` is missing a flag to turn off java docs formatting, which is present on the main jar. This pr introduces this flag: `--skip-docs` Fixes #571 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/571 from dsych:missing-docs-switch 9657b75195c1053ae93c022d34bc35b651d412aa PiperOrigin-RevId: 386554591 --- scripts/google-java-format-diff.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/google-java-format-diff.py b/scripts/google-java-format-diff.py index 1abd037d3..63685aac3 100755 --- a/scripts/google-java-format-diff.py +++ b/scripts/google-java-format-diff.py @@ -59,6 +59,11 @@ def main(): help='do not fix the import order') parser.add_argument('--skip-removing-unused-imports', action='store_true', help='do not remove ununsed imports') + parser.add_argument( + '--skip-javadoc-formatting', + action='store_true', + default=False, + help='do not reformat javadoc') parser.add_argument('-b', '--binary', help='path to google-java-format binary') parser.add_argument('--google-java-format-jar', metavar='ABSOLUTE_PATH', default=None, help='use a custom google-java-format jar') @@ -116,6 +121,8 @@ def main(): command.append('--skip-sorting-imports') if args.skip_removing_unused_imports: command.append('--skip-removing-unused-imports') + if args.skip_javadoc_formatting: + command.append('--skip-javadoc-formatting') command.extend(lines) command.append(filename) p = subprocess.Popen(command, stdout=subprocess.PIPE, From cc8b96ff54df4b2376eb3118537769ee8aa2f041 Mon Sep 17 00:00:00 2001 From: Nikolai Weibull Date: Tue, 27 Jul 2021 11:46:17 -0700 Subject: [PATCH 094/379] Support sealed classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This implements support for JEP 409: Sealed Classes, see https://openjdk.java.net/jeps/409. The implementation handles the sealed and non-sealed keywords and sorts them according to their JLS order. This requires us to look at the actual text of the Tok, as there’s no TokenKind for sealed and non-sealed. The optional permits clause is handled in the same manner as the implements clause. A new private method, classDeclarationTypeList, has been added to facilitate this. This fixes #603. I implemented this in a manner that I deemed fit with the surrounding code, but if I missed something, don’t hesitate to get back to me and I’ll adjust this PR to suit. Fixes #629 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/629 from now:I603 4825e3310e00a1145304d64b4b73e9d3d03d08b3 PiperOrigin-RevId: 387160750 --- .../java/JavaInputAstVisitor.java | 51 ++++++++---- .../java/ModifierOrderer.java | 77 +++++++++---------- .../java/java14/Java14InputAstVisitor.java | 10 +++ .../java/FormatterIntegrationTest.java | 5 ++ .../googlejavaformat/java/testdata/I603.input | 16 ++++ .../java/testdata/I603.output | 13 ++++ 6 files changed, 116 insertions(+), 56 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I603.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I603.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index e22dae5d5..372f3bb59 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -1961,8 +1961,10 @@ public void visitClassDeclaration(ClassTree node) { node.getModifiers(), Direction.VERTICAL, /* declarationAnnotationBreak= */ Optional.empty()); + List permitsTypes = getPermitsClause(node); boolean hasSuperclassType = node.getExtendsClause() != null; boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); + boolean hasPermitsTypes = !permitsTypes.isEmpty(); builder.addAll(breaks); token(node.getKind() == Tree.Kind.INTERFACE ? "interface" : "class"); builder.space(); @@ -1975,7 +1977,7 @@ public void visitClassDeclaration(ClassTree node) { if (!node.getTypeParameters().isEmpty()) { typeParametersRest( node.getTypeParameters(), - hasSuperclassType || hasSuperInterfaceTypes ? plusFour : ZERO); + hasSuperclassType || hasSuperInterfaceTypes || hasPermitsTypes ? plusFour : ZERO); } if (hasSuperclassType) { builder.breakToFill(" "); @@ -1983,22 +1985,10 @@ public void visitClassDeclaration(ClassTree node) { builder.space(); scan(node.getExtendsClause(), null); } - if (hasSuperInterfaceTypes) { - builder.breakToFill(" "); - builder.open(node.getImplementsClause().size() > 1 ? plusFour : ZERO); - token(node.getKind() == Tree.Kind.INTERFACE ? "extends" : "implements"); - builder.space(); - boolean first = true; - for (Tree superInterfaceType : node.getImplementsClause()) { - if (!first) { - token(","); - builder.breakOp(" "); - } - scan(superInterfaceType, null); - first = false; - } - builder.close(); - } + classDeclarationTypeList( + node.getKind() == Tree.Kind.INTERFACE ? "extends" : "implements", + node.getImplementsClause()); + classDeclarationTypeList("permits", permitsTypes); } builder.close(); if (node.getMembers() == null) { @@ -2277,6 +2267,8 @@ boolean nextIsModifier() { case "native": case "strictfp": case "default": + case "sealed": + case "non-sealed": return true; default: return false; @@ -3549,6 +3541,31 @@ protected void addBodyDeclarations( } } + /** Gets the permits clause for the given node. This is only available in Java 15 and later. */ + protected List getPermitsClause(ClassTree node) { + return ImmutableList.of(); + } + + private void classDeclarationTypeList(String token, List types) { + if (types.isEmpty()) { + return; + } + builder.breakToFill(" "); + builder.open(types.size() > 1 ? plusFour : ZERO); + token(token); + builder.space(); + boolean first = true; + for (Tree type : types) { + if (!first) { + token(","); + builder.breakOp(" "); + } + scan(type, null); + first = false; + } + builder.close(); + } + /** * The parser expands multi-variable declarations into separate single-variable declarations. All * of the fragments in the original declaration have the same start position, so we use that as a diff --git a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java index 42eaf45f3..e14b29036 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java @@ -36,44 +36,6 @@ /** Fixes sequences of modifiers to be in JLS order. */ final class ModifierOrderer { - /** - * Returns the {@link javax.lang.model.element.Modifier} for the given token kind, or {@code - * null}. - */ - private static Modifier getModifier(TokenKind kind) { - if (kind == null) { - return null; - } - switch (kind) { - case PUBLIC: - return Modifier.PUBLIC; - case PROTECTED: - return Modifier.PROTECTED; - case PRIVATE: - return Modifier.PRIVATE; - case ABSTRACT: - return Modifier.ABSTRACT; - case STATIC: - return Modifier.STATIC; - case DEFAULT: - return Modifier.DEFAULT; - case FINAL: - return Modifier.FINAL; - case TRANSIENT: - return Modifier.TRANSIENT; - case VOLATILE: - return Modifier.VOLATILE; - case SYNCHRONIZED: - return Modifier.SYNCHRONIZED; - case NATIVE: - return Modifier.NATIVE; - case STRICTFP: - return Modifier.STRICTFP; - default: - return null; - } - } - /** Reorders all modifiers in the given text to be in JLS order. */ static JavaInput reorderModifiers(String text) throws FormatterException { return reorderModifiers( @@ -152,7 +114,44 @@ private static void addTrivia(StringBuilder replacement, ImmutableList getPermitsClause(ClassTree node) { + try { + return (List) ClassTree.class.getMethod("getPermitsClause").invoke(node); + } catch (ReflectiveOperationException e) { + // Java < 15 + return super.getPermitsClause(node); + } + } + @Override public Void visitBindingPattern(BindingPatternTree node, Void unused) { sync(node); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 31d59f171..edbb12b6e 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -50,6 +50,8 @@ public class FormatterIntegrationTest { private static final ImmutableSet JAVA14_TESTS = ImmutableSet.of("I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574", "I594"); + private static final ImmutableSet JAVA15_TESTS = ImmutableSet.of("I603"); + private static final ImmutableSet JAVA16_TESTS = ImmutableSet.of("I588"); @Parameters(name = "{index}: {0}") @@ -92,6 +94,9 @@ public static Iterable data() throws IOException { if (JAVA14_TESTS.contains(fileName) && getMajor() < 14) { continue; } + if (JAVA15_TESTS.contains(fileName) && getMajor() < 15) { + continue; + } if (JAVA16_TESTS.contains(fileName) && getMajor() < 16) { continue; } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I603.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I603.input new file mode 100644 index 000000000..6cedc5300 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I603.input @@ -0,0 +1,16 @@ +class I603 { + sealed abstract class T1 {} + + sealed class T2 extends X implements Y permits Z {} + + sealed class T3 + permits + Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx {} + + sealed class T4 + implements + Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + permits + Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + Yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy {} +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I603.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I603.output new file mode 100644 index 000000000..22153b688 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I603.output @@ -0,0 +1,13 @@ +class I603 { + abstract sealed class T1 {} + + sealed class T2 extends X implements Y permits Z {} + + sealed class T3 + permits Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx {} + + sealed class T4 + implements Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + permits Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + Yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy {} +} From 93ee8fe7363da810b643627a9fbbe04841f630b2 Mon Sep 17 00:00:00 2001 From: Tobias Bouschen Date: Thu, 29 Jul 2021 10:29:15 -0700 Subject: [PATCH 095/379] Fix Eclipse plugin build Updates the Eclipse plugin build logic. The logic is now completely separate from the main google java format build. Instead of relying on the build artifacts of the core build, the needed google-java-format and guava build artifacts used for the build are now pulled from maven. Updates google-java-format version used for the build to '1.9', the build JDK to 11, and removes old dependencies which are no longer used. Updates tycho version to 1.7.0 in order to build with JDK > 8. Updates the build guide in the README. Fixes #465 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/465 from tobous:fix-eclipse-build e80a72bcbe015c9a392eaad06ed4d60377573635 PiperOrigin-RevId: 387615841 --- core/pom.xml | 45 ----------------- eclipse_plugin/META-INF/MANIFEST.MF | 10 ++-- eclipse_plugin/README.md | 61 +++++++++++++++------- eclipse_plugin/build.properties | 5 +- eclipse_plugin/plugin.xml | 3 +- eclipse_plugin/pom.xml | 78 +++++++++++++++++++++-------- 6 files changed, 109 insertions(+), 93 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index faa94d627..74b7504ac 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -156,51 +156,6 @@ - - maven-resources-plugin - 3.0.1 - - - copy-resources - package - - copy-resources - - - ../eclipse_plugin/lib - - - target - ${project.artifactId}-${project.version}.jar - - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 2.10 - - - copy-dependencies - package - - copy-dependencies - - - ../eclipse_plugin/lib - true - true - true - org.eclipse.jdt.core - compile - provided - - - - com.google.code.maven-replacer-plugin replacer diff --git a/eclipse_plugin/META-INF/MANIFEST.MF b/eclipse_plugin/META-INF/MANIFEST.MF index 27613e9ce..fb8d1bbde 100644 --- a/eclipse_plugin/META-INF/MANIFEST.MF +++ b/eclipse_plugin/META-INF/MANIFEST.MF @@ -2,14 +2,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: google-java-format Bundle-SymbolicName: google-java-format-eclipse-plugin;singleton:=true -Bundle-Version: 1.6.0 -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-Vendor: Google +Bundle-Version: 1.9.0 +Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Bundle: org.eclipse.jdt.core;bundle-version="3.10.0", org.eclipse.jface, org.eclipse.text, org.eclipse.ui, org.eclipse.equinox.common Bundle-ClassPath: ., - lib/guava-22.0.jar, - lib/javac-shaded-9+181-r4173-1.jar, - lib/google-java-format-1.6.jar + lib/guava-28.1-jre.jar, + lib/google-java-format-1.9.jar diff --git a/eclipse_plugin/README.md b/eclipse_plugin/README.md index 332468d7e..a45b46538 100644 --- a/eclipse_plugin/README.md +++ b/eclipse_plugin/README.md @@ -1,4 +1,4 @@ -# google-java-format Eclipse Plugin +# Google Java Format Eclipse Plugin ## Enabling @@ -6,21 +6,44 @@ See https://github.com/google/google-java-format#eclipse ## Development -1) Uncomment `eclipse_plugin` in the parent `pom.xml` - -2) Run `mvn install`, which will copy the dependences of the plugin to -`eclipse_plugin/lib`. - -2) If you are using Java 9, add - - ``` - -vm - /Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home/bin/java - ``` - - to `/Applications/Eclipse.app/Contents/Eclipse/eclipse.ini`. - -3) Open the `eclipse_plugin` project in a recent Eclipse SDK build. - -4) From `File > Export` select `Plugin-in Development > Deployable plugin-ins -and fragments` and follow the wizard to export a plugin jar. +### Prerequisites + +Make sure that the `build.properties` and `META-INF/MANIFEST.MF` contain all +necessary dependencies for the build. Furthermore, make sure that the +dependencies declared in the `pom.xml` match the entries in `build.properties` +and `META-INF/MANIFEST.MF`. + +If the used google java format core version is a 'SNAPSHOT' release, the version +for the Eclipse plugin in the `pom.xml` must end in '-SNAPSHOT' as well and the +bundle version specified in `META-INF/MANIFEST.MF` must end in '.qualifier'. + +### Building the Plugin + +1) Run `mvn clean package` in the `eclipse_plugin` directory. This will first copy the dependencies +of the plugin to `eclipse_plugin/lib/` and then triggers the tycho build that uses these +dependencies (as declared in `build.properties`) for the actual Eclipse plugin build.

+If you also want to add the build artifact to the local maven repository, you can use +`mvn clean install -Dtycho.localArtifacts=ignore` instead. Note, however, that you then must use +this build command for every build with that specific version number until you clear the build +artifact (or the +[p2-local-metadata.properties](https://wiki.eclipse.org/Tycho/Target_Platform#Locally_built_artifacts)) +from your local repository. Otherwise, you might run into issues caused by the build using an +outdated build artifact created by a previous build instead of re-building the plugin. More +information on this issue is given +[in this thread](https://www.eclipse.org/lists/tycho-user/msg00952.html) and +[this bug tracker entry](https://bugs.eclipse.org/bugs/show_bug.cgi?id=355367). + +2) You can find the built plugin in +`eclipse_plugin/target/google-java-format-eclipse-plugin-.jar` + +#### Building against a local (snapshot) release of the core + +With the current build setup, the Eclipse plugin build pulls the needed build +artifacts of the google java format core specified in the property +`google-java-format.version` and copies it into the `eclipse_plugin/lib/` +directory. + +If you instead want to build against a local (snapshot) build of the core which +is not available in a maven repository (local or otherwise), you will have to +place the appropriate version into the `eclipse_plugin/lib/` directory yourself +before the build. diff --git a/eclipse_plugin/build.properties b/eclipse_plugin/build.properties index dc5ae7c7e..161a94d3d 100644 --- a/eclipse_plugin/build.properties +++ b/eclipse_plugin/build.properties @@ -3,6 +3,5 @@ output.. = target/classes bin.includes = META-INF/,\ .,\ plugin.xml,\ - lib/javac-shaded-9+181-r4173-1.jar,\ - lib/guava-22.0.jar,\ - lib/google-java-format-1.6.jar + lib/guava-28.1-jre.jar,\ + lib/google-java-format-1.9.jar diff --git a/eclipse_plugin/plugin.xml b/eclipse_plugin/plugin.xml index b832a1e21..1fdfb6e41 100644 --- a/eclipse_plugin/plugin.xml +++ b/eclipse_plugin/plugin.xml @@ -1,3 +1,5 @@ + + - diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index bb581cdb6..3c538a33c 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -14,28 +14,47 @@ ~ limitations under the License. --> - 4.0.0 - - com.google.googlejavaformat - google-java-format-parent - 1.6 - + com.google.googlejavaformat google-java-format-eclipse-plugin - 1.6.0 eclipse-plugin - google-java-format Plugin for Eclipse 4.5+ + 1.9.0 + + Google Java Format Plugin for Eclipse 4.5+ - A Java source code formatter that follows Google Java Style. + A Java source code formatter plugin for Eclipse that follows Google Java Style. - 0.26.0 + UTF-8 + + 1.7.0 + + + 1.9 + 28.1-jre + + + com.google.googlejavaformat + google-java-format + ${google-java-format.version} + jar + + + com.google.guava + guava + ${guava.version} + jar + + + mars @@ -44,16 +63,28 @@ - - - com.google.googlejavaformat - google-java-format - 1.6 - - - + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.2 + + + copy-dependencies + initialize + + copy-dependencies + + + + + lib + runtime + true + true + + org.eclipse.tycho @@ -61,7 +92,6 @@ ${tycho-version} true - org.eclipse.tycho target-platform-configuration @@ -97,7 +127,15 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 11 + 11 + + - From dfb7a238a7f694352bddccfe42d3472fdc64656f Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 29 Jul 2021 10:47:41 -0700 Subject: [PATCH 096/379] Update guava version Closes https://github.com/google/google-java-format/pull/631 PiperOrigin-RevId: 387620183 --- eclipse_plugin/META-INF/MANIFEST.MF | 2 +- eclipse_plugin/build.properties | 2 +- eclipse_plugin/pom.xml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eclipse_plugin/META-INF/MANIFEST.MF b/eclipse_plugin/META-INF/MANIFEST.MF index fb8d1bbde..b5583d602 100644 --- a/eclipse_plugin/META-INF/MANIFEST.MF +++ b/eclipse_plugin/META-INF/MANIFEST.MF @@ -11,5 +11,5 @@ Require-Bundle: org.eclipse.jdt.core;bundle-version="3.10.0", org.eclipse.ui, org.eclipse.equinox.common Bundle-ClassPath: ., - lib/guava-28.1-jre.jar, + lib/guava-30.1.1-jre.jar, lib/google-java-format-1.9.jar diff --git a/eclipse_plugin/build.properties b/eclipse_plugin/build.properties index 161a94d3d..de8466a3f 100644 --- a/eclipse_plugin/build.properties +++ b/eclipse_plugin/build.properties @@ -3,5 +3,5 @@ output.. = target/classes bin.includes = META-INF/,\ .,\ plugin.xml,\ - lib/guava-28.1-jre.jar,\ + lib/guava-30.1.1-jre.jar,\ lib/google-java-format-1.9.jar diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index 3c538a33c..600810687 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -37,7 +37,7 @@ 1.9 - 28.1-jre + 30.1.1-jre diff --git a/pom.xml b/pom.xml index 33af14e8a..aa85ac7c2 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ UTF-8 1.8 - 30.0-jre + 30.1.1-jre 1.0 3.6.1 2.7.1 From 753930c8931fd368215acc10a54ed5ae7982cfb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89amonn=20McManus?= Date: Thu, 29 Jul 2021 10:52:01 -0700 Subject: [PATCH 097/379] PUBLIC: Look up some `Method` variables just once. `Class.getMethod()` can be quite slow so it's best to avoid doing it repeatedly. PiperOrigin-RevId: 387621256 --- .../java/java14/Java14InputAstVisitor.java | 78 ++++++++++++------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index 03ee8d323..e5227da4b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -39,6 +39,7 @@ import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeInfo; +import java.lang.reflect.Method; import java.util.List; import java.util.Optional; import javax.lang.model.element.Name; @@ -48,6 +49,16 @@ * Java 14. */ public class Java14InputAstVisitor extends JavaInputAstVisitor { + private static final Method COMPILATION_UNIT_TREE_GET_MODULE = + maybeGetMethod(CompilationUnitTree.class, "getModule"); + private static final Method CLASS_TREE_GET_PERMITS_CLAUSE = + maybeGetMethod(ClassTree.class, "getPermitsClause"); + private static final Method BINDING_PATTERN_TREE_GET_VARIABLE = + maybeGetMethod(BindingPatternTree.class, "getVariable"); + private static final Method BINDING_PATTERN_TREE_GET_TYPE = + maybeGetMethod(BindingPatternTree.class, "getType"); + private static final Method BINDING_PATTERN_TREE_GET_BINDING = + maybeGetMethod(BindingPatternTree.class, "getBinding"); public Java14InputAstVisitor(OpsBuilder builder, int indentMultiplier) { super(builder, indentMultiplier); @@ -55,27 +66,26 @@ public Java14InputAstVisitor(OpsBuilder builder, int indentMultiplier) { @Override protected void handleModule(boolean first, CompilationUnitTree node) { - try { - ModuleTree module = - (ModuleTree) CompilationUnitTree.class.getMethod("getModule").invoke(node); - if (module != null) { - if (!first) { - builder.blankLineWanted(BlankLineWanted.YES); - } - markForPartialFormat(); - visitModule(module, null); - builder.forcedBreak(); - } - } catch (ReflectiveOperationException e) { + if (COMPILATION_UNIT_TREE_GET_MODULE == null) { // Java < 17, see https://bugs.openjdk.java.net/browse/JDK-8255464 + return; + } + ModuleTree module = (ModuleTree) invoke(COMPILATION_UNIT_TREE_GET_MODULE, node); + if (module != null) { + if (!first) { + builder.blankLineWanted(BlankLineWanted.YES); + } + markForPartialFormat(); + visitModule(module, null); + builder.forcedBreak(); } } @Override protected List getPermitsClause(ClassTree node) { - try { - return (List) ClassTree.class.getMethod("getPermitsClause").invoke(node); - } catch (ReflectiveOperationException e) { + if (CLASS_TREE_GET_PERMITS_CLAUSE != null) { + return (List) invoke(CLASS_TREE_GET_PERMITS_CLAUSE, node); + } else { // Java < 15 return super.getPermitsClause(node); } @@ -84,20 +94,18 @@ protected List getPermitsClause(ClassTree node) { @Override public Void visitBindingPattern(BindingPatternTree node, Void unused) { sync(node); - try { - VariableTree variableTree = - (VariableTree) BindingPatternTree.class.getMethod("getVariable").invoke(node); + if (BINDING_PATTERN_TREE_GET_VARIABLE != null) { + VariableTree variableTree = (VariableTree) invoke(BINDING_PATTERN_TREE_GET_VARIABLE, node); visitBindingPattern( variableTree.getModifiers(), variableTree.getType(), variableTree.getName()); - } catch (ReflectiveOperationException e1) { - try { - Tree type = (Tree) BindingPatternTree.class.getMethod("getType").invoke(node); - Name name = (Name) BindingPatternTree.class.getMethod("getBinding").invoke(node); - visitBindingPattern(/* modifiers= */ null, type, name); - } catch (ReflectiveOperationException e2) { - e2.addSuppressed(e1); - throw new LinkageError(e2.getMessage(), e2); - } + } else if (BINDING_PATTERN_TREE_GET_TYPE != null && BINDING_PATTERN_TREE_GET_BINDING != null) { + Tree type = (Tree) invoke(BINDING_PATTERN_TREE_GET_TYPE, node); + Name name = (Name) invoke(BINDING_PATTERN_TREE_GET_BINDING, node); + visitBindingPattern(/* modifiers= */ null, type, name); + } else { + throw new LinkageError( + "BindingPatternTree must have either getVariable() or both getType() and getBinding()," + + " but does not"); } return null; } @@ -288,4 +296,20 @@ public Void visitCase(CaseTree node, Void unused) { } return null; } + + private static Method maybeGetMethod(Class c, String name) { + try { + return c.getMethod(name); + } catch (ReflectiveOperationException e) { + return null; + } + } + + private static Object invoke(Method m, Object target) { + try { + return m.invoke(target); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } } From ec0849e26ccccee06016469a2e44a23cee542636 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 30 Jul 2021 09:14:55 -0700 Subject: [PATCH 098/379] Update version in README.md PiperOrigin-RevId: 387819445 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 41ab0806f..9802ebaaf 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and run it with: ``` -java -jar /path/to/google-java-format-1.10.0-all-deps.jar [files...] +java -jar /path/to/google-java-format-1.11.0-all-deps.jar [files...] ``` The formatter can act on whole files, on limited lines (`--lines`), on specific @@ -39,7 +39,7 @@ java \ --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ - -jar google-java-format-1.10.0-all-deps.jar [files...] + -jar google-java-format-1.11.0-all-deps.jar [files...] ``` ### IntelliJ, Android Studio, and other JetBrains IDEs @@ -113,7 +113,7 @@ configuration. com.google.googlejavaformat google-java-format - 1.10.0 + 1.11.0 ``` @@ -121,7 +121,7 @@ configuration. ```groovy dependencies { - implementation 'com.google.googlejavaformat:google-java-format:1.10.0' + implementation 'com.google.googlejavaformat:google-java-format:1.11.0' } ``` From 184a5adc4774ae636f6dab4859490753d3d2ae0a Mon Sep 17 00:00:00 2001 From: Amit Mendapara Date: Fri, 30 Jul 2021 09:15:45 -0700 Subject: [PATCH 099/379] Improve version handling for eclipse plugin Use same versions for plugin as google-java-format and strip versions from copied jar to avoid updating build.properties and MANIFEST.MF. Fixes #635 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/635 from cristatus:eclipse-plugin b4f56be226c67375491bf40fb032e139923fe56f PiperOrigin-RevId: 387819617 --- eclipse_plugin/META-INF/MANIFEST.MF | 6 +++--- eclipse_plugin/README.md | 16 +++++---------- eclipse_plugin/build.properties | 4 ++-- eclipse_plugin/pom.xml | 30 ++++++++++++++--------------- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/eclipse_plugin/META-INF/MANIFEST.MF b/eclipse_plugin/META-INF/MANIFEST.MF index b5583d602..34b1e8c88 100644 --- a/eclipse_plugin/META-INF/MANIFEST.MF +++ b/eclipse_plugin/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: google-java-format Bundle-SymbolicName: google-java-format-eclipse-plugin;singleton:=true Bundle-Vendor: Google -Bundle-Version: 1.9.0 +Bundle-Version: 1.11.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Bundle: org.eclipse.jdt.core;bundle-version="3.10.0", org.eclipse.jface, @@ -11,5 +11,5 @@ Require-Bundle: org.eclipse.jdt.core;bundle-version="3.10.0", org.eclipse.ui, org.eclipse.equinox.common Bundle-ClassPath: ., - lib/guava-30.1.1-jre.jar, - lib/google-java-format-1.9.jar + lib/guava.jar, + lib/google-java-format.jar diff --git a/eclipse_plugin/README.md b/eclipse_plugin/README.md index a45b46538..395a368dc 100644 --- a/eclipse_plugin/README.md +++ b/eclipse_plugin/README.md @@ -8,14 +8,9 @@ See https://github.com/google/google-java-format#eclipse ### Prerequisites -Make sure that the `build.properties` and `META-INF/MANIFEST.MF` contain all -necessary dependencies for the build. Furthermore, make sure that the -dependencies declared in the `pom.xml` match the entries in `build.properties` -and `META-INF/MANIFEST.MF`. - -If the used google java format core version is a 'SNAPSHOT' release, the version -for the Eclipse plugin in the `pom.xml` must end in '-SNAPSHOT' as well and the -bundle version specified in `META-INF/MANIFEST.MF` must end in '.qualifier'. +Before building the plugin, make sure to run `mvn +tycho-versions:update-eclipse-metadata` to update the bundle version in +`META-INF/MANIFEST.MF`. ### Building the Plugin @@ -39,9 +34,8 @@ information on this issue is given #### Building against a local (snapshot) release of the core With the current build setup, the Eclipse plugin build pulls the needed build -artifacts of the google java format core specified in the property -`google-java-format.version` and copies it into the `eclipse_plugin/lib/` -directory. +artifacts of the google java format core from the maven repository and copies it +into the `eclipse_plugin/lib/` directory. If you instead want to build against a local (snapshot) build of the core which is not available in a maven repository (local or otherwise), you will have to diff --git a/eclipse_plugin/build.properties b/eclipse_plugin/build.properties index de8466a3f..dd1d835c5 100644 --- a/eclipse_plugin/build.properties +++ b/eclipse_plugin/build.properties @@ -3,5 +3,5 @@ output.. = target/classes bin.includes = META-INF/,\ .,\ plugin.xml,\ - lib/guava-30.1.1-jre.jar,\ - lib/google-java-format-1.9.jar + lib/guava.jar,\ + lib/google-java-format.jar diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index 600810687..6b49c901a 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -22,7 +22,7 @@ com.google.googlejavaformat google-java-format-eclipse-plugin eclipse-plugin - 1.9.0 + 1.11.0 Google Java Format Plugin for Eclipse 4.5+ @@ -32,26 +32,14 @@ UTF-8 - 1.7.0 - - - 1.9 - 30.1.1-jre com.google.googlejavaformat google-java-format - ${google-java-format.version} - jar - - - com.google.guava - guava - ${guava.version} - jar + ${project.version} @@ -81,8 +69,10 @@ lib runtime - true + true + true true + guava,google-java-format @@ -92,6 +82,16 @@ ${tycho-version} true
+ + + org.eclipse.tycho + tycho-versions-plugin + ${tycho-version} + + ${project.version} + + + org.eclipse.tycho target-platform-configuration From f2eabaa9a7a2fe1ccd17c30124d2041fe97a6313 Mon Sep 17 00:00:00 2001 From: Avi Mimoun <36456709+av1m@users.noreply.github.com> Date: Mon, 2 Aug 2021 10:25:57 -0700 Subject: [PATCH 100/379] Updates the eclipse plugin link Upgrade from version 1.6 to version 1.11 (according #465) Fixes #639 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/639 from av1m:patch-1 2c5c2b05a9b0257ac96fdc616772c1e0a9ed451c PiperOrigin-RevId: 388249150 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9802ebaaf..202e69d16 100644 --- a/README.md +++ b/README.md @@ -70,8 +70,8 @@ and import it into File→Settings→Editor→Code Style. ### Eclipse -Version 1.6 of the -[google-java-format Eclipse plugin](https://github.com/google/google-java-format/releases/download/google-java-format-1.6/google-java-format-eclipse-plugin_1.6.0.jar) +Version 1.11 of the +[google-java-format Eclipse plugin](https://github.com/google/google-java-format/releases/download/v1.11.0/google-java-format-eclipse-plugin-1.11.0.jar) can be downloaded from the releases page. Drop it into the Eclipse [drop-ins folder](http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fp2_dropins_format.html) to activate the plugin. From 00511536792cd6b72d3cfb83d426d25521874e80 Mon Sep 17 00:00:00 2001 From: nakulj <3213360+nakulj@users.noreply.github.com> Date: Mon, 2 Aug 2021 13:33:12 -0700 Subject: [PATCH 101/379] Run 2to3 on google-java-format-diff.py Fixes #640 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/640 from nakulj:py2to3 8cf03bcdf5a62aea2bee0e5d9fb05ea88644c253 PiperOrigin-RevId: 388292852 --- scripts/google-java-format-diff.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/google-java-format-diff.py b/scripts/google-java-format-diff.py index 63685aac3..cf2ded9ec 100755 --- a/scripts/google-java-format-diff.py +++ b/scripts/google-java-format-diff.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python3 # #===- google-java-format-diff.py - google-java-format Diff Reformatter -----===# # @@ -31,7 +31,7 @@ import re import string import subprocess -import StringIO +import io import sys from distutils.spawn import find_executable @@ -109,9 +109,9 @@ def main(): base_command = [binary] # Reformat files containing changes in place. - for filename, lines in lines_by_file.iteritems(): + for filename, lines in lines_by_file.items(): if args.i and args.verbose: - print 'Formatting', filename + print('Formatting', filename) command = base_command[:] if args.i: command.append('-i') @@ -134,7 +134,7 @@ def main(): if not args.i: with open(filename) as f: code = f.readlines() - formatted_code = StringIO.StringIO(stdout).readlines() + formatted_code = io.StringIO(stdout).readlines() diff = difflib.unified_diff(code, formatted_code, filename, filename, '(before formatting)', '(after formatting)') From 1a875792f6a074f3f0a504ddb8c7cd932ba6b073 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 24 Aug 2021 16:11:35 -0700 Subject: [PATCH 102/379] Format type annotation as part of the type, not part of the modifiers list Given e.g. `@Deprecated @Nullable Object foo() {}`, prefer this: ``` @Deprecated @Nullable Object foo() {} ``` instead of: ``` @Deprecated @Nullable Object foo() {} ``` The implementation is complicated by the fact that the AST doesn't store source position information for modifiers, and there's no requirement that declaration annotations, modifiers, and type annotations appear in any particular order in source. To work around this, we examine the token stream to figure out the ordering of the modifiers and annotations. https://github.com/google/google-java-format/issues/5 PiperOrigin-RevId: 392769609 --- core/pom.xml | 6 +- .../google/googlejavaformat/OpsBuilder.java | 24 ++ .../java/JavaInputAstVisitor.java | 340 +++++++++++++++--- .../java/java14/Java14InputAstVisitor.java | 13 +- .../java/testdata/TypeAnnotations.input | 33 ++ .../java/testdata/TypeAnnotations.output | 39 ++ pom.xml | 11 + 7 files changed, 398 insertions(+), 68 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output diff --git a/core/pom.xml b/core/pom.xml index 74b7504ac..e8e9bf249 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -51,7 +51,11 @@ error_prone_annotations true - + + com.google.auto.value + auto-value-annotations + true + diff --git a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java index 36e038adf..db431c040 100644 --- a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java +++ b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java @@ -18,6 +18,8 @@ import static java.lang.Math.min; import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -281,6 +283,28 @@ public final Optional peekToken(int skip) { : Optional.empty(); } + /** + * Returns the {@link Input.Tok}s starting at the current source position, which are satisfied by + * the given predicate. + */ + public ImmutableList peekTokens(int startPosition, Predicate predicate) { + ImmutableList tokens = input.getTokens(); + Preconditions.checkState( + tokens.get(tokenI).getTok().getPosition() == startPosition, + "Expected the current token to be at position %s, found: %s", + startPosition, + tokens.get(tokenI)); + ImmutableList.Builder result = ImmutableList.builder(); + for (int idx = tokenI; idx < tokens.size(); idx++) { + Tok tok = tokens.get(idx).getTok(); + if (!predicate.apply(tok)) { + break; + } + result.add(tok); + } + return result.build(); + } + /** * Emit an optional token iff it exists on the input. This is used to emit tokens whose existence * has been lost in the AST. diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 372f3bb59..d0cd7976f 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -14,6 +14,8 @@ package com.google.googlejavaformat.java; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap; import static com.google.common.collect.Iterables.getLast; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.googlejavaformat.Doc.FillMode.INDEPENDENT; @@ -43,19 +45,26 @@ import static com.sun.source.tree.Tree.Kind.VARIABLE; import static java.util.stream.Collectors.toList; +import com.google.auto.value.AutoOneOf; +import com.google.auto.value.AutoValue; import com.google.common.base.MoreObjects; import com.google.common.base.Predicate; import com.google.common.base.Throwables; import com.google.common.base.Verify; import com.google.common.collect.HashMultiset; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import com.google.common.collect.Multiset; import com.google.common.collect.PeekingIterator; +import com.google.common.collect.Range; +import com.google.common.collect.RangeSet; import com.google.common.collect.Streams; +import com.google.common.collect.TreeRangeSet; +import com.google.errorprone.annotations.CheckReturnValue; import com.google.googlejavaformat.CloseOp; import com.google.googlejavaformat.Doc; import com.google.googlejavaformat.Doc.FillMode; @@ -139,7 +148,9 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.Deque; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -167,7 +178,7 @@ boolean isVertical() { } /** Whether to break or not. */ - enum BreakOrNot { + protected enum BreakOrNot { YES, NO; @@ -268,6 +279,13 @@ boolean isYes() { } } + // TODO(cushon): generalize this + private static final ImmutableMultimap TYPE_ANNOTATIONS = + Stream.of( + "org.jspecify.nullness.Nullable", + "org.checkerframework.checker.nullness.qual.Nullable") + .collect(toImmutableSetMultimap(x -> x.substring(x.lastIndexOf('.') + 1), x -> x)); + protected final OpsBuilder builder; protected static final Indent.Const ZERO = Indent.Const.ZERO; @@ -277,6 +295,8 @@ boolean isYes() { protected final Indent.Const plusTwo; protected final Indent.Const plusFour; + private final Set typeAnnotationSimpleNames = new HashSet<>(); + private static final ImmutableList breakList(Optional breakTag) { return ImmutableList.of(Doc.Break.make(Doc.FillMode.UNIFIED, " ", ZERO, breakTag)); } @@ -292,8 +312,6 @@ private static final ImmutableList forceBreakList(Optional breakTa return ImmutableList.of(Doc.Break.make(FillMode.FORCED, "", Indent.Const.ZERO, breakTag)); } - private static final ImmutableList EMPTY_LIST = ImmutableList.of(); - /** * Allow multi-line filling (of array initializers, argument lists, and boolean expressions) for * items with length less than or equal to this threshold. @@ -417,10 +435,7 @@ public Void visitClass(ClassTree tree, Void unused) { public void visitAnnotationType(ClassTree node) { sync(node); builder.open(ZERO); - visitAndBreakModifiers( - node.getModifiers(), - Direction.VERTICAL, - /* declarationAnnotationBreak= */ Optional.empty()); + typeDeclarationModifiers(node.getModifiers()); builder.open(ZERO); token("@"); token("interface"); @@ -679,9 +694,10 @@ public Void visitNewClass(NewClassTree node, Void unused) { builder.space(); addTypeArguments(node.getTypeArguments(), plusFour); if (node.getClassBody() != null) { - builder.addAll( + List annotations = visitModifiers( - node.getClassBody().getModifiers(), Direction.HORIZONTAL, Optional.empty())); + node.getClassBody().getModifiers(), Direction.HORIZONTAL, Optional.empty()); + visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); } scan(node.getIdentifier(), null); addArguments(node.getArguments(), plusFour); @@ -802,10 +818,7 @@ private void visitEnumConstantDeclaration(VariableTree enumConstant) { public boolean visitEnumDeclaration(ClassTree node) { sync(node); builder.open(ZERO); - visitAndBreakModifiers( - node.getModifiers(), - Direction.VERTICAL, - /* declarationAnnotationBreak= */ Optional.empty()); + typeDeclarationModifiers(node.getModifiers()); builder.open(plusFour); token("enum"); builder.breakOp(" "); @@ -969,7 +982,7 @@ void visitVariables( } } - private TypeWithDims variableFragmentDims(boolean first, int leadingDims, Tree type) { + private static TypeWithDims variableFragmentDims(boolean first, int leadingDims, Tree type) { if (type == null) { return null; } @@ -1114,6 +1127,7 @@ public Void visitIf(IfTree node, Void unused) { @Override public Void visitImport(ImportTree node, Void unused) { + checkForTypeAnnotation(node); sync(node); token("import"); builder.space(); @@ -1128,6 +1142,21 @@ public Void visitImport(ImportTree node, Void unused) { return null; } + private void checkForTypeAnnotation(ImportTree node) { + Name simpleName = getSimpleName(node); + Collection wellKnownAnnotations = TYPE_ANNOTATIONS.get(simpleName.toString()); + if (!wellKnownAnnotations.isEmpty() + && wellKnownAnnotations.contains(node.getQualifiedIdentifier().toString())) { + typeAnnotationSimpleNames.add(simpleName); + } + } + + private static Name getSimpleName(ImportTree importTree) { + return importTree.getQualifiedIdentifier() instanceof IdentifierTree + ? ((IdentifierTree) importTree.getQualifiedIdentifier()).getName() + : ((MemberSelectTree) importTree.getQualifiedIdentifier()).getIdentifier(); + } + @Override public Void visitBinary(BinaryTree node, Void unused) { sync(node); @@ -1360,9 +1389,12 @@ public Void visitMethod(MethodTree node, Void unused) { } } } - builder.addAll( + List typeAnnotations = visitModifiers( - annotations, Direction.VERTICAL, /* declarationAnnotationBreak= */ Optional.empty())); + node.getModifiers(), + annotations, + Direction.VERTICAL, + /* declarationAnnotationBreak= */ Optional.empty()); Tree baseReturnType = null; Deque> dims = null; @@ -1371,6 +1403,9 @@ public Void visitMethod(MethodTree node, Void unused) { DimensionHelpers.extractDims(node.getReturnType(), SortedDims.YES); baseReturnType = extractedDims.node; dims = new ArrayDeque<>(extractedDims.dims); + } else { + verticalAnnotations(typeAnnotations); + typeAnnotations = ImmutableList.of(); } builder.open(plusFour); @@ -1379,7 +1414,14 @@ public Void visitMethod(MethodTree node, Void unused) { builder.open(ZERO); { boolean first = true; + if (!typeAnnotations.isEmpty()) { + visitAnnotations(typeAnnotations, BreakOrNot.NO, BreakOrNot.NO); + first = false; + } if (!node.getTypeParameters().isEmpty()) { + if (!first) { + builder.breakToFill(" "); + } token("<"); typeParametersRest(node.getTypeParameters(), plusFour); if (!returnTypeAnnotations.isEmpty()) { @@ -1956,16 +1998,11 @@ public Void visitTry(TryTree node, Void unused) { public void visitClassDeclaration(ClassTree node) { sync(node); - List breaks = - visitModifiers( - node.getModifiers(), - Direction.VERTICAL, - /* declarationAnnotationBreak= */ Optional.empty()); + typeDeclarationModifiers(node.getModifiers()); List permitsTypes = getPermitsClause(node); boolean hasSuperclassType = node.getExtendsClause() != null; boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); boolean hasPermitsTypes = !permitsTypes.isEmpty(); - builder.addAll(breaks); token(node.getKind() == Tree.Kind.INTERFACE ? "interface" : "class"); builder.space(); visit(node.getSimpleName()); @@ -2069,7 +2106,7 @@ public Void visitWildcard(WildcardTree node, Void unused) { // Helper methods. /** Helper method for annotations. */ - void visitAnnotations( + protected void visitAnnotations( List annotations, BreakOrNot breakBefore, BreakOrNot breakAfter) { if (!annotations.isEmpty()) { if (breakBefore.isYes()) { @@ -2089,6 +2126,14 @@ void visitAnnotations( } } + void verticalAnnotations(List annotations) { + for (AnnotationTree annotation : annotations) { + builder.forcedBreak(); + scan(annotation, null); + builder.forcedBreak(); + } + } + /** Helper method for blocks. */ protected void visitBlock( BlockTree node, @@ -2176,12 +2221,21 @@ protected void visitStatements(List statements) { } } + protected void typeDeclarationModifiers(ModifiersTree modifiers) { + List typeAnnotations = + visitModifiers( + modifiers, Direction.VERTICAL, /* declarationAnnotationBreak= */ Optional.empty()); + verticalAnnotations(typeAnnotations); + } + /** Output combined modifiers and annotations and the trailing break. */ void visitAndBreakModifiers( ModifiersTree modifiers, Direction annotationDirection, Optional declarationAnnotationBreak) { - builder.addAll(visitModifiers(modifiers, annotationDirection, declarationAnnotationBreak)); + List typeAnnotations = + visitModifiers(modifiers, annotationDirection, declarationAnnotationBreak); + visitAnnotations(typeAnnotations, BreakOrNot.NO, BreakOrNot.YES); } @Override @@ -2190,36 +2244,50 @@ public Void visitModifiers(ModifiersTree node, Void unused) { } /** Output combined modifiers and annotations and returns the trailing break. */ - protected List visitModifiers( + @CheckReturnValue + protected ImmutableList visitModifiers( ModifiersTree modifiersTree, Direction annotationsDirection, Optional declarationAnnotationBreak) { return visitModifiers( - modifiersTree.getAnnotations(), annotationsDirection, declarationAnnotationBreak); + modifiersTree, + modifiersTree.getAnnotations(), + annotationsDirection, + declarationAnnotationBreak); } - protected List visitModifiers( + @CheckReturnValue + protected ImmutableList visitModifiers( + ModifiersTree modifiersTree, List annotationTrees, Direction annotationsDirection, Optional declarationAnnotationBreak) { - if (annotationTrees.isEmpty() && !nextIsModifier()) { - return EMPTY_LIST; + DeclarationModifiersAndTypeAnnotations splitModifiers = + splitModifiers(modifiersTree, annotationTrees); + return visitModifiers(splitModifiers, annotationsDirection, declarationAnnotationBreak); + } + + @CheckReturnValue + private ImmutableList visitModifiers( + DeclarationModifiersAndTypeAnnotations splitModifiers, + Direction annotationsDirection, + Optional declarationAnnotationBreak) { + if (splitModifiers.declarationModifiers().isEmpty()) { + return splitModifiers.typeAnnotations(); } - Deque annotations = new ArrayDeque<>(annotationTrees); + Deque declarationModifiers = + new ArrayDeque<>(splitModifiers.declarationModifiers()); builder.open(ZERO); boolean first = true; boolean lastWasAnnotation = false; - while (!annotations.isEmpty()) { - if (nextIsModifier()) { - break; - } + while (!declarationModifiers.isEmpty() && !declarationModifiers.peekFirst().isModifier()) { if (!first) { builder.addAll( annotationsDirection.isVertical() ? forceBreakList(declarationAnnotationBreak) : breakList(declarationAnnotationBreak)); } - scan(annotations.removeFirst(), null); + formatAnnotationOrModifier(declarationModifiers.removeFirst()); first = false; lastWasAnnotation = true; } @@ -2228,8 +2296,9 @@ protected List visitModifiers( annotationsDirection.isVertical() ? forceBreakList(declarationAnnotationBreak) : breakList(declarationAnnotationBreak); - if (annotations.isEmpty() && !nextIsModifier()) { - return trailingBreak; + if (declarationModifiers.isEmpty()) { + builder.addAll(trailingBreak); + return splitModifiers.typeAnnotations(); } if (lastWasAnnotation) { builder.addAll(trailingBreak); @@ -2237,24 +2306,169 @@ protected List visitModifiers( builder.open(ZERO); first = true; - while (nextIsModifier() || !annotations.isEmpty()) { + while (!declarationModifiers.isEmpty()) { if (!first) { builder.addAll(breakFillList(Optional.empty())); } - if (nextIsModifier()) { - token(builder.peekToken().get()); - } else { - scan(annotations.removeFirst(), null); - lastWasAnnotation = true; - } + formatAnnotationOrModifier(declarationModifiers.removeFirst()); first = false; } builder.close(); - return breakFillList(Optional.empty()); + builder.addAll(breakFillList(Optional.empty())); + return splitModifiers.typeAnnotations(); + } + + /** Represents an annotation or a modifier in a {@link ModifiersTree}. */ + @AutoOneOf(AnnotationOrModifier.Kind.class) + abstract static class AnnotationOrModifier implements Comparable { + enum Kind { + MODIFIER, + ANNOTATION + } + + abstract Kind getKind(); + + abstract AnnotationTree annotation(); + + abstract Input.Tok modifier(); + + static AnnotationOrModifier ofModifier(Input.Tok m) { + return AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.modifier(m); + } + + static AnnotationOrModifier ofAnnotation(AnnotationTree a) { + return AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.annotation(a); + } + + boolean isModifier() { + return getKind().equals(Kind.MODIFIER); + } + + boolean isAnnotation() { + return getKind().equals(Kind.ANNOTATION); + } + + int position() { + switch (getKind()) { + case MODIFIER: + return modifier().getPosition(); + case ANNOTATION: + return getStartPosition(annotation()); + } + throw new AssertionError(); + } + + private static final Comparator COMPARATOR = + Comparator.comparingInt(AnnotationOrModifier::position); + + @Override + public int compareTo(AnnotationOrModifier o) { + return COMPARATOR.compare(this, o); + } + } + + /** + * The modifiers annotations for a declaration, grouped in to a prefix that contains all of the + * declaration annotations and modifiers, and a suffix of type annotations. + * + *

For examples like {@code @Deprecated public @Nullable Foo foo();}, this allows us to format + * {@code @Deprecated public} as declaration modifiers, and {@code @Nullable} as a type annotation + * on the return type. + */ + @AutoValue + abstract static class DeclarationModifiersAndTypeAnnotations { + abstract ImmutableList declarationModifiers(); + + abstract ImmutableList typeAnnotations(); + + static DeclarationModifiersAndTypeAnnotations create( + ImmutableList declarationModifiers, + ImmutableList typeAnnotations) { + return new AutoValue_JavaInputAstVisitor_DeclarationModifiersAndTypeAnnotations( + declarationModifiers, typeAnnotations); + } + + static DeclarationModifiersAndTypeAnnotations empty() { + return create(ImmutableList.of(), ImmutableList.of()); + } + + boolean hasDeclarationAnnotation() { + return declarationModifiers().stream().anyMatch(AnnotationOrModifier::isAnnotation); + } + } + + /** + * Examines the token stream to convert the modifiers for a declaration into a {@link + * DeclarationModifiersAndTypeAnnotations}. + */ + DeclarationModifiersAndTypeAnnotations splitModifiers( + ModifiersTree modifiersTree, List annotations) { + if (annotations.isEmpty() && !isModifier(builder.peekToken().get())) { + return DeclarationModifiersAndTypeAnnotations.empty(); + } + RangeSet annotationRanges = TreeRangeSet.create(); + for (AnnotationTree annotationTree : annotations) { + annotationRanges.add( + Range.closedOpen( + getStartPosition(annotationTree), getEndPosition(annotationTree, getCurrentPath()))); + } + ImmutableList toks = + builder.peekTokens( + getStartPosition(modifiersTree), + (Input.Tok tok) -> + // ModifiersTree end position information isn't reliable, so scan tokens as long as + // we're seeing annotations or modifiers + annotationRanges.contains(tok.getPosition()) || isModifier(tok.getText())); + ImmutableList modifiers = + Streams.concat( + toks.stream() + // reject tokens from inside AnnotationTrees, we only want modifiers + .filter(t -> !annotationRanges.contains(t.getPosition())) + .map(AnnotationOrModifier::ofModifier), + annotations.stream().map(AnnotationOrModifier::ofAnnotation)) + .sorted() + .collect(toImmutableList()); + // Take a suffix of annotations that are well-known type annotations, and which appear after any + // declaration annotations or modifiers + ImmutableList.Builder typeAnnotations = ImmutableList.builder(); + int idx = modifiers.size() - 1; + while (idx >= 0) { + AnnotationOrModifier modifier = modifiers.get(idx); + if (!modifier.isAnnotation() || !isTypeAnnotation(modifier.annotation())) { + break; + } + typeAnnotations.add(modifier.annotation()); + idx--; + } + return DeclarationModifiersAndTypeAnnotations.create( + modifiers.subList(0, idx + 1), typeAnnotations.build().reverse()); + } + + private void formatAnnotationOrModifier(AnnotationOrModifier modifier) { + switch (modifier.getKind()) { + case MODIFIER: + token(modifier.modifier().getText()); + break; + case ANNOTATION: + scan(modifier.annotation(), null); + break; + } + } + + boolean isTypeAnnotation(AnnotationTree annotationTree) { + Tree annotationType = annotationTree.getAnnotationType(); + if (!(annotationType instanceof IdentifierTree)) { + return false; + } + return typeAnnotationSimpleNames.contains(((IdentifierTree) annotationType).getName()); } boolean nextIsModifier() { - switch (builder.peekToken().get()) { + return isModifier(builder.peekToken().get()); + } + + private static boolean isModifier(String token) { + switch (token) { case "public": case "protected": case "private": @@ -2877,7 +3091,7 @@ private void visitDotWithPrefix( } /** Returns the simple names of expressions in a "." chain. */ - private List simpleNames(Deque stack) { + private static ImmutableList simpleNames(Deque stack) { ImmutableList.Builder simpleNames = ImmutableList.builder(); OUTER: for (ExpressionTree expression : stack) { @@ -2934,14 +3148,14 @@ private void dotExpressionUpToArgs(ExpressionTree expression, Optional * Returns the base expression of an erray access, e.g. given {@code foo[0][0]} returns {@code * foo}. */ - private ExpressionTree getArrayBase(ExpressionTree node) { + private static ExpressionTree getArrayBase(ExpressionTree node) { while (node instanceof ArrayAccessTree) { node = ((ArrayAccessTree) node).getExpression(); } return node; } - private ExpressionTree getMethodReceiver(MethodInvocationTree methodInvocation) { + private static ExpressionTree getMethodReceiver(MethodInvocationTree methodInvocation) { ExpressionTree select = methodInvocation.getMethodSelect(); return select instanceof MemberSelectTree ? ((MemberSelectTree) select).getExpression() : null; } @@ -2982,7 +3196,7 @@ private void formatArrayIndices(Deque indices) { * Returns all array indices for the given expression, e.g. given {@code foo[0][0]} returns the * expressions for {@code [0][0]}. */ - private Deque getArrayIndices(ExpressionTree expression) { + private static Deque getArrayIndices(ExpressionTree expression) { Deque indices = new ArrayDeque<>(); while (expression instanceof ArrayAccessTree) { ArrayAccessTree array = (ArrayAccessTree) expression; @@ -3282,16 +3496,22 @@ int declareOne( new ArrayDeque<>(typeWithDims.isPresent() ? typeWithDims.get().dims : ImmutableList.of()); int baseDims = 0; + // preprocess to separate declaration annotations + modifiers, type annotations + + DeclarationModifiersAndTypeAnnotations declarationAndTypeModifiers = + modifiers + .map(m -> splitModifiers(m, m.getAnnotations())) + .orElse(DeclarationModifiersAndTypeAnnotations.empty()); builder.open( - kind == DeclarationKind.PARAMETER - && (modifiers.isPresent() && !modifiers.get().getAnnotations().isEmpty()) + kind == DeclarationKind.PARAMETER && declarationAndTypeModifiers.hasDeclarationAnnotation() ? plusFour : ZERO); { - if (modifiers.isPresent()) { - visitAndBreakModifiers( - modifiers.get(), annotationsDirection, Optional.of(verticalAnnotationBreak)); - } + List annotations = + visitModifiers( + declarationAndTypeModifiers, + annotationsDirection, + Optional.of(verticalAnnotationBreak)); boolean isVar = builder.peekToken().get().equals("var") && (!name.contentEquals("var") || builder.peekToken(1).get().equals("var")); @@ -3302,6 +3522,7 @@ int declareOne( { builder.open(ZERO); { + visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); if (typeWithDims.isPresent() && typeWithDims.get().node != null) { scan(typeWithDims.get().node, null); int totalDims = dims.size(); @@ -3573,7 +3794,8 @@ private void classDeclarationTypeList(String token, List types) * *

e.g. {@code int x, y;} is parsed as {@code int x; int y;}. */ - private List variableFragments(PeekingIterator it, Tree first) { + private static List variableFragments( + PeekingIterator it, Tree first) { List fragments = new ArrayList<>(); if (first.getKind() == VARIABLE) { int start = getStartPosition(first); @@ -3623,7 +3845,7 @@ private boolean hasTrailingToken(Input input, List nodes, String * @param modifiers the list of {@link ModifiersTree}s * @return whether the local can be declared with horizontal annotations */ - private Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifiers) { + private static Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifiers) { int parameterlessAnnotations = 0; for (AnnotationTree annotation : modifiers.getAnnotations()) { if (annotation.getArguments().isEmpty()) { @@ -3640,7 +3862,7 @@ private Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifiers) { * Should a field with a set of modifiers be declared with horizontal annotations? This is * currently true if all annotations are parameterless annotations. */ - private Direction fieldAnnotationDirection(ModifiersTree modifiers) { + private static Direction fieldAnnotationDirection(ModifiersTree modifiers) { for (AnnotationTree annotation : modifiers.getAnnotations()) { if (!annotation.getArguments().isEmpty()) { return Direction.VERTICAL; diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index e5227da4b..b0d2a7675 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -18,10 +18,10 @@ import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; -import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.OpsBuilder.BlankLineWanted; import com.google.googlejavaformat.java.JavaInputAstVisitor; +import com.sun.source.tree.AnnotationTree; import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.BlockTree; import com.sun.source.tree.CaseTree; @@ -112,7 +112,9 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) { if (modifiers != null) { - builder.addAll(visitModifiers(modifiers, Direction.HORIZONTAL, Optional.empty())); + List annotations = + visitModifiers(modifiers, Direction.HORIZONTAL, Optional.empty()); + visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); } scan(type, null); builder.breakOp(" "); @@ -160,14 +162,9 @@ public Void visitClass(ClassTree tree, Void unused) { public void visitRecordDeclaration(ClassTree node) { sync(node); - List breaks = - visitModifiers( - node.getModifiers(), - Direction.VERTICAL, - /* declarationAnnotationBreak= */ Optional.empty()); + typeDeclarationModifiers(node.getModifiers()); Verify.verify(node.getExtendsClause() == null); boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); - builder.addAll(breaks); token("record"); builder.space(); visit(node.getSimpleName()); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input new file mode 100644 index 000000000..ddaa8f1ad --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input @@ -0,0 +1,33 @@ +import org.checkerframework.checker.nullness.qual.Nullable; + +class TypeAnnotations { + + @Deprecated + public @Nullable Object foo() {} + + public @Deprecated Object foo() {} + + @Nullable Foo handle() { + @Nullable Bar bar = bar(); + try (@Nullable Baz baz = baz()) {} + } + + Foo( + @Nullable Bar // + param1, // + Baz // + param2) {} + + void g( + @Deprecated @Nullable ImmutableList veryVeryLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, + @Deprecated @Nullable ImmutableList veryVeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooong) {} + + @Deprecated @Nullable TypeAnnotations() {} + + enum Foo { + @Nullable + BAR; + } + + @Nullable @Nullable Object doubleTrouble() {} +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output new file mode 100644 index 000000000..8dd5d4efc --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output @@ -0,0 +1,39 @@ +import org.checkerframework.checker.nullness.qual.Nullable; + +class TypeAnnotations { + + @Deprecated + public @Nullable Object foo() {} + + public @Deprecated Object foo() {} + + @Nullable Foo handle() { + @Nullable Bar bar = bar(); + try (@Nullable Baz baz = baz()) {} + } + + Foo( + @Nullable Bar // + param1, // + Baz // + param2) {} + + void g( + @Deprecated + @Nullable ImmutableList + veryVeryLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, + @Deprecated + @Nullable ImmutableList + veryVeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooong) {} + + @Deprecated + @Nullable + TypeAnnotations() {} + + enum Foo { + @Nullable + BAR; + } + + @Nullable @Nullable Object doubleTrouble() {} +} diff --git a/pom.xml b/pom.xml index aa85ac7c2..c66ed2f23 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,7 @@ 1.0 3.6.1 2.7.1 + 1.8.2 3.1.0 3.2.1 @@ -118,6 +119,11 @@ error_prone_annotations ${errorprone.version} + + com.google.auto.value + auto-value-annotations + ${auto-value.version} + @@ -209,6 +215,11 @@ error_prone_core ${errorprone.version} + + com.google.auto.value + auto-value + ${auto-value.version} + From 37f716a1143879a1d8cd94ecb8e976eee593d43f Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Tue, 24 Aug 2021 17:42:10 -0700 Subject: [PATCH 103/379] Automated rollback of commit 1a875792f6a074f3f0a504ddb8c7cd932ba6b073. *** Reason for rollback *** TAP shows this is broke Voice Access (and perhaps other projects) [] *** Original change description *** Format type annotation as part of the type, not part of the modifiers list Given e.g. `@Deprecated @Nullable Object foo() {}`, prefer this: ``` @Deprecated @Nullable Object foo() {} ``` instead of: ``` @Deprecated @Nullable Object foo() {} ``` The implementation is complicated by the fact that the AST doesn't store source position information for modifiers, and there's no requirement that declaration annotations, modifiers, and type annotations appear in any particular order in source. To... *** PiperOrigin-RevId: 392785771 --- core/pom.xml | 6 +- .../google/googlejavaformat/OpsBuilder.java | 24 -- .../java/JavaInputAstVisitor.java | 340 +++--------------- .../java/java14/Java14InputAstVisitor.java | 13 +- .../java/testdata/TypeAnnotations.input | 33 -- .../java/testdata/TypeAnnotations.output | 39 -- pom.xml | 11 - 7 files changed, 68 insertions(+), 398 deletions(-) delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output diff --git a/core/pom.xml b/core/pom.xml index e8e9bf249..74b7504ac 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -51,11 +51,7 @@ error_prone_annotations true - - com.google.auto.value - auto-value-annotations - true - + diff --git a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java index db431c040..36e038adf 100644 --- a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java +++ b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java @@ -18,8 +18,6 @@ import static java.lang.Math.min; import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -283,28 +281,6 @@ public final Optional peekToken(int skip) { : Optional.empty(); } - /** - * Returns the {@link Input.Tok}s starting at the current source position, which are satisfied by - * the given predicate. - */ - public ImmutableList peekTokens(int startPosition, Predicate predicate) { - ImmutableList tokens = input.getTokens(); - Preconditions.checkState( - tokens.get(tokenI).getTok().getPosition() == startPosition, - "Expected the current token to be at position %s, found: %s", - startPosition, - tokens.get(tokenI)); - ImmutableList.Builder result = ImmutableList.builder(); - for (int idx = tokenI; idx < tokens.size(); idx++) { - Tok tok = tokens.get(idx).getTok(); - if (!predicate.apply(tok)) { - break; - } - result.add(tok); - } - return result.build(); - } - /** * Emit an optional token iff it exists on the input. This is used to emit tokens whose existence * has been lost in the AST. diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index d0cd7976f..372f3bb59 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -14,8 +14,6 @@ package com.google.googlejavaformat.java; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.ImmutableSetMultimap.toImmutableSetMultimap; import static com.google.common.collect.Iterables.getLast; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.googlejavaformat.Doc.FillMode.INDEPENDENT; @@ -45,26 +43,19 @@ import static com.sun.source.tree.Tree.Kind.VARIABLE; import static java.util.stream.Collectors.toList; -import com.google.auto.value.AutoOneOf; -import com.google.auto.value.AutoValue; import com.google.common.base.MoreObjects; import com.google.common.base.Predicate; import com.google.common.base.Throwables; import com.google.common.base.Verify; import com.google.common.collect.HashMultiset; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import com.google.common.collect.Multiset; import com.google.common.collect.PeekingIterator; -import com.google.common.collect.Range; -import com.google.common.collect.RangeSet; import com.google.common.collect.Streams; -import com.google.common.collect.TreeRangeSet; -import com.google.errorprone.annotations.CheckReturnValue; import com.google.googlejavaformat.CloseOp; import com.google.googlejavaformat.Doc; import com.google.googlejavaformat.Doc.FillMode; @@ -148,9 +139,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; -import java.util.Comparator; import java.util.Deque; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -178,7 +167,7 @@ boolean isVertical() { } /** Whether to break or not. */ - protected enum BreakOrNot { + enum BreakOrNot { YES, NO; @@ -279,13 +268,6 @@ boolean isYes() { } } - // TODO(cushon): generalize this - private static final ImmutableMultimap TYPE_ANNOTATIONS = - Stream.of( - "org.jspecify.nullness.Nullable", - "org.checkerframework.checker.nullness.qual.Nullable") - .collect(toImmutableSetMultimap(x -> x.substring(x.lastIndexOf('.') + 1), x -> x)); - protected final OpsBuilder builder; protected static final Indent.Const ZERO = Indent.Const.ZERO; @@ -295,8 +277,6 @@ boolean isYes() { protected final Indent.Const plusTwo; protected final Indent.Const plusFour; - private final Set typeAnnotationSimpleNames = new HashSet<>(); - private static final ImmutableList breakList(Optional breakTag) { return ImmutableList.of(Doc.Break.make(Doc.FillMode.UNIFIED, " ", ZERO, breakTag)); } @@ -312,6 +292,8 @@ private static final ImmutableList forceBreakList(Optional breakTa return ImmutableList.of(Doc.Break.make(FillMode.FORCED, "", Indent.Const.ZERO, breakTag)); } + private static final ImmutableList EMPTY_LIST = ImmutableList.of(); + /** * Allow multi-line filling (of array initializers, argument lists, and boolean expressions) for * items with length less than or equal to this threshold. @@ -435,7 +417,10 @@ public Void visitClass(ClassTree tree, Void unused) { public void visitAnnotationType(ClassTree node) { sync(node); builder.open(ZERO); - typeDeclarationModifiers(node.getModifiers()); + visitAndBreakModifiers( + node.getModifiers(), + Direction.VERTICAL, + /* declarationAnnotationBreak= */ Optional.empty()); builder.open(ZERO); token("@"); token("interface"); @@ -694,10 +679,9 @@ public Void visitNewClass(NewClassTree node, Void unused) { builder.space(); addTypeArguments(node.getTypeArguments(), plusFour); if (node.getClassBody() != null) { - List annotations = + builder.addAll( visitModifiers( - node.getClassBody().getModifiers(), Direction.HORIZONTAL, Optional.empty()); - visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); + node.getClassBody().getModifiers(), Direction.HORIZONTAL, Optional.empty())); } scan(node.getIdentifier(), null); addArguments(node.getArguments(), plusFour); @@ -818,7 +802,10 @@ private void visitEnumConstantDeclaration(VariableTree enumConstant) { public boolean visitEnumDeclaration(ClassTree node) { sync(node); builder.open(ZERO); - typeDeclarationModifiers(node.getModifiers()); + visitAndBreakModifiers( + node.getModifiers(), + Direction.VERTICAL, + /* declarationAnnotationBreak= */ Optional.empty()); builder.open(plusFour); token("enum"); builder.breakOp(" "); @@ -982,7 +969,7 @@ void visitVariables( } } - private static TypeWithDims variableFragmentDims(boolean first, int leadingDims, Tree type) { + private TypeWithDims variableFragmentDims(boolean first, int leadingDims, Tree type) { if (type == null) { return null; } @@ -1127,7 +1114,6 @@ public Void visitIf(IfTree node, Void unused) { @Override public Void visitImport(ImportTree node, Void unused) { - checkForTypeAnnotation(node); sync(node); token("import"); builder.space(); @@ -1142,21 +1128,6 @@ public Void visitImport(ImportTree node, Void unused) { return null; } - private void checkForTypeAnnotation(ImportTree node) { - Name simpleName = getSimpleName(node); - Collection wellKnownAnnotations = TYPE_ANNOTATIONS.get(simpleName.toString()); - if (!wellKnownAnnotations.isEmpty() - && wellKnownAnnotations.contains(node.getQualifiedIdentifier().toString())) { - typeAnnotationSimpleNames.add(simpleName); - } - } - - private static Name getSimpleName(ImportTree importTree) { - return importTree.getQualifiedIdentifier() instanceof IdentifierTree - ? ((IdentifierTree) importTree.getQualifiedIdentifier()).getName() - : ((MemberSelectTree) importTree.getQualifiedIdentifier()).getIdentifier(); - } - @Override public Void visitBinary(BinaryTree node, Void unused) { sync(node); @@ -1389,12 +1360,9 @@ public Void visitMethod(MethodTree node, Void unused) { } } } - List typeAnnotations = + builder.addAll( visitModifiers( - node.getModifiers(), - annotations, - Direction.VERTICAL, - /* declarationAnnotationBreak= */ Optional.empty()); + annotations, Direction.VERTICAL, /* declarationAnnotationBreak= */ Optional.empty())); Tree baseReturnType = null; Deque> dims = null; @@ -1403,9 +1371,6 @@ public Void visitMethod(MethodTree node, Void unused) { DimensionHelpers.extractDims(node.getReturnType(), SortedDims.YES); baseReturnType = extractedDims.node; dims = new ArrayDeque<>(extractedDims.dims); - } else { - verticalAnnotations(typeAnnotations); - typeAnnotations = ImmutableList.of(); } builder.open(plusFour); @@ -1414,14 +1379,7 @@ public Void visitMethod(MethodTree node, Void unused) { builder.open(ZERO); { boolean first = true; - if (!typeAnnotations.isEmpty()) { - visitAnnotations(typeAnnotations, BreakOrNot.NO, BreakOrNot.NO); - first = false; - } if (!node.getTypeParameters().isEmpty()) { - if (!first) { - builder.breakToFill(" "); - } token("<"); typeParametersRest(node.getTypeParameters(), plusFour); if (!returnTypeAnnotations.isEmpty()) { @@ -1998,11 +1956,16 @@ public Void visitTry(TryTree node, Void unused) { public void visitClassDeclaration(ClassTree node) { sync(node); - typeDeclarationModifiers(node.getModifiers()); + List breaks = + visitModifiers( + node.getModifiers(), + Direction.VERTICAL, + /* declarationAnnotationBreak= */ Optional.empty()); List permitsTypes = getPermitsClause(node); boolean hasSuperclassType = node.getExtendsClause() != null; boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); boolean hasPermitsTypes = !permitsTypes.isEmpty(); + builder.addAll(breaks); token(node.getKind() == Tree.Kind.INTERFACE ? "interface" : "class"); builder.space(); visit(node.getSimpleName()); @@ -2106,7 +2069,7 @@ public Void visitWildcard(WildcardTree node, Void unused) { // Helper methods. /** Helper method for annotations. */ - protected void visitAnnotations( + void visitAnnotations( List annotations, BreakOrNot breakBefore, BreakOrNot breakAfter) { if (!annotations.isEmpty()) { if (breakBefore.isYes()) { @@ -2126,14 +2089,6 @@ protected void visitAnnotations( } } - void verticalAnnotations(List annotations) { - for (AnnotationTree annotation : annotations) { - builder.forcedBreak(); - scan(annotation, null); - builder.forcedBreak(); - } - } - /** Helper method for blocks. */ protected void visitBlock( BlockTree node, @@ -2221,21 +2176,12 @@ protected void visitStatements(List statements) { } } - protected void typeDeclarationModifiers(ModifiersTree modifiers) { - List typeAnnotations = - visitModifiers( - modifiers, Direction.VERTICAL, /* declarationAnnotationBreak= */ Optional.empty()); - verticalAnnotations(typeAnnotations); - } - /** Output combined modifiers and annotations and the trailing break. */ void visitAndBreakModifiers( ModifiersTree modifiers, Direction annotationDirection, Optional declarationAnnotationBreak) { - List typeAnnotations = - visitModifiers(modifiers, annotationDirection, declarationAnnotationBreak); - visitAnnotations(typeAnnotations, BreakOrNot.NO, BreakOrNot.YES); + builder.addAll(visitModifiers(modifiers, annotationDirection, declarationAnnotationBreak)); } @Override @@ -2244,50 +2190,36 @@ public Void visitModifiers(ModifiersTree node, Void unused) { } /** Output combined modifiers and annotations and returns the trailing break. */ - @CheckReturnValue - protected ImmutableList visitModifiers( + protected List visitModifiers( ModifiersTree modifiersTree, Direction annotationsDirection, Optional declarationAnnotationBreak) { return visitModifiers( - modifiersTree, - modifiersTree.getAnnotations(), - annotationsDirection, - declarationAnnotationBreak); + modifiersTree.getAnnotations(), annotationsDirection, declarationAnnotationBreak); } - @CheckReturnValue - protected ImmutableList visitModifiers( - ModifiersTree modifiersTree, + protected List visitModifiers( List annotationTrees, Direction annotationsDirection, Optional declarationAnnotationBreak) { - DeclarationModifiersAndTypeAnnotations splitModifiers = - splitModifiers(modifiersTree, annotationTrees); - return visitModifiers(splitModifiers, annotationsDirection, declarationAnnotationBreak); - } - - @CheckReturnValue - private ImmutableList visitModifiers( - DeclarationModifiersAndTypeAnnotations splitModifiers, - Direction annotationsDirection, - Optional declarationAnnotationBreak) { - if (splitModifiers.declarationModifiers().isEmpty()) { - return splitModifiers.typeAnnotations(); + if (annotationTrees.isEmpty() && !nextIsModifier()) { + return EMPTY_LIST; } - Deque declarationModifiers = - new ArrayDeque<>(splitModifiers.declarationModifiers()); + Deque annotations = new ArrayDeque<>(annotationTrees); builder.open(ZERO); boolean first = true; boolean lastWasAnnotation = false; - while (!declarationModifiers.isEmpty() && !declarationModifiers.peekFirst().isModifier()) { + while (!annotations.isEmpty()) { + if (nextIsModifier()) { + break; + } if (!first) { builder.addAll( annotationsDirection.isVertical() ? forceBreakList(declarationAnnotationBreak) : breakList(declarationAnnotationBreak)); } - formatAnnotationOrModifier(declarationModifiers.removeFirst()); + scan(annotations.removeFirst(), null); first = false; lastWasAnnotation = true; } @@ -2296,9 +2228,8 @@ private ImmutableList visitModifiers( annotationsDirection.isVertical() ? forceBreakList(declarationAnnotationBreak) : breakList(declarationAnnotationBreak); - if (declarationModifiers.isEmpty()) { - builder.addAll(trailingBreak); - return splitModifiers.typeAnnotations(); + if (annotations.isEmpty() && !nextIsModifier()) { + return trailingBreak; } if (lastWasAnnotation) { builder.addAll(trailingBreak); @@ -2306,169 +2237,24 @@ private ImmutableList visitModifiers( builder.open(ZERO); first = true; - while (!declarationModifiers.isEmpty()) { + while (nextIsModifier() || !annotations.isEmpty()) { if (!first) { builder.addAll(breakFillList(Optional.empty())); } - formatAnnotationOrModifier(declarationModifiers.removeFirst()); + if (nextIsModifier()) { + token(builder.peekToken().get()); + } else { + scan(annotations.removeFirst(), null); + lastWasAnnotation = true; + } first = false; } builder.close(); - builder.addAll(breakFillList(Optional.empty())); - return splitModifiers.typeAnnotations(); - } - - /** Represents an annotation or a modifier in a {@link ModifiersTree}. */ - @AutoOneOf(AnnotationOrModifier.Kind.class) - abstract static class AnnotationOrModifier implements Comparable { - enum Kind { - MODIFIER, - ANNOTATION - } - - abstract Kind getKind(); - - abstract AnnotationTree annotation(); - - abstract Input.Tok modifier(); - - static AnnotationOrModifier ofModifier(Input.Tok m) { - return AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.modifier(m); - } - - static AnnotationOrModifier ofAnnotation(AnnotationTree a) { - return AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.annotation(a); - } - - boolean isModifier() { - return getKind().equals(Kind.MODIFIER); - } - - boolean isAnnotation() { - return getKind().equals(Kind.ANNOTATION); - } - - int position() { - switch (getKind()) { - case MODIFIER: - return modifier().getPosition(); - case ANNOTATION: - return getStartPosition(annotation()); - } - throw new AssertionError(); - } - - private static final Comparator COMPARATOR = - Comparator.comparingInt(AnnotationOrModifier::position); - - @Override - public int compareTo(AnnotationOrModifier o) { - return COMPARATOR.compare(this, o); - } - } - - /** - * The modifiers annotations for a declaration, grouped in to a prefix that contains all of the - * declaration annotations and modifiers, and a suffix of type annotations. - * - *

For examples like {@code @Deprecated public @Nullable Foo foo();}, this allows us to format - * {@code @Deprecated public} as declaration modifiers, and {@code @Nullable} as a type annotation - * on the return type. - */ - @AutoValue - abstract static class DeclarationModifiersAndTypeAnnotations { - abstract ImmutableList declarationModifiers(); - - abstract ImmutableList typeAnnotations(); - - static DeclarationModifiersAndTypeAnnotations create( - ImmutableList declarationModifiers, - ImmutableList typeAnnotations) { - return new AutoValue_JavaInputAstVisitor_DeclarationModifiersAndTypeAnnotations( - declarationModifiers, typeAnnotations); - } - - static DeclarationModifiersAndTypeAnnotations empty() { - return create(ImmutableList.of(), ImmutableList.of()); - } - - boolean hasDeclarationAnnotation() { - return declarationModifiers().stream().anyMatch(AnnotationOrModifier::isAnnotation); - } - } - - /** - * Examines the token stream to convert the modifiers for a declaration into a {@link - * DeclarationModifiersAndTypeAnnotations}. - */ - DeclarationModifiersAndTypeAnnotations splitModifiers( - ModifiersTree modifiersTree, List annotations) { - if (annotations.isEmpty() && !isModifier(builder.peekToken().get())) { - return DeclarationModifiersAndTypeAnnotations.empty(); - } - RangeSet annotationRanges = TreeRangeSet.create(); - for (AnnotationTree annotationTree : annotations) { - annotationRanges.add( - Range.closedOpen( - getStartPosition(annotationTree), getEndPosition(annotationTree, getCurrentPath()))); - } - ImmutableList toks = - builder.peekTokens( - getStartPosition(modifiersTree), - (Input.Tok tok) -> - // ModifiersTree end position information isn't reliable, so scan tokens as long as - // we're seeing annotations or modifiers - annotationRanges.contains(tok.getPosition()) || isModifier(tok.getText())); - ImmutableList modifiers = - Streams.concat( - toks.stream() - // reject tokens from inside AnnotationTrees, we only want modifiers - .filter(t -> !annotationRanges.contains(t.getPosition())) - .map(AnnotationOrModifier::ofModifier), - annotations.stream().map(AnnotationOrModifier::ofAnnotation)) - .sorted() - .collect(toImmutableList()); - // Take a suffix of annotations that are well-known type annotations, and which appear after any - // declaration annotations or modifiers - ImmutableList.Builder typeAnnotations = ImmutableList.builder(); - int idx = modifiers.size() - 1; - while (idx >= 0) { - AnnotationOrModifier modifier = modifiers.get(idx); - if (!modifier.isAnnotation() || !isTypeAnnotation(modifier.annotation())) { - break; - } - typeAnnotations.add(modifier.annotation()); - idx--; - } - return DeclarationModifiersAndTypeAnnotations.create( - modifiers.subList(0, idx + 1), typeAnnotations.build().reverse()); - } - - private void formatAnnotationOrModifier(AnnotationOrModifier modifier) { - switch (modifier.getKind()) { - case MODIFIER: - token(modifier.modifier().getText()); - break; - case ANNOTATION: - scan(modifier.annotation(), null); - break; - } - } - - boolean isTypeAnnotation(AnnotationTree annotationTree) { - Tree annotationType = annotationTree.getAnnotationType(); - if (!(annotationType instanceof IdentifierTree)) { - return false; - } - return typeAnnotationSimpleNames.contains(((IdentifierTree) annotationType).getName()); + return breakFillList(Optional.empty()); } boolean nextIsModifier() { - return isModifier(builder.peekToken().get()); - } - - private static boolean isModifier(String token) { - switch (token) { + switch (builder.peekToken().get()) { case "public": case "protected": case "private": @@ -3091,7 +2877,7 @@ private void visitDotWithPrefix( } /** Returns the simple names of expressions in a "." chain. */ - private static ImmutableList simpleNames(Deque stack) { + private List simpleNames(Deque stack) { ImmutableList.Builder simpleNames = ImmutableList.builder(); OUTER: for (ExpressionTree expression : stack) { @@ -3148,14 +2934,14 @@ private void dotExpressionUpToArgs(ExpressionTree expression, Optional * Returns the base expression of an erray access, e.g. given {@code foo[0][0]} returns {@code * foo}. */ - private static ExpressionTree getArrayBase(ExpressionTree node) { + private ExpressionTree getArrayBase(ExpressionTree node) { while (node instanceof ArrayAccessTree) { node = ((ArrayAccessTree) node).getExpression(); } return node; } - private static ExpressionTree getMethodReceiver(MethodInvocationTree methodInvocation) { + private ExpressionTree getMethodReceiver(MethodInvocationTree methodInvocation) { ExpressionTree select = methodInvocation.getMethodSelect(); return select instanceof MemberSelectTree ? ((MemberSelectTree) select).getExpression() : null; } @@ -3196,7 +2982,7 @@ private void formatArrayIndices(Deque indices) { * Returns all array indices for the given expression, e.g. given {@code foo[0][0]} returns the * expressions for {@code [0][0]}. */ - private static Deque getArrayIndices(ExpressionTree expression) { + private Deque getArrayIndices(ExpressionTree expression) { Deque indices = new ArrayDeque<>(); while (expression instanceof ArrayAccessTree) { ArrayAccessTree array = (ArrayAccessTree) expression; @@ -3496,22 +3282,16 @@ int declareOne( new ArrayDeque<>(typeWithDims.isPresent() ? typeWithDims.get().dims : ImmutableList.of()); int baseDims = 0; - // preprocess to separate declaration annotations + modifiers, type annotations - - DeclarationModifiersAndTypeAnnotations declarationAndTypeModifiers = - modifiers - .map(m -> splitModifiers(m, m.getAnnotations())) - .orElse(DeclarationModifiersAndTypeAnnotations.empty()); builder.open( - kind == DeclarationKind.PARAMETER && declarationAndTypeModifiers.hasDeclarationAnnotation() + kind == DeclarationKind.PARAMETER + && (modifiers.isPresent() && !modifiers.get().getAnnotations().isEmpty()) ? plusFour : ZERO); { - List annotations = - visitModifiers( - declarationAndTypeModifiers, - annotationsDirection, - Optional.of(verticalAnnotationBreak)); + if (modifiers.isPresent()) { + visitAndBreakModifiers( + modifiers.get(), annotationsDirection, Optional.of(verticalAnnotationBreak)); + } boolean isVar = builder.peekToken().get().equals("var") && (!name.contentEquals("var") || builder.peekToken(1).get().equals("var")); @@ -3522,7 +3302,6 @@ int declareOne( { builder.open(ZERO); { - visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); if (typeWithDims.isPresent() && typeWithDims.get().node != null) { scan(typeWithDims.get().node, null); int totalDims = dims.size(); @@ -3794,8 +3573,7 @@ private void classDeclarationTypeList(String token, List types) * *

e.g. {@code int x, y;} is parsed as {@code int x; int y;}. */ - private static List variableFragments( - PeekingIterator it, Tree first) { + private List variableFragments(PeekingIterator it, Tree first) { List fragments = new ArrayList<>(); if (first.getKind() == VARIABLE) { int start = getStartPosition(first); @@ -3845,7 +3623,7 @@ private boolean hasTrailingToken(Input input, List nodes, String * @param modifiers the list of {@link ModifiersTree}s * @return whether the local can be declared with horizontal annotations */ - private static Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifiers) { + private Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifiers) { int parameterlessAnnotations = 0; for (AnnotationTree annotation : modifiers.getAnnotations()) { if (annotation.getArguments().isEmpty()) { @@ -3862,7 +3640,7 @@ private static Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifie * Should a field with a set of modifiers be declared with horizontal annotations? This is * currently true if all annotations are parameterless annotations. */ - private static Direction fieldAnnotationDirection(ModifiersTree modifiers) { + private Direction fieldAnnotationDirection(ModifiersTree modifiers) { for (AnnotationTree annotation : modifiers.getAnnotations()) { if (!annotation.getArguments().isEmpty()) { return Direction.VERTICAL; diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index b0d2a7675..e5227da4b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -18,10 +18,10 @@ import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; +import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.OpsBuilder.BlankLineWanted; import com.google.googlejavaformat.java.JavaInputAstVisitor; -import com.sun.source.tree.AnnotationTree; import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.BlockTree; import com.sun.source.tree.CaseTree; @@ -112,9 +112,7 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) { if (modifiers != null) { - List annotations = - visitModifiers(modifiers, Direction.HORIZONTAL, Optional.empty()); - visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); + builder.addAll(visitModifiers(modifiers, Direction.HORIZONTAL, Optional.empty())); } scan(type, null); builder.breakOp(" "); @@ -162,9 +160,14 @@ public Void visitClass(ClassTree tree, Void unused) { public void visitRecordDeclaration(ClassTree node) { sync(node); - typeDeclarationModifiers(node.getModifiers()); + List breaks = + visitModifiers( + node.getModifiers(), + Direction.VERTICAL, + /* declarationAnnotationBreak= */ Optional.empty()); Verify.verify(node.getExtendsClause() == null); boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); + builder.addAll(breaks); token("record"); builder.space(); visit(node.getSimpleName()); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input deleted file mode 100644 index ddaa8f1ad..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input +++ /dev/null @@ -1,33 +0,0 @@ -import org.checkerframework.checker.nullness.qual.Nullable; - -class TypeAnnotations { - - @Deprecated - public @Nullable Object foo() {} - - public @Deprecated Object foo() {} - - @Nullable Foo handle() { - @Nullable Bar bar = bar(); - try (@Nullable Baz baz = baz()) {} - } - - Foo( - @Nullable Bar // - param1, // - Baz // - param2) {} - - void g( - @Deprecated @Nullable ImmutableList veryVeryLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, - @Deprecated @Nullable ImmutableList veryVeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooong) {} - - @Deprecated @Nullable TypeAnnotations() {} - - enum Foo { - @Nullable - BAR; - } - - @Nullable @Nullable Object doubleTrouble() {} -} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output deleted file mode 100644 index 8dd5d4efc..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output +++ /dev/null @@ -1,39 +0,0 @@ -import org.checkerframework.checker.nullness.qual.Nullable; - -class TypeAnnotations { - - @Deprecated - public @Nullable Object foo() {} - - public @Deprecated Object foo() {} - - @Nullable Foo handle() { - @Nullable Bar bar = bar(); - try (@Nullable Baz baz = baz()) {} - } - - Foo( - @Nullable Bar // - param1, // - Baz // - param2) {} - - void g( - @Deprecated - @Nullable ImmutableList - veryVeryLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, - @Deprecated - @Nullable ImmutableList - veryVeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooong) {} - - @Deprecated - @Nullable - TypeAnnotations() {} - - enum Foo { - @Nullable - BAR; - } - - @Nullable @Nullable Object doubleTrouble() {} -} diff --git a/pom.xml b/pom.xml index c66ed2f23..aa85ac7c2 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,6 @@ 1.0 3.6.1 2.7.1 - 1.8.2 3.1.0 3.2.1 @@ -119,11 +118,6 @@ error_prone_annotations ${errorprone.version} - - com.google.auto.value - auto-value-annotations - ${auto-value.version} - @@ -215,11 +209,6 @@ error_prone_core ${errorprone.version} - - com.google.auto.value - auto-value - ${auto-value.version} - From 865cff01c1bd5b7393f0dd88dbb92a499289e376 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 25 Aug 2021 09:53:59 -0700 Subject: [PATCH 104/379] Format type annotation as part of the type, not part of the modifiers list Given e.g. `@Deprecated @Nullable Object foo() {}`, prefer this: ``` @Deprecated @Nullable Object foo() {} ``` instead of: ``` @Deprecated @Nullable Object foo() {} ``` The implementation is complicated by the fact that the AST doesn't store source position information for modifiers, and there's no requirement that declaration annotations, modifiers, and type annotations appear in any particular order in source. To work around this, we examine the token stream to figure out the ordering of the modifiers and annotations. https://github.com/google/google-java-format/issues/5 Roll forward of https://github.com/google/google-java-format/commit/1a875792f6a074f3f0a504ddb8c7cd932ba6b073 without a use of a server-only Guava API. PiperOrigin-RevId: 392919024 --- core/pom.xml | 6 +- .../google/googlejavaformat/OpsBuilder.java | 24 ++ .../java/JavaInputAstVisitor.java | 348 +++++++++++++++--- .../java/java14/Java14InputAstVisitor.java | 13 +- .../java/testdata/TypeAnnotations.input | 33 ++ .../java/testdata/TypeAnnotations.output | 39 ++ pom.xml | 11 + 7 files changed, 406 insertions(+), 68 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output diff --git a/core/pom.xml b/core/pom.xml index 74b7504ac..e8e9bf249 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -51,7 +51,11 @@ error_prone_annotations true - + + com.google.auto.value + auto-value-annotations + true + diff --git a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java index 36e038adf..db431c040 100644 --- a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java +++ b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java @@ -18,6 +18,8 @@ import static java.lang.Math.min; import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -281,6 +283,28 @@ public final Optional peekToken(int skip) { : Optional.empty(); } + /** + * Returns the {@link Input.Tok}s starting at the current source position, which are satisfied by + * the given predicate. + */ + public ImmutableList peekTokens(int startPosition, Predicate predicate) { + ImmutableList tokens = input.getTokens(); + Preconditions.checkState( + tokens.get(tokenI).getTok().getPosition() == startPosition, + "Expected the current token to be at position %s, found: %s", + startPosition, + tokens.get(tokenI)); + ImmutableList.Builder result = ImmutableList.builder(); + for (int idx = tokenI; idx < tokens.size(); idx++) { + Tok tok = tokens.get(idx).getTok(); + if (!predicate.apply(tok)) { + break; + } + result.add(tok); + } + return result.build(); + } + /** * Emit an optional token iff it exists on the input. This is used to emit tokens whose existence * has been lost in the AST. diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 372f3bb59..8da719564 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -43,19 +43,27 @@ import static com.sun.source.tree.Tree.Kind.VARIABLE; import static java.util.stream.Collectors.toList; +import com.google.auto.value.AutoOneOf; +import com.google.auto.value.AutoValue; import com.google.common.base.MoreObjects; import com.google.common.base.Predicate; import com.google.common.base.Throwables; import com.google.common.base.Verify; import com.google.common.collect.HashMultiset; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import com.google.common.collect.Multiset; import com.google.common.collect.PeekingIterator; +import com.google.common.collect.Range; +import com.google.common.collect.RangeSet; import com.google.common.collect.Streams; +import com.google.common.collect.TreeRangeSet; +import com.google.errorprone.annotations.CheckReturnValue; import com.google.googlejavaformat.CloseOp; import com.google.googlejavaformat.Doc; import com.google.googlejavaformat.Doc.FillMode; @@ -139,7 +147,9 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.Deque; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -167,7 +177,7 @@ boolean isVertical() { } /** Whether to break or not. */ - enum BreakOrNot { + protected enum BreakOrNot { YES, NO; @@ -268,6 +278,21 @@ boolean isYes() { } } + // TODO(cushon): generalize this + private static final ImmutableMultimap TYPE_ANNOTATIONS = typeAnnotations(); + + private static ImmutableSetMultimap typeAnnotations() { + ImmutableSetMultimap.Builder result = ImmutableSetMultimap.builder(); + for (String annotation : + ImmutableList.of( + "org.jspecify.nullness.Nullable", + "org.checkerframework.checker.nullness.qual.Nullable")) { + String simpleName = annotation.substring(annotation.lastIndexOf('.') + 1); + result.put(simpleName, annotation); + } + return result.build(); + } + protected final OpsBuilder builder; protected static final Indent.Const ZERO = Indent.Const.ZERO; @@ -277,6 +302,8 @@ boolean isYes() { protected final Indent.Const plusTwo; protected final Indent.Const plusFour; + private final Set typeAnnotationSimpleNames = new HashSet<>(); + private static final ImmutableList breakList(Optional breakTag) { return ImmutableList.of(Doc.Break.make(Doc.FillMode.UNIFIED, " ", ZERO, breakTag)); } @@ -292,8 +319,6 @@ private static final ImmutableList forceBreakList(Optional breakTa return ImmutableList.of(Doc.Break.make(FillMode.FORCED, "", Indent.Const.ZERO, breakTag)); } - private static final ImmutableList EMPTY_LIST = ImmutableList.of(); - /** * Allow multi-line filling (of array initializers, argument lists, and boolean expressions) for * items with length less than or equal to this threshold. @@ -417,10 +442,7 @@ public Void visitClass(ClassTree tree, Void unused) { public void visitAnnotationType(ClassTree node) { sync(node); builder.open(ZERO); - visitAndBreakModifiers( - node.getModifiers(), - Direction.VERTICAL, - /* declarationAnnotationBreak= */ Optional.empty()); + typeDeclarationModifiers(node.getModifiers()); builder.open(ZERO); token("@"); token("interface"); @@ -679,9 +701,10 @@ public Void visitNewClass(NewClassTree node, Void unused) { builder.space(); addTypeArguments(node.getTypeArguments(), plusFour); if (node.getClassBody() != null) { - builder.addAll( + List annotations = visitModifiers( - node.getClassBody().getModifiers(), Direction.HORIZONTAL, Optional.empty())); + node.getClassBody().getModifiers(), Direction.HORIZONTAL, Optional.empty()); + visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); } scan(node.getIdentifier(), null); addArguments(node.getArguments(), plusFour); @@ -802,10 +825,7 @@ private void visitEnumConstantDeclaration(VariableTree enumConstant) { public boolean visitEnumDeclaration(ClassTree node) { sync(node); builder.open(ZERO); - visitAndBreakModifiers( - node.getModifiers(), - Direction.VERTICAL, - /* declarationAnnotationBreak= */ Optional.empty()); + typeDeclarationModifiers(node.getModifiers()); builder.open(plusFour); token("enum"); builder.breakOp(" "); @@ -969,7 +989,7 @@ void visitVariables( } } - private TypeWithDims variableFragmentDims(boolean first, int leadingDims, Tree type) { + private static TypeWithDims variableFragmentDims(boolean first, int leadingDims, Tree type) { if (type == null) { return null; } @@ -1114,6 +1134,7 @@ public Void visitIf(IfTree node, Void unused) { @Override public Void visitImport(ImportTree node, Void unused) { + checkForTypeAnnotation(node); sync(node); token("import"); builder.space(); @@ -1128,6 +1149,21 @@ public Void visitImport(ImportTree node, Void unused) { return null; } + private void checkForTypeAnnotation(ImportTree node) { + Name simpleName = getSimpleName(node); + Collection wellKnownAnnotations = TYPE_ANNOTATIONS.get(simpleName.toString()); + if (!wellKnownAnnotations.isEmpty() + && wellKnownAnnotations.contains(node.getQualifiedIdentifier().toString())) { + typeAnnotationSimpleNames.add(simpleName); + } + } + + private static Name getSimpleName(ImportTree importTree) { + return importTree.getQualifiedIdentifier() instanceof IdentifierTree + ? ((IdentifierTree) importTree.getQualifiedIdentifier()).getName() + : ((MemberSelectTree) importTree.getQualifiedIdentifier()).getIdentifier(); + } + @Override public Void visitBinary(BinaryTree node, Void unused) { sync(node); @@ -1360,9 +1396,12 @@ public Void visitMethod(MethodTree node, Void unused) { } } } - builder.addAll( + List typeAnnotations = visitModifiers( - annotations, Direction.VERTICAL, /* declarationAnnotationBreak= */ Optional.empty())); + node.getModifiers(), + annotations, + Direction.VERTICAL, + /* declarationAnnotationBreak= */ Optional.empty()); Tree baseReturnType = null; Deque> dims = null; @@ -1371,6 +1410,9 @@ public Void visitMethod(MethodTree node, Void unused) { DimensionHelpers.extractDims(node.getReturnType(), SortedDims.YES); baseReturnType = extractedDims.node; dims = new ArrayDeque<>(extractedDims.dims); + } else { + verticalAnnotations(typeAnnotations); + typeAnnotations = ImmutableList.of(); } builder.open(plusFour); @@ -1379,7 +1421,14 @@ public Void visitMethod(MethodTree node, Void unused) { builder.open(ZERO); { boolean first = true; + if (!typeAnnotations.isEmpty()) { + visitAnnotations(typeAnnotations, BreakOrNot.NO, BreakOrNot.NO); + first = false; + } if (!node.getTypeParameters().isEmpty()) { + if (!first) { + builder.breakToFill(" "); + } token("<"); typeParametersRest(node.getTypeParameters(), plusFour); if (!returnTypeAnnotations.isEmpty()) { @@ -1956,16 +2005,11 @@ public Void visitTry(TryTree node, Void unused) { public void visitClassDeclaration(ClassTree node) { sync(node); - List breaks = - visitModifiers( - node.getModifiers(), - Direction.VERTICAL, - /* declarationAnnotationBreak= */ Optional.empty()); + typeDeclarationModifiers(node.getModifiers()); List permitsTypes = getPermitsClause(node); boolean hasSuperclassType = node.getExtendsClause() != null; boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); boolean hasPermitsTypes = !permitsTypes.isEmpty(); - builder.addAll(breaks); token(node.getKind() == Tree.Kind.INTERFACE ? "interface" : "class"); builder.space(); visit(node.getSimpleName()); @@ -2069,7 +2113,7 @@ public Void visitWildcard(WildcardTree node, Void unused) { // Helper methods. /** Helper method for annotations. */ - void visitAnnotations( + protected void visitAnnotations( List annotations, BreakOrNot breakBefore, BreakOrNot breakAfter) { if (!annotations.isEmpty()) { if (breakBefore.isYes()) { @@ -2089,6 +2133,14 @@ void visitAnnotations( } } + void verticalAnnotations(List annotations) { + for (AnnotationTree annotation : annotations) { + builder.forcedBreak(); + scan(annotation, null); + builder.forcedBreak(); + } + } + /** Helper method for blocks. */ protected void visitBlock( BlockTree node, @@ -2176,12 +2228,21 @@ protected void visitStatements(List statements) { } } + protected void typeDeclarationModifiers(ModifiersTree modifiers) { + List typeAnnotations = + visitModifiers( + modifiers, Direction.VERTICAL, /* declarationAnnotationBreak= */ Optional.empty()); + verticalAnnotations(typeAnnotations); + } + /** Output combined modifiers and annotations and the trailing break. */ void visitAndBreakModifiers( ModifiersTree modifiers, Direction annotationDirection, Optional declarationAnnotationBreak) { - builder.addAll(visitModifiers(modifiers, annotationDirection, declarationAnnotationBreak)); + List typeAnnotations = + visitModifiers(modifiers, annotationDirection, declarationAnnotationBreak); + visitAnnotations(typeAnnotations, BreakOrNot.NO, BreakOrNot.YES); } @Override @@ -2190,36 +2251,50 @@ public Void visitModifiers(ModifiersTree node, Void unused) { } /** Output combined modifiers and annotations and returns the trailing break. */ - protected List visitModifiers( + @CheckReturnValue + protected ImmutableList visitModifiers( ModifiersTree modifiersTree, Direction annotationsDirection, Optional declarationAnnotationBreak) { return visitModifiers( - modifiersTree.getAnnotations(), annotationsDirection, declarationAnnotationBreak); + modifiersTree, + modifiersTree.getAnnotations(), + annotationsDirection, + declarationAnnotationBreak); } - protected List visitModifiers( + @CheckReturnValue + protected ImmutableList visitModifiers( + ModifiersTree modifiersTree, List annotationTrees, Direction annotationsDirection, Optional declarationAnnotationBreak) { - if (annotationTrees.isEmpty() && !nextIsModifier()) { - return EMPTY_LIST; + DeclarationModifiersAndTypeAnnotations splitModifiers = + splitModifiers(modifiersTree, annotationTrees); + return visitModifiers(splitModifiers, annotationsDirection, declarationAnnotationBreak); + } + + @CheckReturnValue + private ImmutableList visitModifiers( + DeclarationModifiersAndTypeAnnotations splitModifiers, + Direction annotationsDirection, + Optional declarationAnnotationBreak) { + if (splitModifiers.declarationModifiers().isEmpty()) { + return splitModifiers.typeAnnotations(); } - Deque annotations = new ArrayDeque<>(annotationTrees); + Deque declarationModifiers = + new ArrayDeque<>(splitModifiers.declarationModifiers()); builder.open(ZERO); boolean first = true; boolean lastWasAnnotation = false; - while (!annotations.isEmpty()) { - if (nextIsModifier()) { - break; - } + while (!declarationModifiers.isEmpty() && !declarationModifiers.peekFirst().isModifier()) { if (!first) { builder.addAll( annotationsDirection.isVertical() ? forceBreakList(declarationAnnotationBreak) : breakList(declarationAnnotationBreak)); } - scan(annotations.removeFirst(), null); + formatAnnotationOrModifier(declarationModifiers.removeFirst()); first = false; lastWasAnnotation = true; } @@ -2228,8 +2303,9 @@ protected List visitModifiers( annotationsDirection.isVertical() ? forceBreakList(declarationAnnotationBreak) : breakList(declarationAnnotationBreak); - if (annotations.isEmpty() && !nextIsModifier()) { - return trailingBreak; + if (declarationModifiers.isEmpty()) { + builder.addAll(trailingBreak); + return splitModifiers.typeAnnotations(); } if (lastWasAnnotation) { builder.addAll(trailingBreak); @@ -2237,24 +2313,170 @@ protected List visitModifiers( builder.open(ZERO); first = true; - while (nextIsModifier() || !annotations.isEmpty()) { + while (!declarationModifiers.isEmpty()) { if (!first) { builder.addAll(breakFillList(Optional.empty())); } - if (nextIsModifier()) { - token(builder.peekToken().get()); - } else { - scan(annotations.removeFirst(), null); - lastWasAnnotation = true; - } + formatAnnotationOrModifier(declarationModifiers.removeFirst()); first = false; } builder.close(); - return breakFillList(Optional.empty()); + builder.addAll(breakFillList(Optional.empty())); + return splitModifiers.typeAnnotations(); + } + + /** Represents an annotation or a modifier in a {@link ModifiersTree}. */ + @AutoOneOf(AnnotationOrModifier.Kind.class) + abstract static class AnnotationOrModifier implements Comparable { + enum Kind { + MODIFIER, + ANNOTATION + } + + abstract Kind getKind(); + + abstract AnnotationTree annotation(); + + abstract Input.Tok modifier(); + + static AnnotationOrModifier ofModifier(Input.Tok m) { + return AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.modifier(m); + } + + static AnnotationOrModifier ofAnnotation(AnnotationTree a) { + return AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.annotation(a); + } + + boolean isModifier() { + return getKind().equals(Kind.MODIFIER); + } + + boolean isAnnotation() { + return getKind().equals(Kind.ANNOTATION); + } + + int position() { + switch (getKind()) { + case MODIFIER: + return modifier().getPosition(); + case ANNOTATION: + return getStartPosition(annotation()); + } + throw new AssertionError(); + } + + private static final Comparator COMPARATOR = + Comparator.comparingInt(AnnotationOrModifier::position); + + @Override + public int compareTo(AnnotationOrModifier o) { + return COMPARATOR.compare(this, o); + } + } + + /** + * The modifiers annotations for a declaration, grouped in to a prefix that contains all of the + * declaration annotations and modifiers, and a suffix of type annotations. + * + *

For examples like {@code @Deprecated public @Nullable Foo foo();}, this allows us to format + * {@code @Deprecated public} as declaration modifiers, and {@code @Nullable} as a type annotation + * on the return type. + */ + @AutoValue + abstract static class DeclarationModifiersAndTypeAnnotations { + abstract ImmutableList declarationModifiers(); + + abstract ImmutableList typeAnnotations(); + + static DeclarationModifiersAndTypeAnnotations create( + ImmutableList declarationModifiers, + ImmutableList typeAnnotations) { + return new AutoValue_JavaInputAstVisitor_DeclarationModifiersAndTypeAnnotations( + declarationModifiers, typeAnnotations); + } + + static DeclarationModifiersAndTypeAnnotations empty() { + return create(ImmutableList.of(), ImmutableList.of()); + } + + boolean hasDeclarationAnnotation() { + return declarationModifiers().stream().anyMatch(AnnotationOrModifier::isAnnotation); + } + } + + /** + * Examines the token stream to convert the modifiers for a declaration into a {@link + * DeclarationModifiersAndTypeAnnotations}. + */ + DeclarationModifiersAndTypeAnnotations splitModifiers( + ModifiersTree modifiersTree, List annotations) { + if (annotations.isEmpty() && !isModifier(builder.peekToken().get())) { + return DeclarationModifiersAndTypeAnnotations.empty(); + } + RangeSet annotationRanges = TreeRangeSet.create(); + for (AnnotationTree annotationTree : annotations) { + annotationRanges.add( + Range.closedOpen( + getStartPosition(annotationTree), getEndPosition(annotationTree, getCurrentPath()))); + } + ImmutableList toks = + builder.peekTokens( + getStartPosition(modifiersTree), + (Input.Tok tok) -> + // ModifiersTree end position information isn't reliable, so scan tokens as long as + // we're seeing annotations or modifiers + annotationRanges.contains(tok.getPosition()) || isModifier(tok.getText())); + ImmutableList modifiers = + ImmutableList.copyOf( + Streams.concat( + toks.stream() + // reject tokens from inside AnnotationTrees, we only want modifiers + .filter(t -> !annotationRanges.contains(t.getPosition())) + .map(AnnotationOrModifier::ofModifier), + annotations.stream().map(AnnotationOrModifier::ofAnnotation)) + .sorted() + .collect(toList())); + // Take a suffix of annotations that are well-known type annotations, and which appear after any + // declaration annotations or modifiers + ImmutableList.Builder typeAnnotations = ImmutableList.builder(); + int idx = modifiers.size() - 1; + while (idx >= 0) { + AnnotationOrModifier modifier = modifiers.get(idx); + if (!modifier.isAnnotation() || !isTypeAnnotation(modifier.annotation())) { + break; + } + typeAnnotations.add(modifier.annotation()); + idx--; + } + return DeclarationModifiersAndTypeAnnotations.create( + modifiers.subList(0, idx + 1), typeAnnotations.build().reverse()); + } + + private void formatAnnotationOrModifier(AnnotationOrModifier modifier) { + switch (modifier.getKind()) { + case MODIFIER: + token(modifier.modifier().getText()); + break; + case ANNOTATION: + scan(modifier.annotation(), null); + break; + } + } + + boolean isTypeAnnotation(AnnotationTree annotationTree) { + Tree annotationType = annotationTree.getAnnotationType(); + if (!(annotationType instanceof IdentifierTree)) { + return false; + } + return typeAnnotationSimpleNames.contains(((IdentifierTree) annotationType).getName()); } boolean nextIsModifier() { - switch (builder.peekToken().get()) { + return isModifier(builder.peekToken().get()); + } + + private static boolean isModifier(String token) { + switch (token) { case "public": case "protected": case "private": @@ -2877,7 +3099,7 @@ private void visitDotWithPrefix( } /** Returns the simple names of expressions in a "." chain. */ - private List simpleNames(Deque stack) { + private static ImmutableList simpleNames(Deque stack) { ImmutableList.Builder simpleNames = ImmutableList.builder(); OUTER: for (ExpressionTree expression : stack) { @@ -2934,14 +3156,14 @@ private void dotExpressionUpToArgs(ExpressionTree expression, Optional * Returns the base expression of an erray access, e.g. given {@code foo[0][0]} returns {@code * foo}. */ - private ExpressionTree getArrayBase(ExpressionTree node) { + private static ExpressionTree getArrayBase(ExpressionTree node) { while (node instanceof ArrayAccessTree) { node = ((ArrayAccessTree) node).getExpression(); } return node; } - private ExpressionTree getMethodReceiver(MethodInvocationTree methodInvocation) { + private static ExpressionTree getMethodReceiver(MethodInvocationTree methodInvocation) { ExpressionTree select = methodInvocation.getMethodSelect(); return select instanceof MemberSelectTree ? ((MemberSelectTree) select).getExpression() : null; } @@ -2982,7 +3204,7 @@ private void formatArrayIndices(Deque indices) { * Returns all array indices for the given expression, e.g. given {@code foo[0][0]} returns the * expressions for {@code [0][0]}. */ - private Deque getArrayIndices(ExpressionTree expression) { + private static Deque getArrayIndices(ExpressionTree expression) { Deque indices = new ArrayDeque<>(); while (expression instanceof ArrayAccessTree) { ArrayAccessTree array = (ArrayAccessTree) expression; @@ -3282,16 +3504,22 @@ int declareOne( new ArrayDeque<>(typeWithDims.isPresent() ? typeWithDims.get().dims : ImmutableList.of()); int baseDims = 0; + // preprocess to separate declaration annotations + modifiers, type annotations + + DeclarationModifiersAndTypeAnnotations declarationAndTypeModifiers = + modifiers + .map(m -> splitModifiers(m, m.getAnnotations())) + .orElse(DeclarationModifiersAndTypeAnnotations.empty()); builder.open( - kind == DeclarationKind.PARAMETER - && (modifiers.isPresent() && !modifiers.get().getAnnotations().isEmpty()) + kind == DeclarationKind.PARAMETER && declarationAndTypeModifiers.hasDeclarationAnnotation() ? plusFour : ZERO); { - if (modifiers.isPresent()) { - visitAndBreakModifiers( - modifiers.get(), annotationsDirection, Optional.of(verticalAnnotationBreak)); - } + List annotations = + visitModifiers( + declarationAndTypeModifiers, + annotationsDirection, + Optional.of(verticalAnnotationBreak)); boolean isVar = builder.peekToken().get().equals("var") && (!name.contentEquals("var") || builder.peekToken(1).get().equals("var")); @@ -3302,6 +3530,7 @@ int declareOne( { builder.open(ZERO); { + visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); if (typeWithDims.isPresent() && typeWithDims.get().node != null) { scan(typeWithDims.get().node, null); int totalDims = dims.size(); @@ -3573,7 +3802,8 @@ private void classDeclarationTypeList(String token, List types) * *

e.g. {@code int x, y;} is parsed as {@code int x; int y;}. */ - private List variableFragments(PeekingIterator it, Tree first) { + private static List variableFragments( + PeekingIterator it, Tree first) { List fragments = new ArrayList<>(); if (first.getKind() == VARIABLE) { int start = getStartPosition(first); @@ -3623,7 +3853,7 @@ private boolean hasTrailingToken(Input input, List nodes, String * @param modifiers the list of {@link ModifiersTree}s * @return whether the local can be declared with horizontal annotations */ - private Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifiers) { + private static Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifiers) { int parameterlessAnnotations = 0; for (AnnotationTree annotation : modifiers.getAnnotations()) { if (annotation.getArguments().isEmpty()) { @@ -3640,7 +3870,7 @@ private Direction canLocalHaveHorizontalAnnotations(ModifiersTree modifiers) { * Should a field with a set of modifiers be declared with horizontal annotations? This is * currently true if all annotations are parameterless annotations. */ - private Direction fieldAnnotationDirection(ModifiersTree modifiers) { + private static Direction fieldAnnotationDirection(ModifiersTree modifiers) { for (AnnotationTree annotation : modifiers.getAnnotations()) { if (!annotation.getArguments().isEmpty()) { return Direction.VERTICAL; diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index e5227da4b..b0d2a7675 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -18,10 +18,10 @@ import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; -import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.OpsBuilder.BlankLineWanted; import com.google.googlejavaformat.java.JavaInputAstVisitor; +import com.sun.source.tree.AnnotationTree; import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.BlockTree; import com.sun.source.tree.CaseTree; @@ -112,7 +112,9 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) { if (modifiers != null) { - builder.addAll(visitModifiers(modifiers, Direction.HORIZONTAL, Optional.empty())); + List annotations = + visitModifiers(modifiers, Direction.HORIZONTAL, Optional.empty()); + visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); } scan(type, null); builder.breakOp(" "); @@ -160,14 +162,9 @@ public Void visitClass(ClassTree tree, Void unused) { public void visitRecordDeclaration(ClassTree node) { sync(node); - List breaks = - visitModifiers( - node.getModifiers(), - Direction.VERTICAL, - /* declarationAnnotationBreak= */ Optional.empty()); + typeDeclarationModifiers(node.getModifiers()); Verify.verify(node.getExtendsClause() == null); boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); - builder.addAll(breaks); token("record"); builder.space(); visit(node.getSimpleName()); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input new file mode 100644 index 000000000..ddaa8f1ad --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input @@ -0,0 +1,33 @@ +import org.checkerframework.checker.nullness.qual.Nullable; + +class TypeAnnotations { + + @Deprecated + public @Nullable Object foo() {} + + public @Deprecated Object foo() {} + + @Nullable Foo handle() { + @Nullable Bar bar = bar(); + try (@Nullable Baz baz = baz()) {} + } + + Foo( + @Nullable Bar // + param1, // + Baz // + param2) {} + + void g( + @Deprecated @Nullable ImmutableList veryVeryLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, + @Deprecated @Nullable ImmutableList veryVeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooong) {} + + @Deprecated @Nullable TypeAnnotations() {} + + enum Foo { + @Nullable + BAR; + } + + @Nullable @Nullable Object doubleTrouble() {} +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output new file mode 100644 index 000000000..8dd5d4efc --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output @@ -0,0 +1,39 @@ +import org.checkerframework.checker.nullness.qual.Nullable; + +class TypeAnnotations { + + @Deprecated + public @Nullable Object foo() {} + + public @Deprecated Object foo() {} + + @Nullable Foo handle() { + @Nullable Bar bar = bar(); + try (@Nullable Baz baz = baz()) {} + } + + Foo( + @Nullable Bar // + param1, // + Baz // + param2) {} + + void g( + @Deprecated + @Nullable ImmutableList + veryVeryLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong, + @Deprecated + @Nullable ImmutableList + veryVeryLoooooooooooooooooooooooooooooooooooooooooooooooooooooooong) {} + + @Deprecated + @Nullable + TypeAnnotations() {} + + enum Foo { + @Nullable + BAR; + } + + @Nullable @Nullable Object doubleTrouble() {} +} diff --git a/pom.xml b/pom.xml index aa85ac7c2..c66ed2f23 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,7 @@ 1.0 3.6.1 2.7.1 + 1.8.2 3.1.0 3.2.1 @@ -118,6 +119,11 @@ error_prone_annotations ${errorprone.version} + + com.google.auto.value + auto-value-annotations + ${auto-value.version} + @@ -209,6 +215,11 @@ error_prone_core ${errorprone.version} + + com.google.auto.value + auto-value + ${auto-value.version} + From 79257edbf26894102793b00a19fe4b68d83e5622 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 25 Aug 2021 13:24:47 -0700 Subject: [PATCH 105/379] Fix indentation of case statements on JDK 17 Fixes https://github.com/google/google-java-format/issues/643 PiperOrigin-RevId: 392966720 --- .../java/java14/Java14InputAstVisitor.java | 2 +- .../googlejavaformat/java/testdata/I643.input | 14 ++++++++++++++ .../googlejavaformat/java/testdata/I643.output | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I643.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I643.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index b0d2a7675..3facbd711 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -251,7 +251,7 @@ public Void visitCase(CaseTree node, Void unused) { token("default", plusTwo); } else { token("case", plusTwo); - builder.open(plusFour); + builder.open(node.getExpressions().size() > 1 ? plusFour : ZERO); builder.space(); boolean first = true; for (ExpressionTree expression : node.getExpressions()) { diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I643.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I643.input new file mode 100644 index 000000000..a31a230be --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I643.input @@ -0,0 +1,14 @@ +public class Foo { + static final int VERBOSE_WORDY_AND_LENGTHY_ONE = 1; + static final int VERBOSE_WORDY_AND_LENGTHY_TWO = 2; + static final int VERBOSE_WORDY_AND_LENGTHY_FOUR = 4; + + public static int fn(int x) { + switch (x) { + case VERBOSE_WORDY_AND_LENGTHY_ONE | VERBOSE_WORDY_AND_LENGTHY_TWO | VERBOSE_WORDY_AND_LENGTHY_FOUR: + return 0; + default: + return 1; + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I643.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I643.output new file mode 100644 index 000000000..945cbea14 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I643.output @@ -0,0 +1,16 @@ +public class Foo { + static final int VERBOSE_WORDY_AND_LENGTHY_ONE = 1; + static final int VERBOSE_WORDY_AND_LENGTHY_TWO = 2; + static final int VERBOSE_WORDY_AND_LENGTHY_FOUR = 4; + + public static int fn(int x) { + switch (x) { + case VERBOSE_WORDY_AND_LENGTHY_ONE + | VERBOSE_WORDY_AND_LENGTHY_TWO + | VERBOSE_WORDY_AND_LENGTHY_FOUR: + return 0; + default: + return 1; + } + } +} From 3fc15f7c5de79cf74ef95343aa8562a9c3b2dd2c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 25 Aug 2021 15:36:46 -0700 Subject: [PATCH 106/379] Clean up some redundancies PiperOrigin-RevId: 392995117 --- core/src/main/java/com/google/googlejavaformat/java/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 451bc697c..4056f2ae3 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -41,7 +41,7 @@ public final class Main { private static final int MAX_THREADS = 20; private static final String STDIN_FILENAME = ""; - static final String versionString() { + static String versionString() { return "google-java-format: Version " + GoogleJavaFormatVersion.version(); } From 86db2b1609031532780af159a59dd1814227ea2b Mon Sep 17 00:00:00 2001 From: nlupien <68999381+nlupien@users.noreply.github.com> Date: Thu, 26 Aug 2021 07:51:10 -0700 Subject: [PATCH 107/379] Make the formatJavadoc option public. Right now the `formatJavadoc` option in the `JavaFormatterOptions` isn't tag as either public or private so it gets the default package private scope. This change makes it public so other projects using this as a dependency can change this option. In regards to tests, I'm not sure how to add the relevant test to validate the scope change but since we don't generally test scope, I assume we can skip them?. Fixes #512 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/512 from nlupien:make_format_javadoc_option_public 77e01d177b97934250d97a51ff9de569c3e5a436 PiperOrigin-RevId: 393123739 --- .../google/googlejavaformat/java/JavaFormatterOptions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java b/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java index 4d3d30d4c..fbb6fe7e4 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java @@ -60,7 +60,7 @@ public int indentationMultiplier() { return style.indentationMultiplier(); } - boolean formatJavadoc() { + public boolean formatJavadoc() { return formatJavadoc; } @@ -91,7 +91,7 @@ public Builder style(Style style) { return this; } - Builder formatJavadoc(boolean formatJavadoc) { + public Builder formatJavadoc(boolean formatJavadoc) { this.formatJavadoc = formatJavadoc; return this; } From 129a70dd911566f3089796568a975afa98899b73 Mon Sep 17 00:00:00 2001 From: cpovirk Date: Thu, 26 Aug 2021 13:55:47 -0700 Subject: [PATCH 108/379] Correct package name of javax.annotation.Nullable. It doesn't really matter, since we don't look things up in a classpath. But as we begin experimenting with recognizing specific fully qualified annotation names, there's an 0.1% change that it will matter somehow. And I just stumbled across this typo while doing research, so I figured I'd make sure it never matters. PiperOrigin-RevId: 393200270 --- .../java/com/google/googlejavaformat/java/FormatterTest.java | 4 ++-- .../com/google/googlejavaformat/java/ImportOrdererTest.java | 4 ++-- .../java/testimports/A.formatting-and-import-sorting | 2 +- .../java/testimports/A.formatting-and-unused-import-removal | 2 +- .../googlejavaformat/java/testimports/A.formatting-only | 2 +- .../java/testimports/A.imports-and-formatting | 2 +- .../google/googlejavaformat/java/testimports/A.imports-only | 2 +- .../com/google/googlejavaformat/java/testimports/A.input | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java index 9859245c7..1653e5645 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java @@ -238,7 +238,7 @@ public void voidMethod() throws FormatterException { "", "import java.util.List;", "", - "import javax.annotations.Nullable;"); + "import javax.annotation.Nullable;"); @Test public void importsNotReorderedByDefault() throws FormatterException { @@ -262,7 +262,7 @@ public void importsFixedIfRequested() throws FormatterException { String expect = "package com.google.example;\n\n" + "import java.util.List;\n" - + "import javax.annotations.Nullable;\n\n" + + "import javax.annotation.Nullable;\n\n" + "public class ExampleTest {\n" + " @Nullable List xs;\n" + "}\n"; diff --git a/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java b/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java index f40fa3821..0b9dab26f 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java @@ -313,7 +313,7 @@ public static Collection parameters() { "", "import java.util.List;", "", - "import javax.annotations.Nullable;", + "import javax.annotation.Nullable;", "", "import static org.junit.Assert.fail;", "import static com.google.truth.Truth.assertThat;", @@ -329,7 +329,7 @@ public static Collection parameters() { "", "import com.google.common.base.Preconditions;", "import java.util.List;", - "import javax.annotations.Nullable;", + "import javax.annotation.Nullable;", "import org.junit.runner.RunWith;", "import org.junit.runners.JUnit4;", "", diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-and-import-sorting b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-and-import-sorting index e6994f7fd..8d144c2c7 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-and-import-sorting +++ b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-and-import-sorting @@ -6,7 +6,7 @@ import static org.junit.Assert.fail; import com.google.common.base.Preconditions; import java.util.List; import java.util.Set; -import javax.annotations.Nullable; +import javax.annotation.Nullable; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-and-unused-import-removal b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-and-unused-import-removal index 7d5df53cb..9b1d01f3f 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-and-unused-import-removal +++ b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-and-unused-import-removal @@ -7,7 +7,7 @@ import org.junit.runners.JUnit4; import java.util.List; -import javax.annotations.Nullable; +import javax.annotation.Nullable; import static org.junit.Assert.fail; import static com.google.truth.Truth.assertThat; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-only b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-only index 7d5df53cb..9b1d01f3f 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-only +++ b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.formatting-only @@ -7,7 +7,7 @@ import org.junit.runners.JUnit4; import java.util.List; -import javax.annotations.Nullable; +import javax.annotation.Nullable; import static org.junit.Assert.fail; import static com.google.truth.Truth.assertThat; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.imports-and-formatting b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.imports-and-formatting index 887d43c6e..d7bcd6d9b 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.imports-and-formatting +++ b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.imports-and-formatting @@ -5,7 +5,7 @@ import static org.junit.Assert.fail; import com.google.common.base.Preconditions; import java.util.List; -import javax.annotations.Nullable; +import javax.annotation.Nullable; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.imports-only b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.imports-only index 88f83f187..a50a83ec1 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.imports-only +++ b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.imports-only @@ -5,7 +5,7 @@ import static org.junit.Assert.fail; import com.google.common.base.Preconditions; import java.util.List; -import javax.annotations.Nullable; +import javax.annotation.Nullable; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.input b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.input index be1eacda1..dd992a32f 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testimports/A.input @@ -8,7 +8,7 @@ import org.junit.runners.JUnit4; import java.util.List; import java.util.Set; -import javax.annotations.Nullable; +import javax.annotation.Nullable; import static org.junit.Assert.fail; import static com.google.truth.Truth.assertThat; From 67f75cb5a5377346266a8ae93526c6bc5a7cb36c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 2 Sep 2021 15:35:02 -0700 Subject: [PATCH 109/379] Migrate from adopt https://github.com/actions/setup-java#supported-distributions https://blog.adoptopenjdk.net/2021/08/goodbye-adoptopenjdk-hello-adoptium/ PiperOrigin-RevId: 394558213 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cfd9cf37b..7f4080a67 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,7 @@ jobs: uses: actions/setup-java@v2 with: java-version: ${{ matrix.java }} - distribution: 'adopt' + distribution: 'zulu' - name: 'Install' shell: bash run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V @@ -90,7 +90,7 @@ jobs: uses: actions/setup-java@v2 with: java-version: 15 - distribution: 'adopt' + distribution: 'zulu' server-id: sonatype-nexus-snapshots server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD From 8490fce70fc6182e1b298fe08ec9eda2961c525e Mon Sep 17 00:00:00 2001 From: Daniel Kraus Date: Thu, 9 Sep 2021 04:49:52 -0700 Subject: [PATCH 110/379] Cache local Maven repository via actions/setup-java As of August 30, ["`setup-java` supports caching for both Gradle and Maven projects"](https://github.blog/changelog/2021-08-30-github-actions-setup-java-now-supports-dependency-caching/). This helps to reduce the amount of boilerplate code in the workflow file. More details can be found in the [corresponding docs](https://github.com/actions/setup-java#caching-packages-dependencies). (And if you wonder what's the used cache key format: https://github.com/actions/setup-java/pull/215/) Fixes #660 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/660 from beatngu13:patch-1 47e262b489e0f3ce795413bd10b7fe50a22ca2c6 PiperOrigin-RevId: 395674252 --- .github/workflows/ci.yml | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f4080a67..0386892e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,18 +52,12 @@ jobs: access_token: ${{ github.token }} - name: 'Check out repository' uses: actions/checkout@v2 - - name: 'Cache local Maven repository' - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: 'Set up JDK ${{ matrix.java }}' uses: actions/setup-java@v2 with: java-version: ${{ matrix.java }} distribution: 'zulu' + cache: 'maven' - name: 'Install' shell: bash run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V @@ -79,18 +73,12 @@ jobs: steps: - name: 'Check out repository' uses: actions/checkout@v2 - - name: 'Cache local Maven repository' - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - name: 'Set up JDK 15' uses: actions/setup-java@v2 with: java-version: 15 distribution: 'zulu' + cache: 'maven' server-id: sonatype-nexus-snapshots server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD From 2c5d5fd85bebbcb7e3b146d983e3027930aee8ef Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Wed, 15 Sep 2021 15:19:58 -0700 Subject: [PATCH 111/379] Automatic code cleanup. COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/656 from sormuras:issues/561-toolprovider 82130f3bb3b4cb9d8bdd62e29c78f818f3108de5 PiperOrigin-RevId: 396936217 --- core/pom.xml | 5 ++ .../java/GoogleJavaFormatToolProvider.java | 38 +++++++++++++ .../google/googlejavaformat/java/Main.java | 15 +++-- .../java/javadoc/JavadocWriter.java | 3 +- .../GoogleJavaFormatToolProviderTest.java | 57 +++++++++++++++++++ pom.xml | 11 ++++ 6 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java create mode 100644 core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java diff --git a/core/pom.xml b/core/pom.xml index e8e9bf249..5ebdb591b 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -56,6 +56,11 @@ auto-value-annotations true + + com.google.auto.service + auto-service-annotations + true + diff --git a/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java new file mode 100644 index 000000000..7bcad4cc5 --- /dev/null +++ b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java @@ -0,0 +1,38 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java; + +import com.google.auto.service.AutoService; +import java.io.PrintWriter; +import java.util.spi.ToolProvider; + +/** Provide a way to be invoked without necessarily starting a new VM. */ +@AutoService(ToolProvider.class) +public class GoogleJavaFormatToolProvider implements ToolProvider { + @Override + public String name() { + return "google-java-format"; + } + + @Override + public int run(PrintWriter out, PrintWriter err, String... args) { + try { + return Main.main(out, err, args); + } catch (RuntimeException e) { + err.print(e.getMessage()); + return -1; // pass non-zero value back indicating an error has happened + } + } +} diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 4056f2ae3..953ca5860 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -63,20 +63,27 @@ public Main(PrintWriter outWriter, PrintWriter errWriter, InputStream inStream) * @param args the command-line arguments */ public static void main(String[] args) { - int result; PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out, UTF_8)); PrintWriter err = new PrintWriter(new OutputStreamWriter(System.err, UTF_8)); + int result = main(out, err, args); + System.exit(result); + } + + /** + * Package-private main entry point used this CLI program and the java.util.spi.ToolProvider + * implementation in the same package as this Main class. + */ + static int main(PrintWriter out, PrintWriter err, String... args) { try { Main formatter = new Main(out, err, System.in); - result = formatter.format(args); + return formatter.format(args); } catch (UsageException e) { err.print(e.getMessage()); - result = 0; + return 0; } finally { err.flush(); out.flush(); } - System.exit(result); } /** diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java index 9c5838aeb..0361415a1 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java @@ -27,7 +27,6 @@ import static com.google.googlejavaformat.java.javadoc.Token.Type.LIST_ITEM_OPEN_TAG; import static com.google.googlejavaformat.java.javadoc.Token.Type.PARAGRAPH_OPEN_TAG; -import com.google.common.base.Strings; import com.google.common.collect.ImmutableSet; import com.google.googlejavaformat.java.javadoc.Token.Type; @@ -395,7 +394,7 @@ private int innerIndent() { // If this is a hotspot, keep a String of many spaces around, and call append(string, start, end). private void appendSpaces(int count) { - output.append(Strings.repeat(" ", count)); + output.append(" ".repeat(count)); } /** diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java new file mode 100644 index 000000000..15e452297 --- /dev/null +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ServiceLoader; +import java.util.spi.ToolProvider; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link GoogleJavaFormatToolProvider}. */ +@RunWith(JUnit4.class) +public class GoogleJavaFormatToolProviderTest { + + @Test + public void testUsageOutputAfterLoadingViaToolName() { + String name = "google-java-format"; + + assertThat( + ServiceLoader.load(ToolProvider.class).stream() + .map(ServiceLoader.Provider::get) + .map(ToolProvider::name)) + .contains(name); + + ToolProvider format = ToolProvider.findFirst(name).get(); + + StringWriter out = new StringWriter(); + StringWriter err = new StringWriter(); + + int result = format.run(new PrintWriter(out, true), new PrintWriter(err, true), "--help"); + + assertThat(result).isEqualTo(0); + + String usage = err.toString(); + + // Check that doc links are included. + assertThat(usage).containsMatch("http.*/google-java-format"); + assertThat(usage).contains("Usage: google-java-format"); + } +} diff --git a/pom.xml b/pom.xml index c66ed2f23..75a18293d 100644 --- a/pom.xml +++ b/pom.xml @@ -95,6 +95,7 @@ 3.6.1 2.7.1 1.8.2 + 1.0 3.1.0 3.2.1 @@ -124,6 +125,11 @@ auto-value-annotations ${auto-value.version} + + com.google.auto.service + auto-service-annotations + ${auto-service.version} + @@ -220,6 +226,11 @@ auto-value ${auto-value.version} + + com.google.auto.service + auto-service + ${auto-service.version} + From 0eb12a1d824204f5d1e4e00fd09149cf6debf783 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 28 Sep 2021 10:15:52 -0700 Subject: [PATCH 112/379] Update to non-EA JDK 17 builds and add JDK 8 to the matrix. PiperOrigin-RevId: 399469056 --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0386892e9..7d3dbc75e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,19 +29,19 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest ] - java: [ 16, 14, 11 ] + java: [ 17, 14, 11 ] experimental: [ false ] include: # Only test on macos and windows with a single recent JDK to avoid a # combinatorial explosion of test configurations. - os: macos-latest - java: 16 + java: 17 experimental: false - os: windows-latest - java: 16 + java: 17 experimental: false - os: ubuntu-latest - java: 17-ea + java: 18-ea experimental: true runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} From 32a919618b937f7c9b60632ae54e59f76a0df183 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 20 Oct 2021 22:27:20 -0700 Subject: [PATCH 113/379] Fix JDK 18 EA build See https://github.com/openjdk/jdk/commit/0ca094bc5f568842b1619229206ec4a385e5ebf6#diff-a7107e3c172ba7be51af55e33db0d236c16cd3a65cb8d242c289c425879239cbL71 PiperOrigin-RevId: 404714793 --- .../com/google/googlejavaformat/java/RemoveUnusedImports.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index b2b484adc..42af3f377 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -146,7 +146,9 @@ public Void visitIdentifier(com.sun.source.doctree.IdentifierTree node, Void aVo public Void visitReference(ReferenceTree referenceTree, Void unused) { DCReference reference = (DCReference) referenceTree; long basePos = - reference.getSourcePosition((DCTree.DCDocComment) getCurrentPath().getDocComment()); + reference + .pos((DCTree.DCDocComment) getCurrentPath().getDocComment()) + .getStartPosition(); // the position of trees inside the reference node aren't stored, but the qualifier's // start position is the beginning of the reference node if (reference.qualifierExpression != null) { From 96a8b90cc9a0bef28401823d3ae55305ea9cd6e4 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 25 Oct 2021 11:00:30 -0700 Subject: [PATCH 114/379] Update g-j-f version for release PiperOrigin-RevId: 405442838 --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 202e69d16..3b79cd0b6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and run it with: ``` -java -jar /path/to/google-java-format-1.11.0-all-deps.jar [files...] +java -jar /path/to/google-java-format-1.12.0-all-deps.jar [files...] ``` The formatter can act on whole files, on limited lines (`--lines`), on specific @@ -39,7 +39,7 @@ java \ --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ - -jar google-java-format-1.11.0-all-deps.jar [files...] + -jar google-java-format-1.12.0-all-deps.jar [files...] ``` ### IntelliJ, Android Studio, and other JetBrains IDEs @@ -71,7 +71,7 @@ and import it into File→Settings→Editor→Code Style. ### Eclipse Version 1.11 of the -[google-java-format Eclipse plugin](https://github.com/google/google-java-format/releases/download/v1.11.0/google-java-format-eclipse-plugin-1.11.0.jar) +[google-java-format Eclipse plugin](https://github.com/google/google-java-format/releases/download/v1.12.0/google-java-format-eclipse-plugin-1.12.0.jar) can be downloaded from the releases page. Drop it into the Eclipse [drop-ins folder](http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fp2_dropins_format.html) to activate the plugin. @@ -113,7 +113,7 @@ configuration. com.google.googlejavaformat google-java-format - 1.11.0 + 1.12.0 ``` @@ -121,7 +121,7 @@ configuration. ```groovy dependencies { - implementation 'com.google.googlejavaformat:google-java-format:1.11.0' + implementation 'com.google.googlejavaformat:google-java-format:1.12.0' } ``` From 7edc0481efc52d0519034d5d14342462c193e922 Mon Sep 17 00:00:00 2001 From: Kurt Alfred Kluever Date: Tue, 9 Nov 2021 13:54:38 -0800 Subject: [PATCH 115/379] Migrate from JSR305's `javax.annotation.CheckReturnValue` to ErrorProne's `com.google.errorprone.annotations.CheckReturnValue`. PiperOrigin-RevId: 408698115 --- .../test/java/com/google/googlejavaformat/java/MainTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index 575153efe..ac3eb3966 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -322,7 +322,7 @@ public void packageInfo() throws Exception { "@ParametersAreNonnullByDefault", "package com.google.common.labs.base;", "", - "import javax.annotation.CheckReturnValue;", + "import com.google.errorprone.annotations.CheckReturnValue;", "import javax.annotation.ParametersAreNonnullByDefault;", "", }; From 5bd619d87498f9ed78982eb8dd5cbd701f9aec49 Mon Sep 17 00:00:00 2001 From: nakulj <3213360+nakulj@users.noreply.github.com> Date: Mon, 15 Nov 2021 08:36:21 -0800 Subject: [PATCH 116/379] Remove use of distutils Distutils will be deprecated in python 3.12, see [PEP 632](https://www.python.org/dev/peps/pep-0632/). `shutil.which` is the recommended replacement for `distutils.spawn.find_executable`. Fixes #680 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/680 from nakulj:patch-1 48c041aa6d8aad5a29e4963e7f0eb062c5351939 PiperOrigin-RevId: 409989153 --- scripts/google-java-format-diff.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/google-java-format-diff.py b/scripts/google-java-format-diff.py index cf2ded9ec..7d087cf27 100755 --- a/scripts/google-java-format-diff.py +++ b/scripts/google-java-format-diff.py @@ -33,7 +33,7 @@ import subprocess import io import sys -from distutils.spawn import find_executable +from shutil import which def main(): parser = argparse.ArgumentParser(description= @@ -105,7 +105,7 @@ def main(): elif args.google_java_format_jar: base_command = ['java', '-jar', args.google_java_format_jar] else: - binary = find_executable('google-java-format') or '/usr/bin/google-java-format' + binary = which('google-java-format') or '/usr/bin/google-java-format' base_command = [binary] # Reformat files containing changes in place. From c8741147a23a858f79e20a662698f44325e9a1c2 Mon Sep 17 00:00:00 2001 From: nakulj <3213360+nakulj@users.noreply.github.com> Date: Mon, 15 Nov 2021 08:49:23 -0800 Subject: [PATCH 117/379] Fix py3 issues with g-j-f-diff - `StringIO` expectes `Text`, not `bytes`. - `string.join(a,b)` is replaced with `b.join(a)` Fixes #682 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/682 from nakulj:patch-2 6f86f50ec0650f6b0187c6451cb773e022bfea1e PiperOrigin-RevId: 409992189 --- scripts/google-java-format-diff.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/google-java-format-diff.py b/scripts/google-java-format-diff.py index 7d087cf27..151ae33d9 100755 --- a/scripts/google-java-format-diff.py +++ b/scripts/google-java-format-diff.py @@ -134,11 +134,11 @@ def main(): if not args.i: with open(filename) as f: code = f.readlines() - formatted_code = io.StringIO(stdout).readlines() + formatted_code = io.StringIO(stdout.decode('utf-8')).readlines() diff = difflib.unified_diff(code, formatted_code, filename, filename, '(before formatting)', '(after formatting)') - diff_string = string.join(diff, '') + diff_string = ''.join(diff) if len(diff_string) > 0: sys.stdout.write(diff_string) From 58978e6739ad1e1f1125b5d332d1136e9bb75b5d Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 19 Nov 2021 13:51:05 -0800 Subject: [PATCH 118/379] Fix handling of case patterns in unused import removal https://github.com/google/google-java-format/issues/684 PiperOrigin-RevId: 411136606 --- .../java/RemoveUnusedImports.java | 28 +++++++++++ .../RemoveUnusedImportsCaseLabelsTest.java | 49 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsCaseLabelsTest.java diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index 42af3f377..20e55e945 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -32,6 +32,7 @@ import com.google.googlejavaformat.Newlines; import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.ReferenceTree; +import com.sun.source.tree.CaseTree; import com.sun.source.tree.IdentifierTree; import com.sun.source.tree.ImportTree; import com.sun.source.tree.Tree; @@ -55,8 +56,10 @@ import com.sun.tools.javac.util.Options; import java.io.IOError; import java.io.IOException; +import java.lang.reflect.Method; import java.net.URI; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Set; import javax.tools.Diagnostic; @@ -115,6 +118,31 @@ public Void visitIdentifier(IdentifierTree tree, Void unused) { return null; } + // TODO(cushon): remove this override when pattern matching in switch is no longer a preview + // feature, and TreePathScanner visits CaseTree#getLabels instead of CaseTree#getExpressions + @SuppressWarnings("unchecked") // reflection + @Override + public Void visitCase(CaseTree tree, Void unused) { + if (CASE_TREE_GET_LABELS != null) { + try { + scan((List) CASE_TREE_GET_LABELS.invoke(tree), null); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } + return super.visitCase(tree, null); + } + + private static final Method CASE_TREE_GET_LABELS = caseTreeGetLabels(); + + private static Method caseTreeGetLabels() { + try { + return CaseTree.class.getMethod("getLabels"); + } catch (NoSuchMethodException e) { + return null; + } + } + @Override public Void scan(Tree tree, Void unused) { if (tree == null) { diff --git a/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsCaseLabelsTest.java b/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsCaseLabelsTest.java new file mode 100644 index 000000000..c0babb0d4 --- /dev/null +++ b/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsCaseLabelsTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.googlejavaformat.java.RemoveUnusedImports.removeUnusedImports; +import static org.junit.Assume.assumeTrue; + +import com.google.common.base.Joiner; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests that unused import removal doesn't remove types used in case labels. */ +@RunWith(JUnit4.class) +public class RemoveUnusedImportsCaseLabelsTest { + @Test + public void preserveTypesInCaseLabels() throws FormatterException { + assumeTrue(Runtime.version().feature() >= 17); + String input = + Joiner.on('\n') + .join( + "package example;", + "import example.model.SealedInterface;", + "import example.model.TypeA;", + "import example.model.TypeB;", + "public class Main {", + " public void apply(SealedInterface sealedInterface) {", + " switch(sealedInterface) {", + " case TypeA a -> System.out.println(\"A!\");", + " case TypeB b -> System.out.println(\"B!\");", + " }", + " }", + "}"); + assertThat(removeUnusedImports(input)).isEqualTo(input); + } +} From 8be9250fa82f679cc1293a5aa4865aae35422df0 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 19 Nov 2021 14:34:04 -0800 Subject: [PATCH 119/379] Update handling of pattern matching in switch for AST changes in Java 17, in particular the addition of CaseTree#getLabels, which returns a single `DefaultCaseLabelTree` to represent the default case. https://github.com/google/google-java-format/issues/683 https://github.com/google/google-java-format/issues/684 PiperOrigin-RevId: 411146137 --- .../java/java14/Java14InputAstVisitor.java | 20 +++++++-- .../java/FormatterIntegrationTest.java | 45 ++++++------------- .../googlejavaformat/java/testdata/I683.input | 14 ++++++ .../java/testdata/I683.output | 15 +++++++ .../googlejavaformat/java/testdata/I684.input | 14 ++++++ .../java/testdata/I684.output | 14 ++++++ 6 files changed, 86 insertions(+), 36 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I683.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I683.output create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I684.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I684.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java index 3facbd711..890687fe2 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java @@ -15,6 +15,7 @@ package com.google.googlejavaformat.java.java14; import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.collect.Iterables.getOnlyElement; import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; @@ -27,7 +28,6 @@ import com.sun.source.tree.CaseTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; -import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.InstanceOfTree; import com.sun.source.tree.ModifiersTree; import com.sun.source.tree.ModuleTree; @@ -59,6 +59,7 @@ public class Java14InputAstVisitor extends JavaInputAstVisitor { maybeGetMethod(BindingPatternTree.class, "getType"); private static final Method BINDING_PATTERN_TREE_GET_BINDING = maybeGetMethod(BindingPatternTree.class, "getBinding"); + private static final Method CASE_TREE_GET_LABELS = maybeGetMethod(CaseTree.class, "getLabels"); public Java14InputAstVisitor(OpsBuilder builder, int indentMultiplier) { super(builder, indentMultiplier); @@ -247,14 +248,25 @@ public Void visitCase(CaseTree node, Void unused) { sync(node); markForPartialFormat(); builder.forcedBreak(); - if (node.getExpressions().isEmpty()) { + List labels; + boolean isDefault; + if (CASE_TREE_GET_LABELS != null) { + labels = (List) invoke(CASE_TREE_GET_LABELS, node); + isDefault = + labels.size() == 1 + && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL"); + } else { + labels = node.getExpressions(); + isDefault = labels.isEmpty(); + } + if (isDefault) { token("default", plusTwo); } else { token("case", plusTwo); - builder.open(node.getExpressions().size() > 1 ? plusFour : ZERO); + builder.open(labels.size() > 1 ? plusFour : ZERO); builder.space(); boolean first = true; - for (ExpressionTree expression : node.getExpressions()) { + for (Tree expression : labels) { if (!first) { token(","); builder.breakOp(" "); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index edbb12b6e..22202e98a 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -14,8 +14,7 @@ package com.google.googlejavaformat.java; -import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_VERSION; -import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION; +import static com.google.common.collect.MoreCollectors.toOptional; import static com.google.common.io.Files.getFileExtension; import static com.google.common.io.Files.getNameWithoutExtension; import static java.nio.charset.StandardCharsets.UTF_8; @@ -23,7 +22,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableMultimap; import com.google.common.io.CharStreams; import com.google.common.reflect.ClassPath; import com.google.common.reflect.ClassPath.ResourceInfo; @@ -31,12 +30,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.lang.reflect.Method; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.TreeMap; import org.junit.Test; import org.junit.runner.RunWith; @@ -47,12 +46,13 @@ @RunWith(Parameterized.class) public class FormatterIntegrationTest { - private static final ImmutableSet JAVA14_TESTS = - ImmutableSet.of("I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574", "I594"); - - private static final ImmutableSet JAVA15_TESTS = ImmutableSet.of("I603"); - - private static final ImmutableSet JAVA16_TESTS = ImmutableSet.of("I588"); + private static final ImmutableMultimap VERSIONED_TESTS = + ImmutableMultimap.builder() + .putAll(14, "I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574", "I594") + .putAll(15, "I603") + .putAll(16, "I588") + .putAll(17, "I683", "I684") + .build(); @Parameters(name = "{index}: {0}") public static Iterable data() throws IOException { @@ -91,13 +91,9 @@ public static Iterable data() throws IOException { String input = inputs.get(fileName); assertTrue("unmatched input", outputs.containsKey(fileName)); String expectedOutput = outputs.get(fileName); - if (JAVA14_TESTS.contains(fileName) && getMajor() < 14) { - continue; - } - if (JAVA15_TESTS.contains(fileName) && getMajor() < 15) { - continue; - } - if (JAVA16_TESTS.contains(fileName) && getMajor() < 16) { + Optional version = + VERSIONED_TESTS.inverse().get(fileName).stream().collect(toOptional()); + if (version.isPresent() && Runtime.version().feature() < version.get()) { continue; } testInputs.add(new Object[] {fileName, input, expectedOutput}); @@ -105,21 +101,6 @@ public static Iterable data() throws IOException { return testInputs; } - private static int getMajor() { - try { - Method versionMethod = Runtime.class.getMethod("version"); - Object version = versionMethod.invoke(null); - return (int) version.getClass().getMethod("major").invoke(version); - } catch (Exception e) { - // continue below - } - int version = (int) Double.parseDouble(JAVA_CLASS_VERSION.value()); - if (49 <= version && version <= 52) { - return version - (49 - 5); - } - throw new IllegalStateException("Unknown Java version: " + JAVA_SPECIFICATION_VERSION.value()); - } - private final String name; private final String input; private final String expected; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I683.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I683.input new file mode 100644 index 000000000..9104f1903 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I683.input @@ -0,0 +1,14 @@ +interface Test { + + static class Test1 implements Test{} + static class Test2 implements Test{} + + public static void main(String[] args) { + Test test = new Test1(); + switch (test) { + case Test1 test1 -> {} + case Test2 test2 -> {} + default -> throw new IllegalStateException("Unexpected value: " + test); + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I683.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I683.output new file mode 100644 index 000000000..5b9c4665a --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I683.output @@ -0,0 +1,15 @@ +interface Test { + + static class Test1 implements Test {} + + static class Test2 implements Test {} + + public static void main(String[] args) { + Test test = new Test1(); + switch (test) { + case Test1 test1 -> {} + case Test2 test2 -> {} + default -> throw new IllegalStateException("Unexpected value: " + test); + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I684.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I684.input new file mode 100644 index 000000000..cbce0ddd5 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I684.input @@ -0,0 +1,14 @@ +package example; + +import example.model.SealedInterface; +import example.model.TypeA; +import example.model.TypeB; + +public class Main { + public void apply(SealedInterface sealedInterface) { + switch(sealedInterface) { + case TypeA a -> System.out.println("A!"); + case TypeB b -> System.out.println("B!"); + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I684.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I684.output new file mode 100644 index 000000000..4e5e9b4be --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I684.output @@ -0,0 +1,14 @@ +package example; + +import example.model.SealedInterface; +import example.model.TypeA; +import example.model.TypeB; + +public class Main { + public void apply(SealedInterface sealedInterface) { + switch (sealedInterface) { + case TypeA a -> System.out.println("A!"); + case TypeB b -> System.out.println("B!"); + } + } +} From 35e97e8fae4d9474f94f7dd474fc3ba921dafa24 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sat, 20 Nov 2021 14:02:59 -0800 Subject: [PATCH 120/379] Update version number for 1.13.0 release PiperOrigin-RevId: 411296447 --- README.md | 10 +++++----- eclipse_plugin/META-INF/MANIFEST.MF | 2 +- eclipse_plugin/pom.xml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3b79cd0b6..aa560505c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and run it with: ``` -java -jar /path/to/google-java-format-1.12.0-all-deps.jar [files...] +java -jar /path/to/google-java-format-1.13.0-all-deps.jar [files...] ``` The formatter can act on whole files, on limited lines (`--lines`), on specific @@ -39,7 +39,7 @@ java \ --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ - -jar google-java-format-1.12.0-all-deps.jar [files...] + -jar google-java-format-1.13.0-all-deps.jar [files...] ``` ### IntelliJ, Android Studio, and other JetBrains IDEs @@ -71,7 +71,7 @@ and import it into File→Settings→Editor→Code Style. ### Eclipse Version 1.11 of the -[google-java-format Eclipse plugin](https://github.com/google/google-java-format/releases/download/v1.12.0/google-java-format-eclipse-plugin-1.12.0.jar) +[google-java-format Eclipse plugin](https://github.com/google/google-java-format/releases/download/v1.13.0/google-java-format-eclipse-plugin-1.13.0.jar) can be downloaded from the releases page. Drop it into the Eclipse [drop-ins folder](http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fp2_dropins_format.html) to activate the plugin. @@ -113,7 +113,7 @@ configuration. com.google.googlejavaformat google-java-format - 1.12.0 + 1.13.0 ``` @@ -121,7 +121,7 @@ configuration. ```groovy dependencies { - implementation 'com.google.googlejavaformat:google-java-format:1.12.0' + implementation 'com.google.googlejavaformat:google-java-format:1.13.0' } ``` diff --git a/eclipse_plugin/META-INF/MANIFEST.MF b/eclipse_plugin/META-INF/MANIFEST.MF index 34b1e8c88..913245393 100644 --- a/eclipse_plugin/META-INF/MANIFEST.MF +++ b/eclipse_plugin/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: google-java-format Bundle-SymbolicName: google-java-format-eclipse-plugin;singleton:=true Bundle-Vendor: Google -Bundle-Version: 1.11.0 +Bundle-Version: 1.13.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Bundle: org.eclipse.jdt.core;bundle-version="3.10.0", org.eclipse.jface, diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index 6b49c901a..ee5635c42 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -22,7 +22,7 @@ com.google.googlejavaformat google-java-format-eclipse-plugin eclipse-plugin - 1.11.0 + 1.13.0 Google Java Format Plugin for Eclipse 4.5+ From 4347a6454978a5401a3b2e1ff851bea1400bb189 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Tue, 23 Nov 2021 09:43:58 -0800 Subject: [PATCH 121/379] Update the plugin to google-java-format 1.13.0. PiperOrigin-RevId: 411832812 --- idea_plugin/build.gradle | 8 ++++---- idea_plugin/resources/META-INF/plugin.xml | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 3d807af01..36c12f13f 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "0.7.2" + id "org.jetbrains.intellij" version "1.3.0" } repositories { @@ -23,7 +23,7 @@ repositories { } ext { - googleJavaFormatVersion = '1.10.0' + googleJavaFormatVersion = '1.13.0' } apply plugin: 'org.jetbrains.intellij' @@ -31,7 +31,7 @@ apply plugin: 'java' intellij { pluginName = "google-java-format" - version = "211.6693.65-EAP-SNAPSHOT" + version = "IC-213.5744.18-EAP-SNAPSHOT" } patchPluginXml { @@ -54,5 +54,5 @@ sourceSets { } dependencies { - compile "com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}" + implementation "com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}" } diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index b089ad603..60705902a 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -28,6 +28,12 @@ +

1.13.0.0
+
Updated to use google-java-format 1.13.
+
1.12.0.0
+
Updated to use google-java-format 1.12.
+
1.11.0.0
+
Updated to use google-java-format 1.11.
1.10.0.0
Updated to use google-java-format 1.10.
1.9.0.0
From 7bc5daec11d91caf28ab8b1bd61d6beaf9a59c15 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 22 Dec 2021 08:01:12 -0800 Subject: [PATCH 122/379] Remove some reflection now that we require JDK 11 to run the formatter PiperOrigin-RevId: 417821422 --- .../googlejavaformat/java/Formatter.java | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index 3e973958d..aac829dd0 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -14,8 +14,6 @@ package com.google.googlejavaformat.java; -import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_VERSION; -import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.collect.ImmutableList; @@ -42,7 +40,6 @@ import com.sun.tools.javac.util.Options; import java.io.IOError; import java.io.IOException; -import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; import java.util.Collection; @@ -154,7 +151,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept OpsBuilder builder = new OpsBuilder(javaInput, javaOutput); // Output the compilation unit. JavaInputAstVisitor visitor; - if (getMajor() >= 14) { + if (Runtime.version().feature() >= 14) { try { visitor = Class.forName("com.google.googlejavaformat.java.java14.Java14InputAstVisitor") @@ -176,23 +173,6 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept javaOutput.flush(); } - // Runtime.Version was added in JDK 9, so use reflection to access it to preserve source - // compatibility with Java 8. - private static int getMajor() { - try { - Method versionMethod = Runtime.class.getMethod("version"); - Object version = versionMethod.invoke(null); - return (int) version.getClass().getMethod("major").invoke(version); - } catch (Exception e) { - // continue below - } - int version = (int) Double.parseDouble(JAVA_CLASS_VERSION.value()); - if (49 <= version && version <= 52) { - return version - (49 - 5); - } - throw new IllegalStateException("Unknown Java version: " + JAVA_SPECIFICATION_VERSION.value()); - } - static boolean errorDiagnostic(Diagnostic input) { if (input.getKind() != Diagnostic.Kind.ERROR) { return false; From 06a2105be2d73bbbdc6cb6f8dc43f84e2eb00e07 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 24 Dec 2021 09:18:41 -0800 Subject: [PATCH 123/379] Don't use single-line for for javadoc without a summary fragment Using the multi-line form here may call attention to the missing summary fragment. The style guide can also be read as discouraging the single-line form for non-required javadoc missing a summary fragment (see b/74239048#comment4), but I'm not sure that's the intent, and I'm looking at changing it (unknown commit). PiperOrigin-RevId: 418174535 --- .../java/javadoc/JavadocFormatter.java | 11 +++++--- .../java/JavadocFormattingTest.java | 25 ++++++++++++++++++- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java index 5addc6770..06176b541 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java @@ -168,10 +168,13 @@ private static Token standardize(Token token, Token standardToken) { private static String makeSingleLineIfPossible(int blockIndent, String input) { int oneLinerContentLength = MAX_LINE_LENGTH - "/** */".length() - blockIndent; Matcher matcher = ONE_CONTENT_LINE_PATTERN.matcher(input); - if (matcher.matches() && matcher.group(1).isEmpty()) { - return "/** */"; - } else if (matcher.matches() && matcher.group(1).length() <= oneLinerContentLength) { - return "/** " + matcher.group(1) + " */"; + if (matcher.matches()) { + String line = matcher.group(1); + if (line.isEmpty()) { + return "/** */"; + } else if (line.length() <= oneLinerContentLength && !line.startsWith("@")) { + return "/** " + line + " */"; + } } return input; } diff --git a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java index f5103d9b5..9d29eef29 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java @@ -937,7 +937,9 @@ public void onlyParams() { "class Test {}", }; String[] expected = { - "/** @param this is a param */", // + "/**", // + " * @param this is a param", + " */", "class Test {}", }; doFormatTest(input, expected); @@ -1415,4 +1417,25 @@ public void u2028LineSeparator() { }; doFormatTest(input, expected); } + + @Test + public void missingSummaryFragment() { + String[] input = { + "public class Foo {", + " /**", + " * @return something.", + " */", + " public void setSomething() {}", + "}", + }; + String[] expected = { + "public class Foo {", + " /**", + " * @return something.", + " */", + " public void setSomething() {}", + "}", + }; + doFormatTest(input, expected); + } } From 7677caeb1c2c77c2df0d2b5cc0575cf33aa55afa Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 24 Dec 2021 10:56:15 -0800 Subject: [PATCH 124/379] Automated rollback of commit 06a2105be2d73bbbdc6cb6f8dc43f84e2eb00e07. *** Reason for rollback *** Broke integration tests, will fix forward later *** Original change description *** Don't use single-line for for javadoc without a summary fragment Using the multi-line form here may call attention to the missing summary fragment. The style guide can also be read as discouraging the single-line form for non-required javadoc missing a summary fragment (see b/74239048#comment4), but I'm not sure that's the intent, and I'm looking at changing it (unknown commit). *** PiperOrigin-RevId: 418182032 --- .../java/javadoc/JavadocFormatter.java | 11 +++----- .../java/JavadocFormattingTest.java | 25 +------------------ 2 files changed, 5 insertions(+), 31 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java index 06176b541..5addc6770 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java @@ -168,13 +168,10 @@ private static Token standardize(Token token, Token standardToken) { private static String makeSingleLineIfPossible(int blockIndent, String input) { int oneLinerContentLength = MAX_LINE_LENGTH - "/** */".length() - blockIndent; Matcher matcher = ONE_CONTENT_LINE_PATTERN.matcher(input); - if (matcher.matches()) { - String line = matcher.group(1); - if (line.isEmpty()) { - return "/** */"; - } else if (line.length() <= oneLinerContentLength && !line.startsWith("@")) { - return "/** " + line + " */"; - } + if (matcher.matches() && matcher.group(1).isEmpty()) { + return "/** */"; + } else if (matcher.matches() && matcher.group(1).length() <= oneLinerContentLength) { + return "/** " + matcher.group(1) + " */"; } return input; } diff --git a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java index 9d29eef29..f5103d9b5 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java @@ -937,9 +937,7 @@ public void onlyParams() { "class Test {}", }; String[] expected = { - "/**", // - " * @param this is a param", - " */", + "/** @param this is a param */", // "class Test {}", }; doFormatTest(input, expected); @@ -1417,25 +1415,4 @@ public void u2028LineSeparator() { }; doFormatTest(input, expected); } - - @Test - public void missingSummaryFragment() { - String[] input = { - "public class Foo {", - " /**", - " * @return something.", - " */", - " public void setSomething() {}", - "}", - }; - String[] expected = { - "public class Foo {", - " /**", - " * @return something.", - " */", - " public void setSomething() {}", - "}", - }; - doFormatTest(input, expected); - } } From 3b70603449ef7411043a81105919bcda046bd062 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 29 Dec 2021 18:06:00 -0800 Subject: [PATCH 125/379] Specify JVM flags required by turbine using `.mvn/jvm.config` see https://github.com/google/error-prone/issues/2786 PiperOrigin-RevId: 418873888 --- .mvn/jvm.config | 10 ++++++++++ pom.xml | 12 ------------ 2 files changed, 10 insertions(+), 12 deletions(-) create mode 100644 .mvn/jvm.config diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 000000000..504456f90 --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1,10 @@ +--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED diff --git a/pom.xml b/pom.xml index 75a18293d..772a16b8c 100644 --- a/pom.xml +++ b/pom.xml @@ -191,19 +191,7 @@ ${java.version} ${java.version} UTF-8 - true - - -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED - -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED - -J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED - -J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED -XDcompilePolicy=simple -Xplugin:ErrorProne From ef0bec605e2de3f9baf550d5f90daad1b5c49329 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 12 Jan 2022 11:01:25 -0800 Subject: [PATCH 126/379] Enable dependabot PiperOrigin-RevId: 421344211 --- .github/dependabot.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..b76b89570 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "daily" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" From de9e3b722356fb6f55ef5ad886a1fa242ff74fd4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jan 2022 13:59:12 -0800 Subject: [PATCH 127/379] Bump maven-source-plugin from 2.1.2 to 3.2.1 Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 2.1.2 to 3.2.1.
Commits
  • a59a2e4 [maven-release-plugin] prepare release maven-source-plugin-3.2.1
  • c954a7e make build as reproducible as possible for now
  • d5b9878 [MSOURCES-123] set archiver reproducible mode earlier
  • 258d666 MSOURCES-122 make output independant from OS newline
  • 5b4e02f [maven-release-plugin] prepare for next development iteration
  • 2a74824 [maven-release-plugin] prepare release maven-source-plugin-3.2.0
  • 816ebc4 MSOURCES-120 fix reproducible IT: remove plugin version from pom.xml
  • 32f122a MSOURCES-120 make output jar file binary Reproducible
  • 6e715b1 [MSOURCES-95] Source JAR is re-created even if sources are not changed
  • 9154e1a [maven-release-plugin] prepare for next development iteration
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-source-plugin&package-manager=maven&previous-version=2.1.2&new-version=3.2.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #708 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/708 from google:dependabot/maven/org.apache.maven.plugins-maven-source-plugin-3.2.1 8062a1f65f10197bfbb9dcf614d4945ac46b0acc PiperOrigin-RevId: 421388226 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 772a16b8c..35904c654 100644 --- a/pom.xml +++ b/pom.xml @@ -166,7 +166,7 @@
maven-source-plugin - 2.1.2 + 3.2.1 maven-javadoc-plugin From e01e66cfecd0b411ec134ac70f73a95c82cb0430 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jan 2022 13:59:56 -0800 Subject: [PATCH 128/379] Bump build-helper-maven-plugin from 3.0.0 to 3.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [build-helper-maven-plugin](https://github.com/mojohaus/build-helper-maven-plugin) from 3.0.0 to 3.3.0.
Release notes

Sourced from build-helper-maven-plugin's releases.

3.3.0

Changes

  • Fixes #108 - released-version does not detect version if maven repository is not configured to look for snapshot (#109) @​stefanseifert
  • Add missing whitespace to output of reserve-network-port (#101) @​albers

🚀 New features and improvements

  • Provide the Mojos logger as variable in the Interpreter context (#72) @​MeyerNils

📦 Dependency updates

👻 Maintenance

build-helper-maven-plugin-3.2.0

Changelog: https://github.com/mojohaus/build-helper-maven-plugin/milestone/6?closed=1

build-helper-maven-plugin-3.1.0

Changelog: https://github.com/mojohaus/build-helper-maven-plugin/issues?q=is%3Aissue+milestone%3A3.1.0+is%3Aclosed

Commits
  • f1fac8c [maven-release-plugin] prepare release build-helper-maven-plugin-3.3.0
  • 3fed18c use version-resolver for release drafter to apply semantic versioning e.g. if...
  • 4d6ca94 allow to run release-drafter on workflow_dispatch for testing
  • b4e5d5a Provide the Mojos logger as variable in the Interpreter context (#72)
  • bda39bc set min. java version to java 8
  • 5f69431 Bump testng from 6.9.9 to 7.4.0 (#116)
  • 5796839 Bump assertj-core from 1.7.1 to 3.22.0
  • e916f57 Bump maven-plugin-annotations from 3.5 to 3.6.2
  • 158475c Bump mojo-parent from 61 to 65
  • 5360a59 Merge pull request #114 from mojohaus/feature/github-actions
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.codehaus.mojo:build-helper-maven-plugin&package-manager=maven&previous-version=3.0.0&new-version=3.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #705 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/705 from google:dependabot/maven/org.codehaus.mojo-build-helper-maven-plugin-3.3.0 fcee6b1504891934f9d49cb216f9dc72c1c71125 PiperOrigin-RevId: 421388545 --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 5ebdb591b..80fa4d9d4 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -191,7 +191,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.0.0 + 3.3.0 add-source From 427a2bde4e5b2d66ff6425e345f8c15612adba18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jan 2022 14:00:14 -0800 Subject: [PATCH 129/379] Bump maven-surefire-plugin from 2.18 to 2.22.2 Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 2.18 to 2.22.2.
Commits
  • d96b95c [maven-release-plugin] prepare release surefire-2.22.2
  • 4a2aafc Remove Travis file
  • 7b9ec3f Remove JUnit SNAPSHOT argument from IT
  • 18b4078 [SUREFIRE-1614] JUnit Runner that writes to System.out corrupts Surefire's ST...
  • af417b8 prepare for next development iteration
  • c23c8b9 [maven-release-plugin] prepare release surefire-2.22.1_vote-1
  • 5376261 [SUREFIRE-1564] Can't override platform version through project/plugin depend...
  • 242c0e8 [SUREFIRE-1564] Can't override platform version through project/plugin depend...
  • 25fadfc CheckTestNgSuiteXmlIT should not be ignored
  • 57fbb16 [SUREFIRE-1532] MIME type for javascript is now officially application/javasc...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-surefire-plugin&package-manager=maven&previous-version=2.18&new-version=2.22.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #710 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/710 from google:dependabot/maven/org.apache.maven.plugins-maven-surefire-plugin-2.22.2 78d9ce680ab611f8896772fbbf579b37146fe3c6 PiperOrigin-RevId: 421388633 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 35904c654..edc295843 100644 --- a/pom.xml +++ b/pom.xml @@ -264,7 +264,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.18 + 2.22.2 From 4424715f9b2d3432c2c5b0559d90070d2bf11452 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jan 2022 14:00:45 -0800 Subject: [PATCH 130/379] Bump checker-qual from 3.6.1 to 3.21.1 Bumps [checker-qual](https://github.com/typetools/checker-framework) from 3.6.1 to 3.21.1.
Release notes

Sourced from checker-qual's releases.

Checker Framework 3.21.1

Version 3.21.1 (January 7, 2022)

User-visible changes:

The Checker Framework Gradle Plugin now works incrementally: if you change just one source file, then Gradle will recompile just that file rather than all files.

Closed issues: #2401, #4994, #4995, #4996.

Checker Framework 3.21.0

Version 3.21.0 (December 17, 2021)

User-visible changes:

The Checker Framework now more precisely computes the type of a switch expression.

Implementation details:

The dataflow framework now analyzes switch expressions and switch statements that use the new -> case syntax. To do so, a new node, SwitchExpressionNode, was added.

Closed issues: #2373, #4934, #4977, #4979, #4987.

Checker Framework 3.20.0

Version 3.20.0 (December 6, 2021)

User-visible changes:

The Checker Framework now runs on code that contains switch expressions and switch statements that use the new -> case syntax, but treats them conservatively. A future version will improve precision.

Implementation details:

The dataflow framework can be run on code that contains switch expressions and switch statements that use the new -> case syntax, but it does not yet analyze the cases in a switch expression and it treats -> as :. A future version will do so.

Removed methods and classes that have been deprecated for more than one year:

  • Old way of constructing qualifier hierarchies
  • @SuppressWarningsKeys
  • RegularBlock.getContents()
  • TestUtilities.testBooleanProperty()
  • CFAbstractTransfer.getValueWithSameAnnotations()

Closed issues: #4911, #4948, #4965.

Checker Framework 3.19.0

Version 3.19.0 (November 1, 2021)

... (truncated)

Changelog

Sourced from checker-qual's changelog.

Version 3.21.1 (January 7, 2022)

User-visible changes:

The Checker Framework Gradle Plugin now works incrementally: if you change just one source file, then Gradle will recompile just that file rather than all files.

Closed issues: #2401, #4994, #4995, #4996.

Version 3.21.0 (December 17, 2021)

User-visible changes:

The Checker Framework now more precisely computes the type of a switch expression.

Implementation details:

The dataflow framework now analyzes switch expressions and switch statements that use the new -> case syntax. To do so, a new node, SwitchExpressionNode, was added.

Closed issues: #2373, #4934, #4977, #4979, #4987.

Version 3.20.0 (December 6, 2021)

User-visible changes:

The Checker Framework now runs on code that contains switch expressions and switch statements that use the new -> case syntax, but treats them conservatively. A future version will improve precision.

Implementation details:

The dataflow framework can be run on code that contains switch expressions and switch statements that use the new -> case syntax, but it does not yet analyze the cases in a switch expression and it treats -> as :. A future version will do so.

Removed methods and classes that have been deprecated for more than one year:

  • Old way of constructing qualifier hierarchies
  • @SuppressWarningsKeys
  • RegularBlock.getContents()
  • TestUtilities.testBooleanProperty()

... (truncated)

Commits
  • dd715c3 new release 3.21.1
  • 3820124 Prep for release.
  • 673b126 Capture enclosing types
  • 269bca0 Checker Framework Gradle Plugin is now incremental
  • c73c4f8 In TreeScanners, ensure "scan" is called so that Java 17+ trees are visited p...
  • ed70606 Add synthetic variables to CFG for ternary expressions (#5000)
  • 3f9646e When releasing, make Randoop use the latest version of the Checker Framework
  • 2ee909e Update BCEL line number (#4999)
  • d3540b9 Bump com.github.johnrengelman.shadow from 7.1.1 to 7.1.2
  • 8e008df Update for next release.
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.checkerframework:checker-qual&package-manager=maven&previous-version=3.6.1&new-version=3.21.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #709 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/709 from google:dependabot/maven/org.checkerframework-checker-qual-3.21.1 ca33afc41d5b68ae67f014293d970009ae65f7e9 PiperOrigin-RevId: 421388780 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index edc295843..cf70803d1 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ 1.8 30.1.1-jre 1.0 - 3.6.1 + 3.21.1 2.7.1 1.8.2 1.0 From bfb0649567b3e85deb70992765cc310fbd2fe9c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jan 2022 14:02:34 -0800 Subject: [PATCH 131/379] Bump styfle/cancel-workflow-action from 0.8.0 to 0.9.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [styfle/cancel-workflow-action](https://github.com/styfle/cancel-workflow-action) from 0.8.0 to 0.9.1.
Release notes

Sourced from styfle/cancel-workflow-action's releases.

0.9.1

Patches

  • Fix: cancelling jobs from different repos where two branches have the same name: #105
  • Fix: use getBooleanInput instead of getInput: #92
  • Chore: add permissions configuration in the README.md: #96
  • Chore: add prettier config, format file, add lint workflow: #63
  • Chore: create dependabot.yml: #68
  • Bump typescript from 4.1.5 to 4.2.4: #71
  • Bump actions/setup-node requirement to v2.1.5: #69
  • Bump @​vercel/ncc to 0.28.3: #73
  • Bump @​actions/core from 1.2.6 to 1.2.7: #74
  • Bump @​vercel/ncc from 0.28.3 to 0.28.5: #81
  • Bump @​actions/core from 1.2.7 to 1.3.0: #90
  • Bump prettier from 2.2.1 to 2.3.0: #85
  • Bump @​vercel/ncc from 0.28.5 to 0.28.6: #95
  • Bump typescript from 4.2.4 to 4.3.2: #94
  • Bump prettier from 2.3.0 to 2.3.1: #97
  • Bump typescript from 4.3.2 to 4.3.4: #99
  • Bump prettier from 2.3.1 to 2.3.2: #100
  • Bump typescript from 4.3.4 to 4.3.5: #101
  • Bump husky from 6.0.0 to 7.0.0: #102
  • Bump husky from 7.0.0 to 7.0.1: #103

Credits

Huge thanks to @​mikehardy, @​MichaelDeBoey, @​Warashi, @​adrienbernede, and @​spaceface777 for helping!

0.9.0

Minor Changes

  • Add all_but_latest flag - cancel all workflows but the latest: #35
  • Cleanup all_but_latest: #67

Credits

Huge thanks to @​thomwiggers for helping!

Commits
  • a40b884 0.9.1
  • a66ae1f fix cancelling jobs from different repos where two branches have the same nam...
  • b54f1a5 Bump husky from 7.0.0 to 7.0.1 (#103)
  • cc6225c Bump husky from 6.0.0 to 7.0.0 (#102)
  • c94109d Bump typescript from 4.3.4 to 4.3.5 (#101)
  • fc3581b Bump prettier from 2.3.1 to 2.3.2 (#100)
  • 6f9f8b4 Bump typescript from 4.3.2 to 4.3.4 (#99)
  • 6135c0f Bump prettier from 2.3.0 to 2.3.1 (#97)
  • 531a036 chore: add permissions configuration in the README.md (#96)
  • 1f10757 Bump typescript from 4.2.4 to 4.3.2 (#94)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=styfle/cancel-workflow-action&package-manager=github_actions&previous-version=0.8.0&new-version=0.9.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #706 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/706 from google:dependabot/github_actions/styfle/cancel-workflow-action-0.9.1 61f4e96d8a56ca6e314ad05dfa8693195deeceb6 PiperOrigin-RevId: 421389297 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7d3dbc75e..e15d01cd3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: continue-on-error: ${{ matrix.experimental }} steps: - name: Cancel previous - uses: styfle/cancel-workflow-action@0.8.0 + uses: styfle/cancel-workflow-action@0.9.1 with: access_token: ${{ github.token }} - name: 'Check out repository' From c3beef135f2c651a77d1097abbbc813e7e0e5b02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 12 Jan 2022 14:02:51 -0800 Subject: [PATCH 132/379] Bump maven-shade-plugin from 2.4.3 to 3.2.4 Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 2.4.3 to 3.2.4.
Commits
  • 768092f [maven-release-plugin] prepare release maven-shade-plugin-3.2.4
  • 4f83ae6 [MSHADE-363] IT to check new Reproducible transformer with old plugin
  • 229f4d7 [MSHADE-363] add ReproducibleResourceTransformer to keep compatibility
  • 51bbf72 [MSHADE-363] add IT showing broken compatibility
  • 3691f60 Merge pull request #48 from apache/MSHADE-364
  • 34736cc [MSHADE-364] drop duplicate resource warning when the resource is handled by ...
  • 830d71a [MSHADE-365] put Properties transformers in separate table
  • ecaa5ee README improvement
  • 9a5b0f8 replace deprecated method (#46)
  • c02f7d6 [MSHADE-360] avoid PrintWriter (#44)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-shade-plugin&package-manager=maven&previous-version=2.4.3&new-version=3.2.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #707 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/707 from google:dependabot/maven/org.apache.maven.plugins-maven-shade-plugin-3.2.4 3c701a3ffc0a0b3e7f99a252dd07a2753d8624ab PiperOrigin-RevId: 421389390 --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 80fa4d9d4..67388fe41 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -119,7 +119,7 @@ org.apache.maven.plugins maven-shade-plugin - 2.4.3 + 3.2.4 shade-all-deps From d46fcf081d365b06d0b850f4acf479b5e38d8afe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Jan 2022 16:37:06 -0800 Subject: [PATCH 133/379] Bump maven-jar-plugin from 3.0.2 to 3.2.2 Bumps [maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.0.2 to 3.2.2.
Commits
  • d37e995 [maven-release-plugin] prepare release maven-jar-plugin-3.2.2
  • 7bb0bfc [MJAR-284] Remove override for Plexus Archiver
  • a3e424d [MJAR-283] Upgrade Plexus Utils to 3.3.1
  • 95bc15b [maven-release-plugin] prepare for next development iteration
  • 50a8e0b [maven-release-plugin] prepare release maven-jar-plugin-3.2.1
  • 0fb2bf0 Proper uppercase JAR
  • e44e5f2 [MJAR-282] Upgrade Maven Archiver to 3.5.2
  • 34d62b6 Bump maven-archiver from 3.5.0 to 3.5.1
  • a496294 use shared gh action - v1 (#28)
  • a7cfde9 Bump junit from 4.13 to 4.13.2
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-jar-plugin&package-manager=maven&previous-version=3.0.2&new-version=3.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #712 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/712 from google:dependabot/maven/org.apache.maven.plugins-maven-jar-plugin-3.2.2 fcb656bd1951005c08df259410d4d673b44e6d91 PiperOrigin-RevId: 421939437 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cf70803d1..86d0753d7 100644 --- a/pom.xml +++ b/pom.xml @@ -162,7 +162,7 @@
maven-jar-plugin - 3.0.2 + 3.2.2 maven-source-plugin From 74ba729707d2b2cb9fe7fbbc3f22edff58502432 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sat, 22 Jan 2022 00:00:17 -0800 Subject: [PATCH 134/379] Update dependency versions PiperOrigin-RevId: 423482707 --- core/pom.xml | 7 ++++++- pom.xml | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 67388fe41..39b9a3d9e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -75,10 +75,15 @@ com.google.truth truth + + com.google.truth.extensions + truth-java8-extension + test + com.google.testing.compile compile-testing - 0.15 + 0.19 test diff --git a/pom.xml b/pom.xml index 86d0753d7..3f7baa0df 100644 --- a/pom.xml +++ b/pom.xml @@ -135,7 +135,7 @@ junit junit - 4.13.1 + 4.13.2 test @@ -150,6 +150,12 @@ ${truth.version} test + + com.google.truth.extensions + truth-java8-extension + ${truth.version} + test + From 8b2601315faacca21086348e9b304ebae954681c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 06:43:09 -0800 Subject: [PATCH 135/379] Bump error_prone_annotations from 2.7.1 to 2.10.0 Bumps [error_prone_annotations](https://github.com/google/error-prone) from 2.7.1 to 2.10.0.
Release notes

Sourced from error_prone_annotations's releases.

Error Prone 2.10.0

New checks

Fixed issues: #2616, #2629

Full Changelog: https://github.com/google/error-prone/compare/v2.9.0...v2.10.0

Error Prone 2.9.0

Release Error Prone 2.9.0

New checks:

  • DeprecatedVariable
  • PublicApiNamedStreamShouldReturnStream

Fixes #2124, #2371, #2393, #2470

Error Prone 2.8.1

This release adds a new check (LoopOverCharArray), and a handful of other small improvements (https://github.com/google/error-prone/compare/v2.8.0...v2.8.1).

Error Prone 2.8.0

New Checks:

Fixes #1652, #2122, #2122, #2366, #2404, #2411

Commits
  • 199a31b Release Error Prone 2.10.0
  • 99cdb15 Always annotate arrays now that we place type-use annotations in the right pl...
  • 0fc9146 Recognize libcore.util.Nullable as type-use, and add a TODO about "hybrid" an...
  • 0f34024 Move check for the regex "." to a new WARNING-level check
  • eb3708a Delete obsolete travis config
  • 5538acc Automated rollback of commit 34d98e8cf1d8da2dc6d261d70c85e96dc4a0d031.
  • f91fff5 ASTHelpers: add getAnnotations method, to allow extraction of annotations fro...
  • cdfa8b8 Add the DistinctVarargs BugChecker. This will generate warning when method ex...
  • 122e512 Add InlineMe:CheckFixCompiles flag, which allows InlineMe users to optional...
  • dd91993 Add ByteString.fromHex to AlwaysThrows
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.errorprone:error_prone_annotations&package-manager=maven&previous-version=2.7.1&new-version=2.10.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #721 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/721 from google:dependabot/maven/com.google.errorprone-error_prone_annotations-2.10.0 73eee1c3efddbb740dc97e76495541c92d9fc0c9 PiperOrigin-RevId: 423801674 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3f7baa0df..894b9dd64 100644 --- a/pom.xml +++ b/pom.xml @@ -93,7 +93,7 @@ 30.1.1-jre 1.0 3.21.1 - 2.7.1 + 2.10.0 1.8.2 1.0 3.1.0 From 8a7ab0d7a8c5977742c884f07ff523dffc09d909 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 06:43:36 -0800 Subject: [PATCH 136/379] Bump maven-gpg-plugin from 1.4 to 3.0.1 Bumps [maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) from 1.4 to 3.0.1.
Commits
  • 5255080 [maven-release-plugin] prepare release maven-gpg-plugin-3.0.1
  • e4dc062 [MGPG-79] fix handling of external pinentry programs in case the passphrase i...
  • 5902b2b deps: update JUnit
  • 12fbd63 Merge pull request #10 from Syquel/bugfix/MGPG-66
  • 4da6921 [MGPG-66] fix handling of excluded files on linux
  • 4016721 Merge pull request #12 from Syquel/bugfix/MGPG-80_equality
  • fba2c39 [MGPG-66] add test for handling of excluded files
  • 26aa5b3 [MGPG-66] fix handling of excluded files
  • 7438b37 [MGPG-80] implement GpgVersion equality in adherence to comparibility
  • b38c638 Merge pull request #11 from Syquel/bugfix/MGPG-80
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-gpg-plugin&package-manager=maven&previous-version=1.4&new-version=3.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #714 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/714 from google:dependabot/maven/org.apache.maven.plugins-maven-gpg-plugin-3.0.1 f73393d9c2bb197b62eb5d776616b59573a06aaa PiperOrigin-RevId: 423801739 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 894b9dd64..3112ee7f1 100644 --- a/pom.xml +++ b/pom.xml @@ -180,7 +180,7 @@
maven-gpg-plugin - 1.4 + 3.0.1 org.apache.felix @@ -338,7 +338,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 + 3.0.1 sign-artifacts From 49eba6d05fd5220aa832b1034491c4ab0310dd21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 06:44:21 -0800 Subject: [PATCH 137/379] Bump truth.version from 1.0 to 1.1.3 Bumps `truth.version` from 1.0 to 1.1.3. Updates `truth` from 1.0 to 1.1.3
Release notes

Sourced from truth's releases.

1.1.3

  • Fixed a bug in how comparingExpectedFieldsOnly() handles oneof fields. (f27208428)
  • Improved comparingExpectedFieldsOnly to work when required fields are absent. (f27208428)
  • Changed Subject.toString() to throw UnsupportedOperationException. (fa4c7b512)

1.1.2

This release completes the feature that I got wrong in 1.1.1 -- the ability to exclude our JUnit 4 dependency and still use standard Truth assertions.

  • Made it possible for users to exclude our JUnit 4 dependency and still use standard Truth assertions -- really this time, even in cases in which excluding the dependency failed under 1.1.1. (JUnit 4 is still required for some advanced features, like Expect, ExpectFailure, and TruthJUnit.assume().) (948f3edca)
  • When JUnit 4 is excluded from the classpath, the AssertionError Truth generates as a substitute for ComparisonFailure now includes the expected and actual values that were missing in 1.1.1. (6b0140730)

1.1.1

We recommend not trying to exclude our JUnit dependency even under this release. We will release 1.1.2 with better handling for the missing dependency shortly.

  • Made it possible for users to exclude our JUnit 4 dependency and still use standard Truth assertions. (JUnit 4 is still required for some advanced features, like Expect, ExpectFailure, and TruthJUnit.assume().) (2d65326ec)
    • Update: This appears to let users exclude the dependency in some cases but not all. We are working on a fix.
    • Update 2: Also, even if you succeed in excluding the dependency in your environment, you will see failure messages that are missing information. We have a fix for this ready.

If you wish to exclude our JUnit dependency, you may wish to consider this alternative approach. That approach may be worthwhile even after we fix the bugs described above.

I apologize for the trouble.

1.1

  • Fixed (we think :)) R8 compilation failure: Error: com.android.tools.r8.errors.b: Compilation can't be completed because `org.objectweb.asm.ClassVisitor` and 1 other classes are missing. (0bfa285fa)
  • Added unpackingAnyUsing(TypeRegistry, ExtensionRegistry). If you call this method, ProtoTruth will attempt to unpack Any messages before comparing them. (b50d878b)
  • Added formattingDiffsUsing methods to IterableSubject and MapSubject. This allows you to get failure messages which show diffs between the actual and expected elements (like you get with comparingElementsUsing) while still comparing them using object equality. (ae997be77)
  • Changed Checker Framework annotations from checker-qual to qual. (e71b57b9f) With this change, we inadvertently introduced Java 8 bytecode into our dependencies. Please report problems on #882. Sorry for the trouble.
  • Added null checks to StringSubject. (3481ab0af)
  • Included ASM as a dependency (non-<optional>) by default. It is still safe to exclude if you want to minimize dependencies, but by including it, you may see better failure messages. (aea78e81c)
  • Removed dependency on []-user. (b54e9ef50fe670bf93dd3b2b6851423be631b429)
  • API documentation for Truth classes is now easier to reach. For example, for StringSubject, visit truth.dev/StringSubject. Also, more easily access the index at truth.dev/api.

1.0.1

  • Changed failure messages to identify trailing whitespace in failed string comparisons. (7a58a45b)
  • Moved []-user to test scope. (51bbbf42)
  • Fixed handling of proto maps with keys equal to the key type's default value. (8ebfe2ab)
  • Worked around what seems to be a classloading bug in old versions of some vendors' Android runtimes. (02c5e79925d455331377f3e6640cc450aecf6774)
Commits

Updates `truth-java8-extension` from 1.0 to 1.1.3 Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #720 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/720 from google:dependabot/maven/truth.version-1.1.3 8916bd632c588d87908f4d62e4aed99022004dc0 PiperOrigin-RevId: 423801861 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3112ee7f1..231f49625 100644 --- a/pom.xml +++ b/pom.xml @@ -91,7 +91,7 @@ UTF-8 1.8 30.1.1-jre - 1.0 + 1.1.3 3.21.1 2.10.0 1.8.2 From 621fb85a8de8000fd80ced515828789cc45ff037 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 24 Jan 2022 08:14:36 -0800 Subject: [PATCH 138/379] Handle modifiers that start with `non-` Fixes https://github.com/google/google-java-format/issues/696 PiperOrigin-RevId: 423819018 --- .../java/JavaInputAstVisitor.java | 18 ++++++++++-------- .../java/FormatterIntegrationTest.java | 2 +- .../googlejavaformat/java/testdata/I696.input | 11 +++++++++++ .../googlejavaformat/java/testdata/I696.output | 8 ++++++++ 4 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I696.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I696.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 8da719564..daed2502e 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -2294,7 +2294,7 @@ private ImmutableList visitModifiers( ? forceBreakList(declarationAnnotationBreak) : breakList(declarationAnnotationBreak)); } - formatAnnotationOrModifier(declarationModifiers.removeFirst()); + formatAnnotationOrModifier(declarationModifiers); first = false; lastWasAnnotation = true; } @@ -2317,7 +2317,7 @@ private ImmutableList visitModifiers( if (!first) { builder.addAll(breakFillList(Optional.empty())); } - formatAnnotationOrModifier(declarationModifiers.removeFirst()); + formatAnnotationOrModifier(declarationModifiers); first = false; } builder.close(); @@ -2452,10 +2452,15 @@ DeclarationModifiersAndTypeAnnotations splitModifiers( modifiers.subList(0, idx + 1), typeAnnotations.build().reverse()); } - private void formatAnnotationOrModifier(AnnotationOrModifier modifier) { + private void formatAnnotationOrModifier(Deque modifiers) { + AnnotationOrModifier modifier = modifiers.removeFirst(); switch (modifier.getKind()) { case MODIFIER: token(modifier.modifier().getText()); + if (modifier.modifier().getText().equals("non")) { + token(modifiers.removeFirst().modifier().getText()); + token(modifiers.removeFirst().modifier().getText()); + } break; case ANNOTATION: scan(modifier.annotation(), null); @@ -2471,10 +2476,6 @@ boolean isTypeAnnotation(AnnotationTree annotationTree) { return typeAnnotationSimpleNames.contains(((IdentifierTree) annotationType).getName()); } - boolean nextIsModifier() { - return isModifier(builder.peekToken().get()); - } - private static boolean isModifier(String token) { switch (token) { case "public": @@ -2490,7 +2491,8 @@ private static boolean isModifier(String token) { case "strictfp": case "default": case "sealed": - case "non-sealed": + case "non": + case "-": return true; default: return false; diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 22202e98a..61a43468a 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -51,7 +51,7 @@ public class FormatterIntegrationTest { .putAll(14, "I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574", "I594") .putAll(15, "I603") .putAll(16, "I588") - .putAll(17, "I683", "I684") + .putAll(17, "I683", "I684", "I696") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I696.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I696.input new file mode 100644 index 000000000..156e6efc9 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I696.input @@ -0,0 +1,11 @@ +public abstract non-sealed class A extends SealedClass { +} + +non-sealed class B extends SealedClass { +} + +non-sealed @A class B extends SealedClass { +} + +@A non-sealed class B extends SealedClass { +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I696.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I696.output new file mode 100644 index 000000000..14721c378 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I696.output @@ -0,0 +1,8 @@ +public abstract non-sealed class A extends SealedClass {} + +non-sealed class B extends SealedClass {} + +non-sealed @A class B extends SealedClass {} + +@A +non-sealed class B extends SealedClass {} From 3de0712022506bb22aa7e89a7cbd25912696bf37 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 10:21:53 -0800 Subject: [PATCH 139/379] Bump auto-service-annotations from 1.0 to 1.0.1 Bumps [auto-service-annotations](https://github.com/google/auto) from 1.0 to 1.0.1.
Release notes

Sourced from auto-service-annotations's releases.

AutoFactory 1.0.1

  • Fixed Gradle incremental compilation. (8f17e4c4)

AutoCommon 1.0.1

  • Added some methods to allow annotation processors to use Streams functionality that is present in mainline Guava but not Android Guava. This can be useful if Android Guava might be on the processor path.

AutoService 1.0.1

  • AutoService no longer throws an exception for a missing service class. (d8083fde)
  • Fixed a bug in AutoServiceProcessor that could lead to some services not being processed. (d4c865be)
Commits
  • e057b8b Set version number for auto-common to 1.0.1.
  • 15d49d9 Replace server Guava API usage with Android compatible alternatives.
  • 64b9ecc Bump actions/cache from 2.1.5 to 2.1.6
  • 7d3aa66 Implicitly exclude Kotlin @Metadata annotations from @CopyAnnotations
  • 2b77e44 Bump kotlin.version from 1.5.0 to 1.5.10 in /value
  • acb0765 Bump truth from 1.1.2 to 1.1.3 in /factory
  • 7f8bd35 Bump truth from 1.1.2 to 1.1.3 in /common
  • d482097 Bump truth from 1.1.2 to 1.1.3 in /service
  • 31eeb67 Bump truth.version from 1.1.2 to 1.1.3 in /value
  • 54baeb3 Update an AutoValue test to the newer compile-testing API.
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.auto.service:auto-service-annotations&package-manager=maven&previous-version=1.0&new-version=1.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #724 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/724 from google:dependabot/maven/com.google.auto.service-auto-service-annotations-1.0.1 f73ae20a8d349ad0cf51c047cac205a5954e0a97 PiperOrigin-RevId: 423849278 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 231f49625..0b3df5294 100644 --- a/pom.xml +++ b/pom.xml @@ -95,7 +95,7 @@ 3.21.1 2.10.0 1.8.2 - 1.0 + 1.0.1 3.1.0 3.2.1 From fa48f487494ce22c12210902a8b13e18e6c253e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 11:50:46 -0800 Subject: [PATCH 140/379] Bump maven-compiler-plugin from 3.7.0 to 3.9.0 Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.7.0 to 3.9.0.
Commits
  • aeb15b6 [maven-release-plugin] prepare release maven-compiler-plugin-3.9.0
  • 6335382 Shared GitHub Acton v2
  • 8d5d3cd Fix site build
  • ce4eb1e Bump plexus-component-metadata from 2.1.0 to 2.1.1
  • f875750 Bump mockito-core from 4.1.0 to 4.2.0
  • 5463357 fix CI site goal
  • 859c903 Update plugins
  • b0de9bc Bump mockito-core from 4.0.0 to 4.1.0
  • f95dd46 Bump plexusCompilerVersion from 2.8.8 to 2.9.0
  • 26900cf Bump mockito-core from 2.28.2 to 4.0.0
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-compiler-plugin&package-manager=maven&previous-version=3.7.0&new-version=3.9.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #725 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/725 from google:dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.9.0 d8cdb3fd6ae508b7311981da10875797bc57c725 PiperOrigin-RevId: 423873405 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0b3df5294..fab2146df 100644 --- a/pom.xml +++ b/pom.xml @@ -164,7 +164,7 @@ maven-compiler-plugin - 3.7.0 + 3.9.0 maven-jar-plugin From d52e308814a04a5f0a0c3e4b46f73acdee77b089 Mon Sep 17 00:00:00 2001 From: Derek Perez Date: Thu, 27 Jan 2022 13:23:59 -0800 Subject: [PATCH 141/379] GraalVM native-image Maven build support Closes #358. This appears to work as expected. I have a [weird case](https://github.com/oracle/graal/discussions/4254) I'm not really sure how to address (the need to specify -Djava.home during execution), but otherwise, this produces a fully static binary that is very fast and works. To execute the build, you run the following command: ``` mvn -Pnative -DskipTests package ``` Fixes #728 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/728 from perezd:native-image 9b64d0770418601b5a4e82ab6d52bbfca993c87e PiperOrigin-RevId: 424692716 --- core/pom.xml | 39 +++++++++++++++++++ .../META-INF/native-image/reflect-config.json | 6 +++ 2 files changed, 45 insertions(+) create mode 100644 core/src/main/resources/META-INF/native-image/reflect-config.json diff --git a/core/pom.xml b/core/pom.xml index 39b9a3d9e..718385d7e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -249,5 +249,44 @@ + + native + + + + org.graalvm.buildtools + native-maven-plugin + 0.9.9 + true + + + build-native + + build + + package + + + test-native + + test + + test + + + + google-java-format + + ${project.build.directory}/${project.artifactId}-${project.version}-all-deps.jar + + + -H:IncludeResourceBundles=com.sun.tools.javac.resources.compiler + --no-fallback + + + + + + diff --git a/core/src/main/resources/META-INF/native-image/reflect-config.json b/core/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 000000000..2c6580345 --- /dev/null +++ b/core/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,6 @@ +[ + { + "name": "com.sun.tools.javac.parser.UnicodeReader", + "allDeclaredMethods": true + } +] From 0198230882db1c122078d5b8a9b1286f408c2ac5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Jan 2022 07:34:11 -0800 Subject: [PATCH 142/379] Bump error_prone_annotations from 2.10.0 to 2.11.0 Bumps [error_prone_annotations](https://github.com/google/error-prone) from 2.10.0 to 2.11.0.
Release notes

Sourced from error_prone_annotations's releases.

Error Prone 2.11.0

Error Prone now requires JDK 11 or newer (google/error-prone#2730).

New checks

Fixed issues: #2641, #2705, #2776, #2798, #2799, #2819, #2820, #2831, #2833, #2834, #2835, #2861, #2873, #2889, #2892, #2901

Full Changelog: https://github.com/google/error-prone/compare/v2.10.0...v2.11.0

Commits
  • 6439153 Release Error Prone 2.11.0
  • d33ab70 Add backreferences to b/216306810
  • 3f61879 Decrease TooManyParameters default limit from 10 to 9.
  • c2e14f2 Make ASTHelpers.getSymbol(MethodInvocationTree) and friends throw instead o...
  • c18ae52 Autofix all the AnnotationPosition findings in EP.
  • 4698c8e intellij project files update
  • f6a508f Bump more deps.
  • 048a664 Document missing itself lock expression.
  • fbaa55b Update OrphanedFormatString to warn on log("hello %s")
  • e09ca6f More version updates
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=com.google.errorprone:error_prone_annotations&package-manager=maven&previous-version=2.10.0&new-version=2.11.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #729 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/729 from google:dependabot/maven/com.google.errorprone-error_prone_annotations-2.11.0 77a2bb8cc92c18539ccdc47aa6d235571df32df4 PiperOrigin-RevId: 424866054 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fab2146df..95fb8f68c 100644 --- a/pom.xml +++ b/pom.xml @@ -93,7 +93,7 @@ 30.1.1-jre 1.1.3 3.21.1 - 2.10.0 + 2.11.0 1.8.2 1.0.1 3.1.0 From 16e72a1a9bbf182fac6686807e54bc846a9543ed Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 28 Jan 2022 08:43:12 -0800 Subject: [PATCH 143/379] Treat single-character upper case identifiers as UpperCamelCase as a concession to Android `R` classes. PiperOrigin-RevId: 424878859 --- .../com/google/googlejavaformat/java/TypeNameClassifier.java | 2 +- .../google/googlejavaformat/java/TypeNameClassifierTest.java | 2 ++ .../google/googlejavaformat/java/testdata/b26306390.input | 3 +++ .../google/googlejavaformat/java/testdata/b26306390.output | 5 +++++ 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/b26306390.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/b26306390.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/TypeNameClassifier.java b/core/src/main/java/com/google/googlejavaformat/java/TypeNameClassifier.java index 4e871a67f..21fae5f03 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/TypeNameClassifier.java +++ b/core/src/main/java/com/google/googlejavaformat/java/TypeNameClassifier.java @@ -164,7 +164,7 @@ static JavaCaseFormat from(String name) { hasLowercase |= Character.isLowerCase(c); } if (firstUppercase) { - return hasLowercase ? UPPER_CAMEL : UPPERCASE; + return (hasLowercase || name.length() == 1) ? UPPER_CAMEL : UPPERCASE; } else { return hasUppercase ? LOWER_CAMEL : LOWERCASE; } diff --git a/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java b/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java index 9d1e00a18..3270bc64e 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java @@ -43,6 +43,7 @@ public void caseFormat() throws Exception { assertThat(JavaCaseFormat.from("a_$")).isEqualTo(JavaCaseFormat.LOWERCASE); assertThat(JavaCaseFormat.from("_")).isEqualTo(JavaCaseFormat.LOWERCASE); assertThat(JavaCaseFormat.from("_A")).isEqualTo(JavaCaseFormat.UPPERCASE); + assertThat(JavaCaseFormat.from("A")).isEqualTo(JavaCaseFormat.UPPER_CAMEL); } private static Optional getPrefix(String qualifiedName) { @@ -62,6 +63,7 @@ public void typePrefixLength() { assertThat(getPrefix("ClassName.CONST")).hasValue(1); assertThat(getPrefix("ClassName.varName")).hasValue(1); assertThat(getPrefix("ClassName.Inner.varName")).hasValue(2); + assertThat(getPrefix("com.R.foo")).hasValue(2); } @Test diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/b26306390.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/b26306390.input new file mode 100644 index 000000000..da6c01b01 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/b26306390.input @@ -0,0 +1,3 @@ +class B26306390 { + int resourceId = com.some.extremely.verbose.pkg.name.R.string.some_extremely_long_resource_identifier_that_exceeds_the_column_limit; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/b26306390.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/b26306390.output new file mode 100644 index 000000000..a21772f8f --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/b26306390.output @@ -0,0 +1,5 @@ +class B26306390 { + int resourceId = + com.some.extremely.verbose.pkg.name.R.string + .some_extremely_long_resource_identifier_that_exceeds_the_column_limit; +} From f07691cdf6f035f1b9008b72dc3c52597ba7c553 Mon Sep 17 00:00:00 2001 From: Derek Perez Date: Fri, 28 Jan 2022 12:20:36 -0800 Subject: [PATCH 144/379] Defining basic structure. --- .github/workflows/release.yml | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..e3021e19c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,56 @@ +name: Release google-java-format + +on: + workflow_dispatch: + inputs: + version: + description: "version number for this release." + required: true + +env: + JAVA_HOME: "$JAVA_HOME_17_X64" + +jobs: + define-release: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Setup Signing Key + run: | + cat <(echo -e "${{ secrets.GPG_SIGNING_KEY }}") | gpg --batch --import + gpg --list-secret-keys --keyid-format LONG + + - name: Checkout + uses: actions/checkout@2.4.0 + + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: 17 + distribution: 'zulu' + cache: 'maven' + + - name: Run Tests + run: mvn verify + + - name: Bump Version Number + env: + NEW_VERSION: ${{ github.events.input.version }} + run: | + mvn versions:set versions:commit -DnewVersion="${NEW_VERSION}" + git ls-files | grep 'pom.xml$' | xargs git add + git commit -m "Release google-java-format ${NEW_VERSION}" + git tag "v${NEW_VERSION}" + git push origin "v${NEW_VERSION}" + + - name: Create Maven Jars + run: mvn clean deploy + + - name: Define Release Entry + uses: softprops/action-gh-release@v1 + with: + draft: true + name: ${{ github.events.input.version }} + tag_name: "v${{ github.events.input.version }}" + From da0ad7f608eac6ca06fb15d128f21bad05a091a3 Mon Sep 17 00:00:00 2001 From: Derek Perez Date: Fri, 28 Jan 2022 12:22:09 -0800 Subject: [PATCH 145/379] rm custom JAVA_HOME env. --- .github/workflows/release.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e3021e19c..9eee6509e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,9 +7,6 @@ on: description: "version number for this release." required: true -env: - JAVA_HOME: "$JAVA_HOME_17_X64" - jobs: define-release: runs-on: ubuntu-latest From 9da00eb6046dd725cc124c50d04eda6ccebd0e12 Mon Sep 17 00:00:00 2001 From: Derek Perez Date: Fri, 28 Jan 2022 13:06:02 -0800 Subject: [PATCH 146/379] Update release.yml --- .github/workflows/release.yml | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9eee6509e..689f33947 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,10 +8,10 @@ on: required: true jobs: - define-release: + build-maven-jars: runs-on: ubuntu-latest permissions: - contents: write + contents: read steps: - name: Setup Signing Key run: | @@ -20,17 +20,14 @@ jobs: - name: Checkout uses: actions/checkout@2.4.0 - + - name: Set up JDK uses: actions/setup-java@v2 with: java-version: 17 distribution: 'zulu' cache: 'maven' - - - name: Run Tests - run: mvn verify - + - name: Bump Version Number env: NEW_VERSION: ${{ github.events.input.version }} @@ -38,16 +35,15 @@ jobs: mvn versions:set versions:commit -DnewVersion="${NEW_VERSION}" git ls-files | grep 'pom.xml$' | xargs git add git commit -m "Release google-java-format ${NEW_VERSION}" - git tag "v${NEW_VERSION}" - git push origin "v${NEW_VERSION}" - - - name: Create Maven Jars - run: mvn clean deploy + git push + + - name: Build Jars + run: mvn clean verify gpg:sign -DskipTests=true -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" - - name: Define Release Entry + - name: Add Jars to Release Entry uses: softprops/action-gh-release@v1 with: draft: true name: ${{ github.events.input.version }} tag_name: "v${{ github.events.input.version }}" - + files: core/target/google-java-format-*.jar From f004493ab5af51d9d0ceea4c239527feff8c9047 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 31 Jan 2022 13:27:18 -0800 Subject: [PATCH 147/379] Stop hard-coding explicit versions in the README PiperOrigin-RevId: 425446891 --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index aa560505c..5d1d7c7dd 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ and run it with: ``` -java -jar /path/to/google-java-format-1.13.0-all-deps.jar [files...] +java -jar /path/to/google-java-format-${GJF_VERSION?}-all-deps.jar [files...] ``` The formatter can act on whole files, on limited lines (`--lines`), on specific @@ -39,7 +39,7 @@ java \ --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ - -jar google-java-format-1.13.0-all-deps.jar [files...] + -jar google-java-format-${GJF_VERSION?}-all-deps.jar [files...] ``` ### IntelliJ, Android Studio, and other JetBrains IDEs @@ -70,9 +70,9 @@ and import it into File→Settings→Editor→Code Style. ### Eclipse -Version 1.11 of the -[google-java-format Eclipse plugin](https://github.com/google/google-java-format/releases/download/v1.13.0/google-java-format-eclipse-plugin-1.13.0.jar) -can be downloaded from the releases page. Drop it into the Eclipse +The latest version of the `google-java-format` Eclipse plugin can be downloaded +from the [releases page](https://github.com/google/google-java-format/releases). +Drop it into the Eclipse [drop-ins folder](http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fp2_dropins_format.html) to activate the plugin. @@ -113,7 +113,7 @@ configuration. com.google.googlejavaformat google-java-format - 1.13.0 + ${google-java-format.version} ``` @@ -121,7 +121,7 @@ configuration. ```groovy dependencies { - implementation 'com.google.googlejavaformat:google-java-format:1.13.0' + implementation 'com.google.googlejavaformat:google-java-format:$googleJavaFormatVersion' } ``` From 94bedf4e2194716d2df059218aeb3d042247b735 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 31 Jan 2022 13:43:32 -0800 Subject: [PATCH 148/379] Pass `--initialize-at-build-time=com.sun.tools.javac.file.Locations` to native image build to work around https://github.com/oracle/graal/discussions/4254 PiperOrigin-RevId: 425451233 --- core/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/core/pom.xml b/core/pom.xml index 718385d7e..1d4715957 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -282,6 +282,7 @@ -H:IncludeResourceBundles=com.sun.tools.javac.resources.compiler --no-fallback + --initialize-at-build-time=com.sun.tools.javac.file.Locations
From 668f108de438db15158d33ed1a386bdbab3b4d09 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 31 Jan 2022 13:44:08 -0800 Subject: [PATCH 149/379] Don't use single-line for for javadoc without a summary fragment Roll forward of https://github.com/google/google-java-format/commit/06a2105be2d73bbbdc6cb6f8dc43f84e2eb00e07 Using the multi-line form here may call attention to the missing summary fragment. The style guide can also be read as discouraging the single-line form for non-required javadoc missing a summary fragment (see b/74239048#comment4), but I'm not sure that's the intent, and I'm looking at changing it (unknown commit). PiperOrigin-RevId: 425451391 --- .../java/javadoc/JavadocFormatter.java | 25 +++++++++++--- .../java/JavadocFormattingTest.java | 33 ++++++++++++++++++- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java index 5addc6770..03938a677 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java @@ -166,15 +166,30 @@ private static Token standardize(Token token, Token standardToken) { * fits on one line. */ private static String makeSingleLineIfPossible(int blockIndent, String input) { - int oneLinerContentLength = MAX_LINE_LENGTH - "/** */".length() - blockIndent; Matcher matcher = ONE_CONTENT_LINE_PATTERN.matcher(input); - if (matcher.matches() && matcher.group(1).isEmpty()) { - return "/** */"; - } else if (matcher.matches() && matcher.group(1).length() <= oneLinerContentLength) { - return "/** " + matcher.group(1) + " */"; + if (matcher.matches()) { + String line = matcher.group(1); + if (line.isEmpty()) { + return "/** */"; + } else if (oneLineJavadoc(line, blockIndent)) { + return "/** " + line + " */"; + } } return input; } + private static boolean oneLineJavadoc(String line, int blockIndent) { + int oneLinerContentLength = MAX_LINE_LENGTH - "/** */".length() - blockIndent; + if (line.length() > oneLinerContentLength) { + return false; + } + // If the javadoc contains only a tag, use multiple lines to encourage writing a summary + // fragment, unless it's /* @hide */. + if (line.startsWith("@") && !line.equals("@hide")) { + return false; + } + return true; + } + private JavadocFormatter() {} } diff --git a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java index f5103d9b5..6849c01f2 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java @@ -937,7 +937,9 @@ public void onlyParams() { "class Test {}", }; String[] expected = { - "/** @param this is a param */", // + "/**", // + " * @param this is a param", + " */", "class Test {}", }; doFormatTest(input, expected); @@ -1415,4 +1417,33 @@ public void u2028LineSeparator() { }; doFormatTest(input, expected); } + + @Test + public void missingSummaryFragment() { + String[] input = { + "public class Foo {", + " /**", + " * @return something.", + " */", + " public void setSomething() {}", + "", + " /**", + " * @hide", + " */", + " public void setSomething() {}", + "}", + }; + String[] expected = { + "public class Foo {", + " /**", + " * @return something.", + " */", + " public void setSomething() {}", + "", + " /** @hide */", + " public void setSomething() {}", + "}", + }; + doFormatTest(input, expected); + } } From 05c5649ff1549d07be1c9557715a2bf267c5440c Mon Sep 17 00:00:00 2001 From: Derek Perez Date: Mon, 31 Jan 2022 14:35:02 -0800 Subject: [PATCH 150/379] Maven artifacts + GitHub Release page automation Fixes #733 PiperOrigin-RevId: 425464073 --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 38 ++++++++++++++++++++++------------- eclipse_plugin/pom.xml | 2 +- pom.xml | 3 --- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e15d01cd3..a1da280ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest ] - java: [ 17, 14, 11 ] + java: [ 17, 11 ] experimental: [ false ] include: # Only test on macos and windows with a single recent JDK to avoid a diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 689f33947..08619cd8c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,39 +11,49 @@ jobs: build-maven-jars: runs-on: ubuntu-latest permissions: - contents: read + contents: write steps: - name: Setup Signing Key run: | - cat <(echo -e "${{ secrets.GPG_SIGNING_KEY }}") | gpg --batch --import + gpg-agent --daemon --default-cache-ttl 7200 + echo -e "${{ secrets.GPG_SIGNING_KEY }}" | gpg --batch --import --no-tty + echo "hello world" > temp.txt + gpg --detach-sig --yes -v --output=/dev/null --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" temp.txt + rm temp.txt gpg --list-secret-keys --keyid-format LONG - name: Checkout - uses: actions/checkout@2.4.0 + uses: actions/checkout@v2.4.0 - name: Set up JDK - uses: actions/setup-java@v2 + uses: actions/setup-java@v2.5.0 with: java-version: 17 distribution: 'zulu' cache: 'maven' - name: Bump Version Number - env: - NEW_VERSION: ${{ github.events.input.version }} run: | - mvn versions:set versions:commit -DnewVersion="${NEW_VERSION}" + mvn --no-transfer-progress versions:set versions:commit -DnewVersion="${{ github.event.inputs.version }}" + mvn tycho-versions:update-eclipse-metadata -pl eclipse_plugin git ls-files | grep 'pom.xml$' | xargs git add - git commit -m "Release google-java-format ${NEW_VERSION}" + git config --global user.email "${{ github.actor }}@users.noreply.github.com" + git config --global user.name "${{ github.actor }}" + git commit -m "Release google-java-format ${{ github.event.inputs.version }}" + echo "TARGET_COMMITISH=$(git rev-parse HEAD)" >> $GITHUB_ENV + git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/google/google-java-format.git git push - + - name: Build Jars - run: mvn clean verify gpg:sign -DskipTests=true -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" + run: mvn --no-transfer-progress clean verify gpg:sign -DskipTests=true -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" - name: Add Jars to Release Entry - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v0.1.14 with: draft: true - name: ${{ github.events.input.version }} - tag_name: "v${{ github.events.input.version }}" - files: core/target/google-java-format-*.jar + name: ${{ github.event.input.version }} + tag_name: "v${{ github.event.inputs.version }}" + target_commitish: ${{ env.TARGET_COMMITISH }} + files: | + core/target/google-java-format-*.jar + eclipse_plugin/target/google-java-format-eclipse-plugin-*.jar diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index ee5635c42..bf3ef3d60 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -32,7 +32,7 @@ UTF-8 - 1.7.0 + 2.6.0 diff --git a/pom.xml b/pom.xml index 95fb8f68c..5d768de79 100644 --- a/pom.xml +++ b/pom.xml @@ -27,10 +27,7 @@ core - Google Java Format Parent From 69799747b38ad42bf51ad4c2e67f2f8a12bd8a17 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 31 Jan 2022 16:13:11 -0800 Subject: [PATCH 151/379] Update release.yml Try to only push the new tag --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 08619cd8c..7bf270ba7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,7 @@ jobs: git commit -m "Release google-java-format ${{ github.event.inputs.version }}" echo "TARGET_COMMITISH=$(git rev-parse HEAD)" >> $GITHUB_ENV git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/google/google-java-format.git - git push + git push origin "${{ github.event.inputs.version }}" - name: Build Jars run: mvn --no-transfer-progress clean verify gpg:sign -DskipTests=true -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" From f72191b67add34474644e6eb65b4b5295e1b8446 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 31 Jan 2022 16:26:49 -0800 Subject: [PATCH 152/379] Update release.yml Tag release commits --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7bf270ba7..2c5315d9f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,9 +40,10 @@ jobs: git config --global user.email "${{ github.actor }}@users.noreply.github.com" git config --global user.name "${{ github.actor }}" git commit -m "Release google-java-format ${{ github.event.inputs.version }}" + git tag "v${{ github.event.inputs.version }}" echo "TARGET_COMMITISH=$(git rev-parse HEAD)" >> $GITHUB_ENV git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/google/google-java-format.git - git push origin "${{ github.event.inputs.version }}" + git push origin "v${{ github.event.inputs.version }}" - name: Build Jars run: mvn --no-transfer-progress clean verify gpg:sign -DskipTests=true -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" From 4c649342725460d08f7a14d3c5033f0b099d9dbd Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 31 Jan 2022 16:37:30 -0800 Subject: [PATCH 153/379] Update ci.yml Use JDK 17 to build snapshots --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1da280ca..033cf2da1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,10 +73,10 @@ jobs: steps: - name: 'Check out repository' uses: actions/checkout@v2 - - name: 'Set up JDK 15' + - name: 'Set up JDK 17' uses: actions/setup-java@v2 with: - java-version: 15 + java-version: 17 distribution: 'zulu' cache: 'maven' server-id: sonatype-nexus-snapshots From 9d2225aafabb1cc4c3c4e4f496decd9ee10e07b8 Mon Sep 17 00:00:00 2001 From: Kurt Alfred Kluever Date: Tue, 1 Feb 2022 09:32:46 -0800 Subject: [PATCH 154/379] Automatic code cleanup. PiperOrigin-RevId: 425644626 --- .../main/java/com/google/googlejavaformat/java/JavaInput.java | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index e671ad012..165bdebb1 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -311,7 +311,7 @@ private static ImmutableMap makePositionToColumnMap(List for (Tok tok : toks) { builder.put(tok.getPosition(), tok.getColumn()); } - return builder.build(); + return builder.buildOrThrow(); } /** diff --git a/pom.xml b/pom.xml index 5d768de79..5ea3c3b3d 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ UTF-8 1.8 - 30.1.1-jre + 31.0.1-jre 1.1.3 3.21.1 2.11.0 From 0c95c8f635cf4acc42a020382229dbf8ca0cb2ef Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 1 Feb 2022 10:08:22 -0800 Subject: [PATCH 155/379] Update ci.yml Skip the eclipse plugin for snapshot builds --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 033cf2da1..016b8e776 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,4 +86,4 @@ jobs: env: CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} - run: mvn source:jar deploy -B -DskipTests=true -Dinvoker.skip=true -Dmaven.javadoc.skip=true + run: mvn -pl '!eclipse_plugin' source:jar deploy -B -DskipTests=true -Dinvoker.skip=true -Dmaven.javadoc.skip=true From 304bb7184a105e0029baae38108319e59631b614 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 2 Feb 2022 13:45:03 -0800 Subject: [PATCH 156/379] Update dependabot.yml Stop updating github-actions --- .github/dependabot.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b76b89570..daec31893 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,7 +4,3 @@ updates: directory: "/" schedule: interval: "daily" - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" From af804c68b8f2bd790e1a0a0848b6c74a519ed975 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 2 Feb 2022 16:52:08 -0800 Subject: [PATCH 157/379] Update versions PiperOrigin-RevId: 426010942 --- eclipse_plugin/pom.xml | 2 +- pom.xml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index bf3ef3d60..534e685f0 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -56,7 +56,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.1.2 + 3.2.0 copy-dependencies diff --git a/pom.xml b/pom.xml index 5ea3c3b3d..1f3855b80 100644 --- a/pom.xml +++ b/pom.xml @@ -91,9 +91,9 @@ 1.1.3 3.21.1 2.11.0 - 1.8.2 + 1.9 1.0.1 - 3.1.0 + 3.3.1 3.2.1 @@ -173,7 +173,7 @@
maven-javadoc-plugin - 3.2.0 + 3.3.1 maven-gpg-plugin @@ -182,7 +182,7 @@ org.apache.felix maven-bundle-plugin - 2.4.0 + 5.1.4 @@ -251,7 +251,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.2.0 + 3.3.1 none From d86e930de93f123994fba151a8d289b8035db87b Mon Sep 17 00:00:00 2001 From: Zakaria Elkatani Date: Fri, 4 Feb 2022 14:23:19 -0800 Subject: [PATCH 158/379] Make some best-practices changes to the plugin. Since the last plugin update was almost half a year ago, I thought it would be prudent to update it and resolve most of the issues regarding updating the plugin. It took around half an hour once I managed to correctly set up the module due to the gradle plugin version 1.2.1 + intellij version 2020.3 requiring java 11 to develop. All of the included annotation changes were requested by IntelliJ to add since the overrides added them as well. The change of `` to `` was to resolve the syntax errors introduced by a change removing the wildcard requirement. NotificationGroup was deprecated and moved into the plugin xml file as per the SDK docs The same was required for `StdFileTypes.JAVA` being deprecated with the fix being `JavaFileType.INSTANCE` + changing the depend module to add that fix. I had to change the project SDK to JDK 11 on my end to have the gradle build work. I also tested the plugin with 1.12 and 1.10 on some test files such as from #653 and #654. Would be good to have some double checking though because I've had issues trying to get the test file reformatted in #558 working. Probably because it's locked behind an experimental flag? Fixes #688 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/688 from ze:idea-1.12.0 53f216cd030a553c8200c75606168de0a8039e1a PiperOrigin-RevId: 426491735 --- idea_plugin/.gitignore | 5 ++ idea_plugin/build.gradle | 24 ++++---- idea_plugin/resources/META-INF/plugin.xml | 24 +++++--- .../intellij/CodeStyleManagerDecorator.java | 57 +++++++++++-------- .../intellij/FormatterUtil.java | 3 +- .../GoogleJavaFormatCodeStyleManager.java | 24 ++++---- .../intellij/GoogleJavaFormatSettings.java | 7 ++- ...alConfigurationProjectManagerListener.java | 5 +- 8 files changed, 87 insertions(+), 62 deletions(-) create mode 100644 idea_plugin/.gitignore diff --git a/idea_plugin/.gitignore b/idea_plugin/.gitignore new file mode 100644 index 000000000..16bc65a53 --- /dev/null +++ b/idea_plugin/.gitignore @@ -0,0 +1,5 @@ +build +.gradle +gradle +gradlew +gradlew.bat \ No newline at end of file diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 36c12f13f..d9f769d47 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "1.3.0" + id "org.jetbrains.intellij" version "1.3.1" } repositories { @@ -23,23 +23,27 @@ repositories { } ext { - googleJavaFormatVersion = '1.13.0' + googleJavaFormatVersion = "1.13.0" } -apply plugin: 'org.jetbrains.intellij' -apply plugin: 'java' +apply plugin: "org.jetbrains.intellij" +apply plugin: "java" + +sourceCompatibility = JavaVersion.VERSION_11 +targetCompatibility = JavaVersion.VERSION_11 intellij { pluginName = "google-java-format" - version = "IC-213.5744.18-EAP-SNAPSHOT" + plugins = ["java"] + version = "221.3427-EAP-CANDIDATE-SNAPSHOT" } patchPluginXml { pluginDescription = "Formats source code using the google-java-format tool. This version of " + "the plugin uses version ${googleJavaFormatVersion} of the tool." - version = "${googleJavaFormatVersion}.0" - sinceBuild = '201' - untilBuild = '' + version.set("${googleJavaFormatVersion}.0") + sinceBuild = "203" + untilBuild = "" } publishPlugin { @@ -48,8 +52,8 @@ publishPlugin { sourceSets { main { - java.srcDir 'src' - resources.srcDir 'resources' + java.srcDir "src" + resources.srcDir "resources" } } diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index 60705902a..f10cde5a3 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -14,7 +14,8 @@ limitations under the License. --> - + google-java-format google-java-format @@ -24,7 +25,7 @@ - com.intellij.modules.lang + com.intellij.java @@ -58,17 +59,22 @@ ]]> - + + topic="com.intellij.openapi.project.ProjectManagerListener"/> - - + + + diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java index fc335ad63..af5da957a 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java @@ -34,10 +34,11 @@ import com.intellij.util.ThrowableRunnable; import java.util.Collection; import org.checkerframework.checker.nullness.qual.Nullable; +import org.jetbrains.annotations.NotNull; /** * Decorates the {@link CodeStyleManager} abstract class by delegating to a concrete implementation - * instance (likely IJ's default instance). + * instance (likely IntelliJ's default instance). */ @SuppressWarnings("deprecation") class CodeStyleManagerDecorator extends CodeStyleManager @@ -54,98 +55,102 @@ CodeStyleManager getDelegate() { } @Override - public Project getProject() { + public @NotNull Project getProject() { return delegate.getProject(); } @Override - public PsiElement reformat(PsiElement element) throws IncorrectOperationException { + public @NotNull PsiElement reformat(@NotNull PsiElement element) + throws IncorrectOperationException { return delegate.reformat(element); } @Override - public PsiElement reformat(PsiElement element, boolean canChangeWhiteSpacesOnly) + public @NotNull PsiElement reformat(@NotNull PsiElement element, boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException { return delegate.reformat(element, canChangeWhiteSpacesOnly); } @Override - public PsiElement reformatRange(PsiElement element, int startOffset, int endOffset) + public PsiElement reformatRange(@NotNull PsiElement element, int startOffset, int endOffset) throws IncorrectOperationException { return delegate.reformatRange(element, startOffset, endOffset); } @Override public PsiElement reformatRange( - PsiElement element, int startOffset, int endOffset, boolean canChangeWhiteSpacesOnly) + @NotNull PsiElement element, int startOffset, int endOffset, boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException { return delegate.reformatRange(element, startOffset, endOffset, canChangeWhiteSpacesOnly); } @Override - public void reformatText(PsiFile file, int startOffset, int endOffset) + public void reformatText(@NotNull PsiFile file, int startOffset, int endOffset) throws IncorrectOperationException { delegate.reformatText(file, startOffset, endOffset); } @Override - public void reformatText(PsiFile file, Collection ranges) + public void reformatText(@NotNull PsiFile file, @NotNull Collection ranges) throws IncorrectOperationException { delegate.reformatText(file, ranges); } @Override - public void reformatTextWithContext(PsiFile psiFile, ChangedRangesInfo changedRangesInfo) + public void reformatTextWithContext( + @NotNull PsiFile psiFile, @NotNull ChangedRangesInfo changedRangesInfo) throws IncorrectOperationException { delegate.reformatTextWithContext(psiFile, changedRangesInfo); } @Override - public void reformatTextWithContext(PsiFile file, Collection ranges) + public void reformatTextWithContext( + @NotNull PsiFile file, @NotNull Collection ranges) throws IncorrectOperationException { delegate.reformatTextWithContext(file, ranges); } @Override - public void adjustLineIndent(PsiFile file, TextRange rangeToAdjust) + public void adjustLineIndent(@NotNull PsiFile file, TextRange rangeToAdjust) throws IncorrectOperationException { delegate.adjustLineIndent(file, rangeToAdjust); } @Override - public int adjustLineIndent(PsiFile file, int offset) throws IncorrectOperationException { + public int adjustLineIndent(@NotNull PsiFile file, int offset) + throws IncorrectOperationException { return delegate.adjustLineIndent(file, offset); } @Override - public int adjustLineIndent(Document document, int offset) { + public int adjustLineIndent(@NotNull Document document, int offset) { return delegate.adjustLineIndent(document, offset); } - public void scheduleIndentAdjustment(Document document, int offset) { + public void scheduleIndentAdjustment(@NotNull Document document, int offset) { delegate.scheduleIndentAdjustment(document, offset); } @Override - public boolean isLineToBeIndented(PsiFile file, int offset) { + public boolean isLineToBeIndented(@NotNull PsiFile file, int offset) { return delegate.isLineToBeIndented(file, offset); } @Override @Nullable - public String getLineIndent(PsiFile file, int offset) { + public String getLineIndent(@NotNull PsiFile file, int offset) { return delegate.getLineIndent(file, offset); } @Override @Nullable - public String getLineIndent(PsiFile file, int offset, FormattingMode mode) { + public String getLineIndent(@NotNull PsiFile file, int offset, FormattingMode mode) { return delegate.getLineIndent(file, offset, mode); } @Override @Nullable - public String getLineIndent(Document document, int offset) { + public String getLineIndent(@NotNull Document document, int offset) { return delegate.getLineIndent(document, offset); } @@ -165,7 +170,7 @@ public Indent zeroIndent() { } @Override - public void reformatNewlyAddedElement(ASTNode block, ASTNode addedElement) + public void reformatNewlyAddedElement(@NotNull ASTNode block, @NotNull ASTNode addedElement) throws IncorrectOperationException { delegate.reformatNewlyAddedElement(block, addedElement); } @@ -192,22 +197,23 @@ public T performActionWithFormatterDisabled(Computable r) { } @Override - public int getSpacing(PsiFile file, int offset) { + public int getSpacing(@NotNull PsiFile file, int offset) { return delegate.getSpacing(file, offset); } @Override - public int getMinLineFeeds(PsiFile file, int offset) { + public int getMinLineFeeds(@NotNull PsiFile file, int offset) { return delegate.getMinLineFeeds(file, offset); } @Override - public void runWithDocCommentFormattingDisabled(PsiFile file, Runnable runnable) { + public void runWithDocCommentFormattingDisabled( + @NotNull PsiFile file, @NotNull Runnable runnable) { delegate.runWithDocCommentFormattingDisabled(file, runnable); } @Override - public DocCommentSettings getDocCommentSettings(PsiFile file) { + public @NotNull DocCommentSettings getDocCommentSettings(@NotNull PsiFile file) { return delegate.getDocCommentSettings(file); } @@ -223,7 +229,8 @@ public FormattingMode getCurrentFormattingMode() { } @Override - public int adjustLineIndent(final Document document, final int offset, FormattingMode mode) + public int adjustLineIndent( + final @NotNull Document document, final int offset, FormattingMode mode) throws IncorrectOperationException { if (delegate instanceof FormattingModeAwareIndentAdjuster) { return ((FormattingModeAwareIndentAdjuster) delegate) @@ -233,7 +240,7 @@ public int adjustLineIndent(final Document document, final int offset, Formattin } @Override - public void scheduleReformatWhenSettingsComputed(PsiFile file) { + public void scheduleReformatWhenSettingsComputed(@NotNull PsiFile file) { delegate.scheduleReformatWhenSettingsComputed(file); } } diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java b/idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java index 9939bbade..a5e69c93d 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java @@ -50,8 +50,7 @@ static Map getReplacements( } private static Collection> toRanges(Collection textRanges) { - return textRanges - .stream() + return textRanges.stream() .map(textRange -> Range.closedOpen(textRange.getStartOffset(), textRange.getEndOffset())) .collect(Collectors.toList()); } diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java index 550d0a93c..3d56743ee 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java @@ -22,10 +22,10 @@ import com.google.googlejavaformat.java.Formatter; import com.google.googlejavaformat.java.JavaFormatterOptions; import com.google.googlejavaformat.java.JavaFormatterOptions.Style; +import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; @@ -44,7 +44,7 @@ /** * A {@link CodeStyleManager} implementation which formats .java files with google-java-format. - * Formatting of all other types of files is delegated to IJ's default implementation. + * Formatting of all other types of files is delegated to IntelliJ's default implementation. */ class GoogleJavaFormatCodeStyleManager extends CodeStyleManagerDecorator { @@ -53,7 +53,7 @@ public GoogleJavaFormatCodeStyleManager(@NotNull CodeStyleManager original) { } @Override - public void reformatText(PsiFile file, int startOffset, int endOffset) + public void reformatText(@NotNull PsiFile file, int startOffset, int endOffset) throws IncorrectOperationException { if (overrideFormatterForFile(file)) { formatInternal(file, ImmutableList.of(new TextRange(startOffset, endOffset))); @@ -63,7 +63,7 @@ public void reformatText(PsiFile file, int startOffset, int endOffset) } @Override - public void reformatText(PsiFile file, Collection ranges) + public void reformatText(@NotNull PsiFile file, @NotNull Collection ranges) throws IncorrectOperationException { if (overrideFormatterForFile(file)) { formatInternal(file, ranges); @@ -73,7 +73,7 @@ public void reformatText(PsiFile file, Collection ranges) } @Override - public void reformatTextWithContext(PsiFile file, ChangedRangesInfo info) + public void reformatTextWithContext(@NotNull PsiFile file, @NotNull ChangedRangesInfo info) throws IncorrectOperationException { List ranges = new ArrayList<>(); if (info.insertedRanges != null) { @@ -84,7 +84,8 @@ public void reformatTextWithContext(PsiFile file, ChangedRangesInfo info) } @Override - public void reformatTextWithContext(PsiFile file, Collection ranges) { + public void reformatTextWithContext( + @NotNull PsiFile file, @NotNull Collection ranges) { if (overrideFormatterForFile(file)) { formatInternal(file, ranges); } else { @@ -94,7 +95,10 @@ public void reformatTextWithContext(PsiFile file, Collection ranges * Format the ranges of the given document. * *

Overriding methods will need to modify the document with the result of the external - * formatter (usually using {@link #performReplacements(Document, Map)}. + * formatter (usually using {@link #performReplacements(Document, Map)}). */ private void format(Document document, Collection ranges) { Style style = GoogleJavaFormatSettings.getInstance(getProject()).getStyle(); diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java index f6d9b5ff1..1e92a4bdd 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java @@ -23,6 +23,7 @@ import com.intellij.openapi.components.Storage; import com.intellij.openapi.project.Project; import org.checkerframework.checker.nullness.qual.Nullable; +import org.jetbrains.annotations.NotNull; @State( name = "GoogleJavaFormatSettings", @@ -42,7 +43,7 @@ public State getState() { } @Override - public void loadState(State state) { + public void loadState(@NotNull State state) { this.state = state; } @@ -73,7 +74,7 @@ void setStyle(JavaFormatterOptions.Style style) { enum EnabledState { UNKNOWN, ENABLED, - DISABLED; + DISABLED } static class State { @@ -85,7 +86,7 @@ static class State { public void setEnabled(@Nullable String enabledStr) { if (enabledStr == null) { enabled = EnabledState.UNKNOWN; - } else if (Boolean.valueOf(enabledStr)) { + } else if (Boolean.parseBoolean(enabledStr)) { enabled = EnabledState.ENABLED; } else { enabled = EnabledState.DISABLED; diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java b/idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java index da02310c7..1906347f7 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java @@ -17,8 +17,8 @@ package com.google.googlejavaformat.intellij; import com.intellij.notification.Notification; -import com.intellij.notification.NotificationDisplayType; import com.intellij.notification.NotificationGroup; +import com.intellij.notification.NotificationGroupManager; import com.intellij.notification.NotificationType; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManagerListener; @@ -28,11 +28,10 @@ final class InitialConfigurationProjectManagerListener implements ProjectManager private static final String NOTIFICATION_TITLE = "Enable google-java-format"; private static final NotificationGroup NOTIFICATION_GROUP = - new NotificationGroup(NOTIFICATION_TITLE, NotificationDisplayType.STICKY_BALLOON, true); + NotificationGroupManager.getInstance().getNotificationGroup(NOTIFICATION_TITLE); @Override public void projectOpened(@NotNull Project project) { - GoogleJavaFormatSettings settings = GoogleJavaFormatSettings.getInstance(project); if (settings.isUninitialized()) { From 7629900d72648c7040c87ace856c8a50318ca83d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Feb 2022 08:14:40 -0800 Subject: [PATCH 159/379] Bump checker-qual from 3.21.1 to 3.21.2 Bumps [checker-qual](https://github.com/typetools/checker-framework) from 3.21.1 to 3.21.2.

Release notes

Sourced from checker-qual's releases.

Checker Framework 3.21.2

Version 3.21.2 (February 1, 2022)

User-visible changes:

The wpi.sh script supports non-standard names for build system compile targets via the new -c command-line option.

The Checker Framework now more precisely computes and checks the type of the pattern variable in a pattern match instanceof.

Implementation details:

Deprecated CFGLambda.getMethod{Name} in favor of getEnclosingMethod{Name}.

Closed issues: #4615, #4993, #5006, #5007, #5008, #5013, #5016, #5021.

Changelog

Sourced from checker-qual's changelog.

Version 3.21.2 (March 1, 2022)

User-visible changes:

Implementation details:

Closed issues:

Version 3.21.2 (February 1, 2022)

User-visible changes:

The wpi.sh script supports non-standard names for build system compile targets via the new -c command-line option.

The Checker Framework now more precisely computes and checks the type of the pattern variable in a pattern match instanceof.

Implementation details:

Deprecated CFGLambda.getMethod{Name} in favor of getEnclosingMethod{Name}.

Closed issues: #4615, #4993, #5006, #5007, #5008, #5013, #5016, #5021.

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.checkerframework:checker-qual&package-manager=maven&previous-version=3.21.1&new-version=3.21.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #743 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/743 from google:dependabot/maven/org.checkerframework-checker-qual-3.21.2 d2ffb4a989b7cc261d163aca6e685dd23505df68 PiperOrigin-RevId: 427475341 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1f3855b80..c7f685698 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 1.8 31.0.1-jre 1.1.3 - 3.21.1 + 3.21.2 2.11.0 1.9 1.0.1 From 71dd2a3897745fa0d5c04c9343e39833a03357c3 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 9 Feb 2022 11:14:32 -0800 Subject: [PATCH 160/379] Update release.yml Update release workflow to actually push to sonatype --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2c5315d9f..09cd08048 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,7 +46,7 @@ jobs: git push origin "v${{ github.event.inputs.version }}" - name: Build Jars - run: mvn --no-transfer-progress clean verify gpg:sign -DskipTests=true -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" + run: mvn --no-transfer-progress -P sonatype-oss-release clean deploy -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" - name: Add Jars to Release Entry uses: softprops/action-gh-release@v0.1.14 From e35f4a9db0f0ed0c4e9d0502ca2592b1abafc7cc Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 9 Feb 2022 11:25:34 -0800 Subject: [PATCH 161/379] Update release.yml Set up sonatype credentials, and push the tag after `mvn deploy` in case the build fails --- .github/workflows/release.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 09cd08048..c18d40c7a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,9 @@ jobs: java-version: 17 distribution: 'zulu' cache: 'maven' + server-id: sonatype-nexus-staging + server-username: CI_DEPLOY_USERNAME + server-password: CI_DEPLOY_PASSWORD - name: Bump Version Number run: | @@ -43,11 +46,17 @@ jobs: git tag "v${{ github.event.inputs.version }}" echo "TARGET_COMMITISH=$(git rev-parse HEAD)" >> $GITHUB_ENV git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/google/google-java-format.git - git push origin "v${{ github.event.inputs.version }}" - name: Build Jars + env: + CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} + CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} run: mvn --no-transfer-progress -P sonatype-oss-release clean deploy -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" + - name: Push tag + run: | + git push origin "v${{ github.event.inputs.version }}" + - name: Add Jars to Release Entry uses: softprops/action-gh-release@v0.1.14 with: From 2affc9899279b9ff8fd51df8a70d4e2b9cd309e0 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 9 Feb 2022 11:36:37 -0800 Subject: [PATCH 162/379] Update release.yml Build the Eclipse plugin separately --- .github/workflows/release.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c18d40c7a..a3f066df0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -47,11 +47,16 @@ jobs: echo "TARGET_COMMITISH=$(git rev-parse HEAD)" >> $GITHUB_ENV git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/google/google-java-format.git - - name: Build Jars + - name: Deploy to Sonatype staging env: CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} - run: mvn --no-transfer-progress -P sonatype-oss-release clean deploy -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" + run: + mvn --no-transfer-progress -pl '!eclipse_plugin' -P sonatype-oss-release clean deploy -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" + + - name: Build Eclipse plugin + run: + mvn --no-transfer-progress -pl 'eclipse_plugin' verify gpg:sign -DskipTests=true -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" - name: Push tag run: | From ca91facc04718111572da51b1e61827a1a619d29 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Mon, 21 Feb 2022 21:26:44 -0800 Subject: [PATCH 163/379] Update the IntelliJ plugin to gjf 1.14.0. PiperOrigin-RevId: 430128196 --- idea_plugin/build.gradle | 4 ++-- idea_plugin/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index d9f769d47..1a8bca26c 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "1.3.1" + id "org.jetbrains.intellij" version "1.4.0" } repositories { @@ -23,7 +23,7 @@ repositories { } ext { - googleJavaFormatVersion = "1.13.0" + googleJavaFormatVersion = "1.14.0" } apply plugin: "org.jetbrains.intellij" diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index f10cde5a3..09360c15d 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -29,6 +29,8 @@ +
1.14.0.0
+
Updated to use google-java-format 1.14.
1.13.0.0
Updated to use google-java-format 1.13.
1.12.0.0
From 4e83b17484ff59cd2efac15da02f0b02d79b571d Mon Sep 17 00:00:00 2001 From: Cameron Gregor Date: Wed, 23 Feb 2022 08:14:09 -0800 Subject: [PATCH 164/379] Update fmt-maven-plugin README link from coveo to spotify Spotify has taken over as maintainers of fmt-maven-plugin, so this PR is just updating the link in the README. See https://github.com/spotify/fmt-maven-plugin/issues/105 for reference Fixes #752 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/752 from camac:readme-coveo-to-spotify 80c1df507c7c1866a46f8d8888eb43a772b0cca9 PiperOrigin-RevId: 430456599 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d1d7c7dd..793a66c8b 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ Implementation`. * [sherter/google-java-format-gradle-plugin](https://github.com/sherter/google-java-format-gradle-plugin) * Apache Maven plugins * [spotless](https://github.com/diffplug/spotless/tree/main/plugin-maven#google-java-format) - * [coveo/fmt-maven-plugin](https://github.com/coveo/fmt-maven-plugin) + * [spotify/fmt-maven-plugin](https://github.com/spotify/fmt-maven-plugin) * [talios/googleformatter-maven-plugin](https://github.com/talios/googleformatter-maven-plugin) * [Cosium/maven-git-code-format](https://github.com/Cosium/maven-git-code-format): A maven plugin that automatically deploys google-java-format as a From ec76c664107109225dfca2a302cde3fa28ed57cb Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 2 Mar 2022 17:18:01 -0800 Subject: [PATCH 165/379] Document new g-j-f release process PiperOrigin-RevId: 432066347 --- scripts/mvn-deploy.sh | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100755 scripts/mvn-deploy.sh diff --git a/scripts/mvn-deploy.sh b/scripts/mvn-deploy.sh deleted file mode 100755 index 0133e3612..000000000 --- a/scripts/mvn-deploy.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -# Copyright 2020 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -if [ $# -lt 1 ]; then - echo "usage $0 [ ...]" - exit 1; -fi -key=${1} -shift -params=${@} - -#validate key -keystatus=$(gpg --list-keys | grep ${key} | awk '{print $1}') -if [ "${keystatus}" != "pub" ]; then - echo "Could not find public key with label ${key}" - echo -n "Available keys from: " - gpg --list-keys | grep --invert-match '^sub' - - exit 1 -fi - -mvn ${params} -P sonatype-oss-release -Dgpg.keyname=${key} deploy From ee81afc93990493701a6f7a2801eff058ac57891 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 7 Mar 2022 08:08:34 -0800 Subject: [PATCH 166/379] Use `Add-Exports` and `Add-Opens` manifest entries for google-java-format to avoid passing the flags on the command line when using `java -jar`. PiperOrigin-RevId: 432947555 --- pom.xml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c7f685698..f6c7b590d 100644 --- a/pom.xml +++ b/pom.xml @@ -198,13 +198,13 @@ -XDcompilePolicy=simple -Xplugin:ErrorProne + --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED - --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED - --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED @@ -233,6 +233,19 @@ com.google.googlejavaformat.java.Main + + jdk.compiler/com.sun.tools.javac.api jdk.compiler/com.sun.tools.javac.file jdk.compiler/com.sun.tools.javac.main jdk.compiler/com.sun.tools.javac.model jdk.compiler/com.sun.tools.javac.parser jdk.compiler/com.sun.tools.javac.processing jdk.compiler/com.sun.tools.javac.tree jdk.compiler/com.sun.tools.javac.util + jdk.compiler/com.sun.tools.javac.code jdk.compiler/com.sun.tools.javac.comp +
From 13ca73ebbfa86f6aca5f86be16e6829de6d5014c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 7 Mar 2022 09:06:56 -0800 Subject: [PATCH 167/379] Remove documentation for `--add-exports` and `--add-opens` flags These are now specified in the manifest: unknown commit PiperOrigin-RevId: 432959471 --- README.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/README.md b/README.md index 793a66c8b..cdb82c900 100644 --- a/README.md +++ b/README.md @@ -27,21 +27,6 @@ To reformat changed lines in a specific patch, use formatting. This is a deliberate design decision to unify our code formatting on a single format.* -#### JDK 16 - -The following flags are required when running on JDK 16, due to -[JEP 396: Strongly Encapsulate JDK Internals by Default](https://openjdk.java.net/jeps/396): - -``` -java \ - --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ - --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ - --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \ - --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ - --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ - -jar google-java-format-${GJF_VERSION?}-all-deps.jar [files...] -``` - ### IntelliJ, Android Studio, and other JetBrains IDEs A From e9410fc57a4a112bfb101a74c787e0ea66081229 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Thu, 10 Mar 2022 21:57:26 -0800 Subject: [PATCH 168/379] Update the IntelliJ plugin to gjf 1.15.0. PiperOrigin-RevId: 433928217 --- idea_plugin/build.gradle | 2 +- idea_plugin/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 1a8bca26c..294d77e73 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -23,7 +23,7 @@ repositories { } ext { - googleJavaFormatVersion = "1.14.0" + googleJavaFormatVersion = "1.15.0" } apply plugin: "org.jetbrains.intellij" diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/resources/META-INF/plugin.xml index 09360c15d..42d5f3b31 100644 --- a/idea_plugin/resources/META-INF/plugin.xml +++ b/idea_plugin/resources/META-INF/plugin.xml @@ -29,6 +29,8 @@ +
1.15.0.0
+
Updated to use google-java-format 1.15.0.
1.14.0.0
Updated to use google-java-format 1.14.
1.13.0.0
From b316fffe106496b4fc12184b50fb9bbca59c725c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 14 Mar 2022 10:39:23 -0700 Subject: [PATCH 169/379] Mention `--add-exports` in the docs for using g-j-f as a library https://github.com/google/google-java-format/pull/760#pullrequestreview-902082926 PiperOrigin-RevId: 434504969 --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index cdb82c900..02ef5c5fc 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,18 @@ The formatter can be used in software which generates java to output more legible java code. Just include the library in your maven/gradle/etc. configuration. +`google-java-format` uses internal javac APIs for parsing Java source. The +following JVM flags are required when running on JDK 16 and newer, due to +[JEP 396: Strongly Encapsulate JDK Internals by Default](https://openjdk.java.net/jeps/396): + +``` +--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +``` + #### Maven ```xml From 27670bee4fb54b237344dc66bd7e243c7e16c94b Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 25 Mar 2022 15:33:05 -0700 Subject: [PATCH 170/379] Avoid ignoring constructor results PiperOrigin-RevId: 437348911 --- .../main/java/com/google/googlejavaformat/java/JavaInput.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 165bdebb1..eee210e20 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -49,6 +49,7 @@ import javax.tools.Diagnostic; import javax.tools.DiagnosticCollector; import javax.tools.DiagnosticListener; +import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; import javax.tools.SimpleJavaFileObject; @@ -349,7 +350,8 @@ static ImmutableList buildToks(String text, ImmutableSet stopTok stopTokens = ImmutableSet.builder().addAll(stopTokens).add(TokenKind.EOF).build(); Context context = new Context(); Options.instance(context).put("--enable-preview", "true"); - new JavacFileManager(context, true, UTF_8); + JavaFileManager fileManager = new JavacFileManager(context, false, UTF_8); + context.put(JavaFileManager.class, fileManager); DiagnosticCollector diagnosticCollector = new DiagnosticCollector<>(); context.put(DiagnosticListener.class, diagnosticCollector); Log log = Log.instance(context); From 1551cc251b0cb41ae5669a7fd4ad7068d7890f77 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sun, 8 May 2022 14:24:47 -0700 Subject: [PATCH 171/379] Update ci.yml Add 19-ea, use released 18 --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 016b8e776..9072785f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,19 +29,19 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest ] - java: [ 17, 11 ] + java: [ 18, 17, 11 ] experimental: [ false ] include: # Only test on macos and windows with a single recent JDK to avoid a # combinatorial explosion of test configurations. - os: macos-latest - java: 17 + java: 18 experimental: false - os: windows-latest - java: 17 + java: 18 experimental: false - os: ubuntu-latest - java: 18-ea + java: 19-ea experimental: true runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} From 04fbd4fe3e6bd40cd09eb8e504b2489ddd69063e Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 11 May 2022 18:43:34 -0700 Subject: [PATCH 172/379] Update tycho version to see if it helps w/ JDK 19-EA Startblock: unknown commit is submitted PiperOrigin-RevId: 448133464 --- eclipse_plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index 534e685f0..4f108340f 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -32,7 +32,7 @@ UTF-8 - 2.6.0 + 2.7.3 From e0132d0fb62624d6616426e8c9e450a814f2db02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jun 2022 10:34:23 -0700 Subject: [PATCH 173/379] Bump guava.version from 31.0.1-jre to 31.1-jre Bumps `guava.version` from 31.0.1-jre to 31.1-jre. Updates `guava` from 31.0.1-jre to 31.1-jre
Release notes

Sourced from guava's releases.

31.1

Maven

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>31.1-jre</version>
  <!-- or, for Android: -->
  <version>31.1-android</version>
</dependency>

Jar files

Guava requires one runtime dependency, which you can download here:

Javadoc

JDiff

Changelog

  • base: Deprecated the Throwables methods lazyStackTrace and lazyStackTraceIsLazy. They are no longer useful on any current platform. (6ebd7d8648)
  • collect: Added a new method ImmutableMap.Builder.buildKeepingLast(), which keeps the last value for any given key rather than throwing an exception when a key appears more than once. (68500b2c09)
  • collect: As a side-effect of the buildKeepingLast() change, the idiom ImmutableList.copyOf(Maps.transformValues(map, function)) may produce different results if function has side-effects. (This is not recommended.) (68500b2c09)
  • hash: Added Hashing.fingerprint2011(). (13f703c25f)
  • io: Changed ByteStreams.nullOutputStream() to follow the contract of OutputStream.write by throwing an exception if the range of bytes is out of bounds. (1cd85d01c9)
  • net: Added @CheckReturnValue to the package (with a few exceptions). (a0e2577de6)
  • net: Added HttpHeaders constant for Access-Control-Allow-Private-Network. (6dabbdf9c9)
  • util.concurrent: Added accumulate/update methods for AtomicDouble and AtomicDoubleArray. (2d875d327a)

APIs promoted from @Beta

  • base: Throwables methods getCausalChain and getCauseAs (dd462afa6b)
  • collect: Streams methods mapWithIndex and findLast (8079a29463)
  • collect: the remaining methods in Comparators: min, max, lexicographical, emptiesFirst, emptiesLast, isInOrder, isInStrictOrder (a3e411c3a4)
  • escape: various APIs (468c68a6ac)

... (truncated)

Commits

Updates `guava-testlib` from 31.0.1-jre to 31.1-jre
Release notes

Sourced from guava-testlib's releases.

31.1

Maven

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>31.1-jre</version>
  <!-- or, for Android: -->
  <version>31.1-android</version>
</dependency>

Jar files

Guava requires one runtime dependency, which you can download here:

Javadoc

JDiff

Changelog

  • base: Deprecated the Throwables methods lazyStackTrace and lazyStackTraceIsLazy. They are no longer useful on any current platform. (6ebd7d8648)
  • collect: Added a new method ImmutableMap.Builder.buildKeepingLast(), which keeps the last value for any given key rather than throwing an exception when a key appears more than once. (68500b2c09)
  • collect: As a side-effect of the buildKeepingLast() change, the idiom ImmutableList.copyOf(Maps.transformValues(map, function)) may produce different results if function has side-effects. (This is not recommended.) (68500b2c09)
  • hash: Added Hashing.fingerprint2011(). (13f703c25f)
  • io: Changed ByteStreams.nullOutputStream() to follow the contract of OutputStream.write by throwing an exception if the range of bytes is out of bounds. (1cd85d01c9)
  • net: Added @CheckReturnValue to the package (with a few exceptions). (a0e2577de6)
  • net: Added HttpHeaders constant for Access-Control-Allow-Private-Network. (6dabbdf9c9)
  • util.concurrent: Added accumulate/update methods for AtomicDouble and AtomicDoubleArray. (2d875d327a)

APIs promoted from @Beta

  • base: Throwables methods getCausalChain and getCauseAs (dd462afa6b)
  • collect: Streams methods mapWithIndex and findLast (8079a29463)
  • collect: the remaining methods in Comparators: min, max, lexicographical, emptiesFirst, emptiesLast, isInOrder, isInStrictOrder (a3e411c3a4)
  • escape: various APIs (468c68a6ac)

... (truncated)

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #754 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/754 from google:dependabot/maven/guava.version-31.1-jre 70a8d22d3181232e19775b25083779900e213972 PiperOrigin-RevId: 455648330 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f6c7b590d..3e3c865e9 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ UTF-8 1.8 - 31.0.1-jre + 31.1-jre 1.1.3 3.21.2 2.11.0 From 5c6f6bcc7a465b084d069ca014629330d587bc8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Aug 2022 08:39:08 -0700 Subject: [PATCH 174/379] Bump native-maven-plugin from 0.9.9 to 0.9.13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [native-maven-plugin](https://github.com/graalvm/native-build-tools) from 0.9.9 to 0.9.13.
Release notes

Sourced from native-maven-plugin's releases.

0.9.12

What's Changed

Read what's new in the documentation.

Full Changelog: https://github.com/graalvm/native-build-tools/compare/0.9.11...0.9.12

0.9.11

What's Changed

Read what's new in the documentation.

New Contributors

Full Changelog: https://github.com/graalvm/native-build-tools/compare/0.9.10...0.9.11

0.9.10

What's Changed

Read what's new in the documentation.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.graalvm.buildtools:native-maven-plugin&package-manager=maven&previous-version=0.9.9&new-version=0.9.13)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #799 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/799 from google:dependabot/maven/org.graalvm.buildtools-native-maven-plugin-0.9.13 dacb9ae64ffe78550813e9f1737b5e5fd6b735cf PiperOrigin-RevId: 466369202 --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 1d4715957..07716f615 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -256,7 +256,7 @@ org.graalvm.buildtools native-maven-plugin - 0.9.9 + 0.9.13 true From 858e6c6d6be56ed2b705b388c09c316ae09a1f02 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Aug 2022 08:39:21 -0700 Subject: [PATCH 175/379] Bump maven-javadoc-plugin from 3.3.1 to 3.4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) from 3.3.1 to 3.4.0.
Release notes

Sourced from maven-javadoc-plugin's releases.

3.3.2

What's Changed

... (truncated)

Commits
  • 40cc602 [maven-release-plugin] prepare release maven-javadoc-plugin-3.4.0
  • 0c6b32f [MJAVADOC-714] Upgrade to Maven 3.2.5
  • 506cb74 [MJAVADOC-696] Invalid anchors in Javadoc and plugin mojo
  • 47d03d3 [MJAVADOC-712] Remove remains of org.codehaus.doxia.sink.Sink
  • 5fae3b6 [MJAVADOC-711] Upgrade plugins in ITs
  • 03ca843 Bump maven-archiver from 3.5.1 to 3.5.2
  • 5dcfa6e Bump plexus-archiver from 4.2.6 to 4.2.7
  • ca00601 Bump junit in /src/it/projects/MJAVADOC-498_modulepath
  • 2583554 Bump commons-io from 2.2 to 2.7 in /src/it/projects/MJAVADOC-437/module2
  • 9dd7bdd use shared gh action/release-drafter (#128)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-javadoc-plugin&package-manager=maven&previous-version=3.3.1&new-version=3.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #776 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/776 from google:dependabot/maven/org.apache.maven.plugins-maven-javadoc-plugin-3.4.0 84e66973c58e17a4d0e336c5577ad73ca0ba060b PiperOrigin-RevId: 466369247 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 3e3c865e9..4cd7afeea 100644 --- a/pom.xml +++ b/pom.xml @@ -93,7 +93,7 @@ 2.11.0 1.9 1.0.1 - 3.3.1 + 3.4.0 3.2.1
@@ -173,7 +173,7 @@
maven-javadoc-plugin - 3.3.1 + 3.4.0 maven-gpg-plugin @@ -264,7 +264,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.3.1 + 3.4.0 none From f70db1b041492e4048f9c2c768667330098d0247 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Aug 2022 08:39:46 -0700 Subject: [PATCH 176/379] Bump maven-dependency-plugin from 3.2.0 to 3.3.0 Bumps [maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin) from 3.2.0 to 3.3.0.
Commits
  • e52bc02 [maven-release-plugin] prepare release maven-dependency-plugin-3.3.0
  • 0ec0a52 Fix Jenkins url
  • 77e42ca [MDEP-796] Upgrade Maven Parent to 35
  • 78976c0 [MDEP-795] Update Jetty to 9.4.45.v20220203 (#202)
  • a8d4690 [MDEP-788] Upgrade maven-reporting-impl to version 3.1.0
  • 25ca833 (doc) Update link to Github PR docs
  • 76d59f0 [MDEP-789] Improve documentation of analyze - Non-test scoped
  • b66d2b2 Bump mockito-core from 4.2.0 to 4.3.1
  • b057234 Bump slf4j-simple from 1.7.32 to 1.7.36
  • f64d4f7 [MDEP-787] allow ignoring non-test-scoped dependencies
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.apache.maven.plugins:maven-dependency-plugin&package-manager=maven&previous-version=3.2.0&new-version=3.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Fixes #794 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/794 from google:dependabot/maven/org.apache.maven.plugins-maven-dependency-plugin-3.3.0 1ca666e76b569ca5d01c404fd18d57138ec3d62b PiperOrigin-RevId: 466369343 --- eclipse_plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index 4f108340f..5bd3a829b 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -56,7 +56,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.2.0 + 3.3.0 copy-dependencies From 309d92ae66a37477f0d2a365475ab99ee85e73e0 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 30 Aug 2022 16:00:56 -0700 Subject: [PATCH 177/379] Adjust parameter comment style PiperOrigin-RevId: 471112648 --- .../java/com/google/googlejavaformat/java/Formatter.java | 6 +++--- .../google/googlejavaformat/java/RemoveUnusedImports.java | 5 ++++- .../com/google/googlejavaformat/java/StringWrapper.java | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index aac829dd0..9965a6ff8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -136,9 +136,9 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept JavacParser parser = parserFactory.newParser( javaInput.getText(), - /*keepDocComments=*/ true, - /*keepEndPos=*/ true, - /*keepLineMap=*/ true); + /* keepDocComments= */ true, + /* keepEndPos= */ true, + /* keepLineMap= */ true); unit = parser.parseCompilationUnit(); unit.sourcefile = source; diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index 20e55e945..ecb30eed6 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -252,7 +252,10 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept ParserFactory parserFactory = ParserFactory.instance(context); JavacParser parser = parserFactory.newParser( - javaInput, /*keepDocComments=*/ true, /*keepEndPos=*/ true, /*keepLineMap=*/ true); + javaInput, + /* keepDocComments= */ true, + /* keepEndPos= */ true, + /* keepLineMap= */ true); unit = parser.parseCompilationUnit(); unit.sourcefile = source; Iterable> errorDiagnostics = diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index c0f16e9b5..1d309308c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -396,7 +396,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) { ParserFactory parserFactory = ParserFactory.instance(context); JavacParser parser = parserFactory.newParser( - source, /*keepDocComments=*/ true, /*keepEndPos=*/ true, /*keepLineMap=*/ true); + source, /* keepDocComments= */ true, /* keepEndPos= */ true, /* keepLineMap= */ true); unit = parser.parseCompilationUnit(); unit.sourcefile = sjfo; Iterable> errorDiagnostics = From 3d03777aed468582c82d0fed4b7ada62a595ebe5 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 6 Sep 2022 14:54:00 -0700 Subject: [PATCH 178/379] Remove a link to an unmaintained project Fixes https://github.com/google/google-java-format/issues/822 PiperOrigin-RevId: 472563830 --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 02ef5c5fc..2d53f8ae5 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,6 @@ Implementation`. pre-commit git hook. * SBT plugins * [sbt/sbt-java-formatter](https://github.com/sbt/sbt-java-formatter) -* [maltzj/google-style-precommit-hook](https://github.com/maltzj/google-style-precommit-hook): - A pre-commit (pre-commit.com) hook that will automatically run GJF whenever - you commit code to your repository * [Github Actions](https://github.com/features/actions) * [googlejavaformat-action](https://github.com/axel-op/googlejavaformat-action): Automatically format your Java files when you push on github From 5496c3af114e74e0a385e044c09d10e96a9e4127 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 6 Oct 2022 10:11:48 -0700 Subject: [PATCH 179/379] Update ci.yml --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9072785f9..79a260eab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,19 +29,19 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest ] - java: [ 18, 17, 11 ] + java: [ 19, 17, 11 ] experimental: [ false ] include: # Only test on macos and windows with a single recent JDK to avoid a # combinatorial explosion of test configurations. - os: macos-latest - java: 18 + java: 19 experimental: false - os: windows-latest - java: 18 + java: 19 experimental: false - os: ubuntu-latest - java: 19-ea + java: 20-ea experimental: true runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} From 72248abd0092af2893bfb267832850ab7b3d47a4 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 6 Oct 2022 11:36:11 -0700 Subject: [PATCH 180/379] Update tycho version To include the fix for https://github.com/eclipse-tycho/tycho/issues/958 PiperOrigin-RevId: 479370465 --- eclipse_plugin/pom.xml | 2 +- pom.xml | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index 5bd3a829b..9e6acdac0 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -32,7 +32,7 @@ UTF-8 - 2.7.3 + 3.0.0 diff --git a/pom.xml b/pom.xml index 4cd7afeea..7066ecb6d 100644 --- a/pom.xml +++ b/pom.xml @@ -27,7 +27,6 @@ core - eclipse_plugin Google Java Format Parent @@ -362,5 +361,14 @@ + + eclipse + + [17,) + + + eclipse_plugin + + From 41d6e373ca84f1980f5ef52f683ae00cf6ec87b9 Mon Sep 17 00:00:00 2001 From: Alan Malloy Date: Fri, 7 Oct 2022 12:09:41 -0700 Subject: [PATCH 181/379] Improve error message for malformed edits PiperOrigin-RevId: 479639885 --- .../java/com/google/googlejavaformat/java/StringWrapper.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 1d309308c..d801c9b86 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -96,7 +96,9 @@ static String wrap(final int columnLimit, String input, Formatter formatter) if (!expected.equals(actual)) { throw new FormatterException( String.format( - "Something has gone terribly wrong. Please file a bug: " + "Something has gone terribly wrong. We planned to make the below formatting change," + + " but have aborted because it would unexpectedly change the AST.\n" + + "Please file a bug: " + "https://github.com/google/google-java-format/issues/new" + "\n\n=== Actual: ===\n%s\n=== Expected: ===\n%s\n", actual, expected)); From 198cc39e650fb2c744aeac80b6b834691a6b4695 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 25 Oct 2022 09:28:51 -0700 Subject: [PATCH 182/379] Update Error Prone version PiperOrigin-RevId: 483696374 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7066ecb6d..150173ee6 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 31.1-jre 1.1.3 3.21.2 - 2.11.0 + 2.16 1.9 1.0.1 3.4.0 From c1ea933ba37f27810d3ae01b5958514c02425009 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 27 Oct 2022 16:17:26 -0700 Subject: [PATCH 183/379] Stop supporting JDK 14 in google-java-format, and update to remove uses of reflection for APIs that can be accessed directly in JDK 17 PiperOrigin-RevId: 484376678 --- core/pom.xml | 6 +- .../googlejavaformat/java/Formatter.java | 4 +- .../Java17InputAstVisitor.java} | 82 ++++--------------- 3 files changed, 19 insertions(+), 73 deletions(-) rename core/src/main/java/com/google/googlejavaformat/java/{java14/Java14InputAstVisitor.java => java17/Java17InputAstVisitor.java} (72%) diff --git a/core/pom.xml b/core/pom.xml index 07716f615..10565c66a 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -227,7 +227,7 @@ jdk11 - (,14) + (,17) @@ -236,14 +236,14 @@ maven-compiler-plugin - **/Java14InputAstVisitor.java + **/Java17InputAstVisitor.java maven-javadoc-plugin - com.google.googlejavaformat.java.java14 + com.google.googlejavaformat.java.java17 diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index 9965a6ff8..841e88a8a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -151,10 +151,10 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept OpsBuilder builder = new OpsBuilder(javaInput, javaOutput); // Output the compilation unit. JavaInputAstVisitor visitor; - if (Runtime.version().feature() >= 14) { + if (Runtime.version().feature() >= 17) { try { visitor = - Class.forName("com.google.googlejavaformat.java.java14.Java14InputAstVisitor") + Class.forName("com.google.googlejavaformat.java.java17.Java17InputAstVisitor") .asSubclass(JavaInputAstVisitor.class) .getConstructor(OpsBuilder.class, int.class) .newInstance(builder, options.indentationMultiplier()); diff --git a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java similarity index 72% rename from core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java rename to core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java index 890687fe2..a0561e2fe 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java @@ -12,7 +12,7 @@ * the License. */ -package com.google.googlejavaformat.java.java14; +package com.google.googlejavaformat.java.java17; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.Iterables.getOnlyElement; @@ -25,6 +25,7 @@ import com.sun.source.tree.AnnotationTree; import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.BlockTree; +import com.sun.source.tree.CaseLabelTree; import com.sun.source.tree.CaseTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; @@ -39,39 +40,23 @@ import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.TreeInfo; -import java.lang.reflect.Method; import java.util.List; import java.util.Optional; import javax.lang.model.element.Name; /** - * Extends {@link JavaInputAstVisitor} with support for AST nodes that were added or modified for - * Java 14. + * Extends {@link JavaInputAstVisitor} with support for AST nodes that were added or modified in + * Java 17. */ -public class Java14InputAstVisitor extends JavaInputAstVisitor { - private static final Method COMPILATION_UNIT_TREE_GET_MODULE = - maybeGetMethod(CompilationUnitTree.class, "getModule"); - private static final Method CLASS_TREE_GET_PERMITS_CLAUSE = - maybeGetMethod(ClassTree.class, "getPermitsClause"); - private static final Method BINDING_PATTERN_TREE_GET_VARIABLE = - maybeGetMethod(BindingPatternTree.class, "getVariable"); - private static final Method BINDING_PATTERN_TREE_GET_TYPE = - maybeGetMethod(BindingPatternTree.class, "getType"); - private static final Method BINDING_PATTERN_TREE_GET_BINDING = - maybeGetMethod(BindingPatternTree.class, "getBinding"); - private static final Method CASE_TREE_GET_LABELS = maybeGetMethod(CaseTree.class, "getLabels"); +public class Java17InputAstVisitor extends JavaInputAstVisitor { - public Java14InputAstVisitor(OpsBuilder builder, int indentMultiplier) { + public Java17InputAstVisitor(OpsBuilder builder, int indentMultiplier) { super(builder, indentMultiplier); } @Override protected void handleModule(boolean first, CompilationUnitTree node) { - if (COMPILATION_UNIT_TREE_GET_MODULE == null) { - // Java < 17, see https://bugs.openjdk.java.net/browse/JDK-8255464 - return; - } - ModuleTree module = (ModuleTree) invoke(COMPILATION_UNIT_TREE_GET_MODULE, node); + ModuleTree module = node.getModule(); if (module != null) { if (!first) { builder.blankLineWanted(BlankLineWanted.YES); @@ -84,30 +69,15 @@ protected void handleModule(boolean first, CompilationUnitTree node) { @Override protected List getPermitsClause(ClassTree node) { - if (CLASS_TREE_GET_PERMITS_CLAUSE != null) { - return (List) invoke(CLASS_TREE_GET_PERMITS_CLAUSE, node); - } else { - // Java < 15 - return super.getPermitsClause(node); - } + return node.getPermitsClause(); } @Override public Void visitBindingPattern(BindingPatternTree node, Void unused) { sync(node); - if (BINDING_PATTERN_TREE_GET_VARIABLE != null) { - VariableTree variableTree = (VariableTree) invoke(BINDING_PATTERN_TREE_GET_VARIABLE, node); - visitBindingPattern( - variableTree.getModifiers(), variableTree.getType(), variableTree.getName()); - } else if (BINDING_PATTERN_TREE_GET_TYPE != null && BINDING_PATTERN_TREE_GET_BINDING != null) { - Tree type = (Tree) invoke(BINDING_PATTERN_TREE_GET_TYPE, node); - Name name = (Name) invoke(BINDING_PATTERN_TREE_GET_BINDING, node); - visitBindingPattern(/* modifiers= */ null, type, name); - } else { - throw new LinkageError( - "BindingPatternTree must have either getVariable() or both getType() and getBinding()," - + " but does not"); - } + VariableTree variableTree = node.getVariable(); + visitBindingPattern( + variableTree.getModifiers(), variableTree.getType(), variableTree.getName()); return null; } @@ -248,17 +218,9 @@ public Void visitCase(CaseTree node, Void unused) { sync(node); markForPartialFormat(); builder.forcedBreak(); - List labels; - boolean isDefault; - if (CASE_TREE_GET_LABELS != null) { - labels = (List) invoke(CASE_TREE_GET_LABELS, node); - isDefault = - labels.size() == 1 - && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL"); - } else { - labels = node.getExpressions(); - isDefault = labels.isEmpty(); - } + List labels = node.getLabels(); + boolean isDefault = + labels.size() == 1 && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL"); if (isDefault) { token("default", plusTwo); } else { @@ -305,20 +267,4 @@ public Void visitCase(CaseTree node, Void unused) { } return null; } - - private static Method maybeGetMethod(Class c, String name) { - try { - return c.getMethod(name); - } catch (ReflectiveOperationException e) { - return null; - } - } - - private static Object invoke(Method m, Object target) { - try { - return m.invoke(target); - } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); - } - } } From dda43216576c4cb84e2497424b9ca9246f2687e5 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Mon, 7 Nov 2022 05:11:20 -0800 Subject: [PATCH 184/379] Reformat parameter comments in the canonical Java format (`/* foo= */`). This only formats comments that would already trigger the `ParameterComment` check; it shouldn't make things parameter comments which could then cause compilation errors. PiperOrigin-RevId: 486631656 --- .../googlejavaformat/CommentsHelper.java | 19 +++++++ .../java/com/google/googlejavaformat/Doc.java | 5 +- .../java/JavaCommentsHelper.java | 10 ++-- .../java/testdata/B21283374.output | 56 +++++++++---------- .../java/testdata/B26694550.output | 6 +- .../java/testdata/ParameterComment.input | 26 +++++++++ .../java/testdata/ParameterComment.output | 34 +++++++++++ 7 files changed, 119 insertions(+), 37 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.output diff --git a/core/src/main/java/com/google/googlejavaformat/CommentsHelper.java b/core/src/main/java/com/google/googlejavaformat/CommentsHelper.java index 45e507bbd..2b789612c 100644 --- a/core/src/main/java/com/google/googlejavaformat/CommentsHelper.java +++ b/core/src/main/java/com/google/googlejavaformat/CommentsHelper.java @@ -14,6 +14,10 @@ package com.google.googlejavaformat; +import com.google.googlejavaformat.Input.Tok; +import java.util.Optional; +import java.util.regex.Pattern; + /** * Rewrite comments. This interface is implemented by {@link * com.google.googlejavaformat.java.JavaCommentsHelper JavaCommentsHelper}. @@ -28,4 +32,19 @@ public interface CommentsHelper { * @return the rewritten comment */ String rewrite(Input.Tok tok, int maxWidth, int column0); + + static Optional reformatParameterComment(Tok tok) { + if (!tok.isSlashStarComment()) { + return Optional.empty(); + } + var match = PARAMETER_COMMENT.matcher(tok.getOriginalText()); + if (!match.matches()) { + return Optional.empty(); + } + return Optional.of(String.format("/* %s= */", match.group(1))); + } + + Pattern PARAMETER_COMMENT = + Pattern.compile( + "/\\*\\s*(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)(\\Q...\\E)?\\s*=\\s*\\*/"); } diff --git a/core/src/main/java/com/google/googlejavaformat/Doc.java b/core/src/main/java/com/google/googlejavaformat/Doc.java index 35acca367..d638ddb40 100644 --- a/core/src/main/java/com/google/googlejavaformat/Doc.java +++ b/core/src/main/java/com/google/googlejavaformat/Doc.java @@ -15,6 +15,7 @@ package com.google.googlejavaformat; import static com.google.common.collect.Iterables.getLast; +import static com.google.googlejavaformat.CommentsHelper.reformatParameterComment; import static java.lang.Math.max; import com.google.common.base.MoreObjects; @@ -727,7 +728,7 @@ float computeWidth() { // Account for line comments with missing spaces, see computeFlat. return tok.length() + 1; } else { - return tok.length(); + return reformatParameterComment(tok).map(String::length).orElse(tok.length()); } } return idx != -1 ? Float.POSITIVE_INFINITY : (float) tok.length(); @@ -741,7 +742,7 @@ String computeFlat() { if (tok.isSlashSlashComment() && !tok.getOriginalText().startsWith("// ")) { return "// " + tok.getOriginalText().substring("//".length()); } - return tok.getOriginalText(); + return reformatParameterComment(tok).orElse(tok.getOriginalText()); } @Override diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java b/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java index 346324a45..d34ecc43f 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java @@ -53,11 +53,13 @@ public String rewrite(Tok tok, int maxWidth, int column0) { } if (tok.isSlashSlashComment()) { return indentLineComments(lines, column0); - } else if (javadocShaped(lines)) { - return indentJavadoc(lines, column0); - } else { - return preserveIndentation(lines, column0); } + return CommentsHelper.reformatParameterComment(tok) + .orElseGet( + () -> + javadocShaped(lines) + ? indentJavadoc(lines, column0) + : preserveIndentation(lines, column0)); } // For non-javadoc-shaped block comments, shift the entire block to the correct diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B21283374.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B21283374.output index f98a37b2f..777303e61 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B21283374.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B21283374.output @@ -14,41 +14,41 @@ class B21283374 { { f( - /*flagA=*/ Boolean.TRUE, - /*flagB=*/ Boolean.FALSE, - /*flagC=*/ Boolean.FALSE, - /*flagD=*/ Boolean.FALSE, - /*flagE=*/ Boolean.FALSE, - /*flagF=*/ Boolean.FALSE, - /*flagG=*/ Boolean.FALSE, - /*flagH=*/ Boolean.FALSE, - /*flagI=*/ Boolean.FALSE, - /*flagJ=*/ Boolean.FALSE, - /*flagK=*/ Boolean.FALSE); + /* flagA= */ Boolean.TRUE, + /* flagB= */ Boolean.FALSE, + /* flagC= */ Boolean.FALSE, + /* flagD= */ Boolean.FALSE, + /* flagE= */ Boolean.FALSE, + /* flagF= */ Boolean.FALSE, + /* flagG= */ Boolean.FALSE, + /* flagH= */ Boolean.FALSE, + /* flagI= */ Boolean.FALSE, + /* flagJ= */ Boolean.FALSE, + /* flagK= */ Boolean.FALSE); f( - /*flagA=*/ Boolean.TRUE, - /*flagB=*/ Boolean.FALSE, - /*flagC=*/ Boolean.FALSE, - /*flagD=*/ Boolean.FALSE, - /*flagE=*/ Boolean.FALSE, - /*flagF=*/ Boolean.FALSE, - /*flagG=*/ Boolean.FALSE, - /*flagH=*/ Boolean.FALSE, - /*flagI=*/ Boolean.FALSE, - /*flagJ=*/ Boolean.FALSE, - /*flagK=*/ Boolean.FALSE); + /* flagA= */ Boolean.TRUE, + /* flagB= */ Boolean.FALSE, + /* flagC= */ Boolean.FALSE, + /* flagD= */ Boolean.FALSE, + /* flagE= */ Boolean.FALSE, + /* flagF= */ Boolean.FALSE, + /* flagG= */ Boolean.FALSE, + /* flagH= */ Boolean.FALSE, + /* flagI= */ Boolean.FALSE, + /* flagJ= */ Boolean.FALSE, + /* flagK= */ Boolean.FALSE); - assertThat(foo.barAndBaz(/*paramName=*/ false, thingy)).isEqualTo(new Something("")); - assertThat(foo.barAndBaz(/*paramName=*/ false, thingy)).isEqualTo(new Something("")); - assertThat(foo.barAndBaz(/*paramName=*/ false, thingy)).isEqualTo(new Something("")); + assertThat(foo.barAndBaz(/* paramName= */ false, thingy)).isEqualTo(new Something("")); + assertThat(foo.barAndBaz(/* paramName= */ false, thingy)).isEqualTo(new Something("")); + assertThat(foo.barAndBaz(/* paramName= */ false, thingy)).isEqualTo(new Something("")); - f(/*paramName=*/ false); + f(/* paramName= */ false); assertThat__________________________________________________________( - /*paramName=*/ false, thingy); + /* paramName= */ false, thingy); assertThat__________________________________________________________( - /*paramName=*/ false, thingy); + /* paramName= */ false, thingy); f( arg1, /* which arg is this attached to? */ diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B26694550.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B26694550.output index 945a40fce..aedafb779 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B26694550.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B26694550.output @@ -3,15 +3,15 @@ class B26694550 { /* === not a param comment */ fffffffffffffffffffffffffffffff( ImmutableList.copyOf(keys), /*&=*/ - /*keepGoing=*/ false, + /* keepGoing= */ false, ggggggggggggggggggggggggggggggggggggggggggg); fffffffffffffffffffffffffffffff( ImmutableList.copyOf(keys), - /*keepGoing=*/ false, + /* keepGoing= */ false, ggggggggggggggggggggggggggggggggggggggggggg); fffffffffffffffffffffffffffffff( ImmutableList.copyOf(keys), - /*foo_bar=*/ false, + /* foo_bar= */ false, /*foo-bar=*/ false, ggggggggggggggggggggggggggggggggggggggggggg); } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.input new file mode 100644 index 000000000..58590ac4e --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.input @@ -0,0 +1,26 @@ +package com.google.googlejavaformat.java.test; + +/** Tests for formatting of ParameterComments. */ +class Q { + static void f(int a) { + f(/*a=*/ 1); + f( + /* a= */ 1 + ); + } + static void g(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k) { + g( + /*a=*/ 1, + /*b=*/ 1, + /*c=*/ 1, + /*d=*/ 1, + /*e=*/ 1, + /*f=*/ 1, + /*g=*/ 1, + /*h=*/ 1, + /*i=*/ 1, + /*j=*/ 1, + /*k=*/ 1); + g(/*a=*/ 1, /*b=*/ 1, /*c=*/ 1, /*d=*/ 1, /*e=*/ 1, /*f=*/ 1, /*g=*/ 1, /*h=*/ 1, /*i=*/ 1); + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.output new file mode 100644 index 000000000..5616ec0da --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.output @@ -0,0 +1,34 @@ +package com.google.googlejavaformat.java.test; + +/** Tests for formatting of ParameterComments. */ +class Q { + static void f(int a) { + f(/* a= */ 1); + f(/* a= */ 1); + } + + static void g(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k) { + g( + /* a= */ 1, + /* b= */ 1, + /* c= */ 1, + /* d= */ 1, + /* e= */ 1, + /* f= */ 1, + /* g= */ 1, + /* h= */ 1, + /* i= */ 1, + /* j= */ 1, + /* k= */ 1); + g( + /* a= */ 1, + /* b= */ 1, + /* c= */ 1, + /* d= */ 1, + /* e= */ 1, + /* f= */ 1, + /* g= */ 1, + /* h= */ 1, + /* i= */ 1); + } +} From 198fa4236724f0305f1d4fb9447ce0b48984746f Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 8 Nov 2022 08:16:05 -0800 Subject: [PATCH 185/379] Format long exception lists one-per-line PiperOrigin-RevId: 486955708 --- .../java/JavaInputAstVisitor.java | 2 +- .../googlejavaformat/java/testdata/M.output | 108 +++++++++++++++--- 2 files changed, 91 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index daed2502e..75f36873b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -2639,7 +2639,7 @@ private void visitThrowsClause(List thrownExceptionTyp for (ExpressionTree thrownExceptionType : thrownExceptionTypes) { if (!first) { token(","); - builder.breakToFill(" "); + builder.breakOp(" "); } scan(thrownExceptionType, null); first = false; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/M.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/M.output index dbad1bb67..d28d5dd7c 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/M.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/M.output @@ -36,8 +36,16 @@ class M { /** JavaDoc. */ void methodName3(int x) - throws Exception0, Exception1, Exception2, Exception3, Exception4, Exception5, Exception6, - Exception7, Exception8, Exception9 {} + throws Exception0, + Exception1, + Exception2, + Exception3, + Exception4, + Exception5, + Exception6, + Exception7, + Exception8, + Exception9 {} /** JavaDoc. */ void methodName4( @@ -114,8 +122,16 @@ class M { int t, int u, int v) - throws Exception0, Exception1, Exception2, Exception3, Exception4, Exception5, Exception6, - Exception7, Exception8, Exception9 {} + throws Exception0, + Exception1, + Exception2, + Exception3, + Exception4, + Exception5, + Exception6, + Exception7, + Exception8, + Exception9 {} Pair< Pair, Pair>, Pair, Pair>>, @@ -135,8 +151,16 @@ class M { Pair, Pair>, Pair, Pair>>, Pair, Pair>, Pair, Pair>>> methodName11(int x) - throws Exception0, Exception1, Exception2, Exception3, Exception4, Exception5, Exception6, - Exception7, Exception8, Exception9 { + throws Exception0, + Exception1, + Exception2, + Exception3, + Exception4, + Exception5, + Exception6, + Exception7, + Exception8, + Exception9 { return null; } @@ -225,8 +249,16 @@ class M { int t, int u, int v) - throws Exception0, Exception1, Exception2, Exception3, Exception4, Exception5, Exception6, - Exception7, Exception8, Exception9 { + throws Exception0, + Exception1, + Exception2, + Exception3, + Exception4, + Exception5, + Exception6, + Exception7, + Exception8, + Exception9 { return null; } @@ -338,8 +370,16 @@ class M { T30, T31> T methodName22(int x) - throws Exception0, Exception1, Exception2, Exception3, Exception4, Exception5, Exception6, - Exception7, Exception8, Exception9 { + throws Exception0, + Exception1, + Exception2, + Exception3, + Exception4, + Exception5, + Exception6, + Exception7, + Exception8, + Exception9 { return null; } @@ -518,8 +558,16 @@ class M { int t, int u, int v) - throws Exception0, Exception1, Exception2, Exception3, Exception4, Exception5, Exception6, - Exception7, Exception8, Exception9 { + throws Exception0, + Exception1, + Exception2, + Exception3, + Exception4, + Exception5, + Exception6, + Exception7, + Exception8, + Exception9 { return null; } @@ -640,8 +688,16 @@ class M { Pair, Pair>, Pair, Pair>>, Pair, Pair>, Pair, Pair>>> methodName(int x) - throws Exception0, Exception1, Exception2, Exception3, Exception4, Exception5, - Exception6, Exception7, Exception8, Exception9 { + throws Exception0, + Exception1, + Exception2, + Exception3, + Exception4, + Exception5, + Exception6, + Exception7, + Exception8, + Exception9 { return null; } @@ -829,8 +885,16 @@ class M { int t, int u, int v) - throws Exception0, Exception1, Exception2, Exception3, Exception4, Exception5, - Exception6, Exception7, Exception8, Exception9 { + throws Exception0, + Exception1, + Exception2, + Exception3, + Exception4, + Exception5, + Exception6, + Exception7, + Exception8, + Exception9 { return null; } @@ -1011,6 +1075,14 @@ class M { ZZZZZZZZZZ z, ZZZZZZZZZZ z, ZZZZZZZZZZ z) - throws EEEEEEEEEE, EEEEEEEEEE, EEEEEEEEEE, EEEEEEEEEE, EEEEEEEEEE, EEEEEEEEEE, EEEEEEEEEE, - EEEEEEEEEE, EEEEEEEEEE, EEEEEEEEEE {} + throws EEEEEEEEEE, + EEEEEEEEEE, + EEEEEEEEEE, + EEEEEEEEEE, + EEEEEEEEEE, + EEEEEEEEEE, + EEEEEEEEEE, + EEEEEEEEEE, + EEEEEEEEEE, + EEEEEEEEEE {} } From e3227913ca7ca9f53c3e5098c5d702a50df0304c Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Wed, 16 Nov 2022 09:09:26 -0800 Subject: [PATCH 186/379] Preserve ellipses when formatting parameter comments. PiperOrigin-RevId: 488956140 --- .../main/java/com/google/googlejavaformat/CommentsHelper.java | 2 +- .../googlejavaformat/java/testdata/ParameterComment.input | 3 +++ .../googlejavaformat/java/testdata/ParameterComment.output | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/CommentsHelper.java b/core/src/main/java/com/google/googlejavaformat/CommentsHelper.java index 2b789612c..1e33003b0 100644 --- a/core/src/main/java/com/google/googlejavaformat/CommentsHelper.java +++ b/core/src/main/java/com/google/googlejavaformat/CommentsHelper.java @@ -46,5 +46,5 @@ static Optional reformatParameterComment(Tok tok) { Pattern PARAMETER_COMMENT = Pattern.compile( - "/\\*\\s*(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)(\\Q...\\E)?\\s*=\\s*\\*/"); + "/\\*\\s*(\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(\\Q...\\E)?)\\s*=\\s*\\*/"); } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.input index 58590ac4e..decebe92a 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.input @@ -23,4 +23,7 @@ class Q { /*k=*/ 1); g(/*a=*/ 1, /*b=*/ 1, /*c=*/ 1, /*d=*/ 1, /*e=*/ 1, /*f=*/ 1, /*g=*/ 1, /*h=*/ 1, /*i=*/ 1); } + static void h(Object... xs) { + h(/*xs...=*/ null); + } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.output index 5616ec0da..d26ca1135 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/ParameterComment.output @@ -31,4 +31,8 @@ class Q { /* h= */ 1, /* i= */ 1); } + + static void h(Object... xs) { + h(/* xs...= */ null); + } } From 8afb866e7c5f26846c475c0cf6d7e314861b072c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 21 Nov 2022 14:38:29 -0800 Subject: [PATCH 187/379] Create a build rule for compiling deps at the Java STS language level This allows building the Java > 11 logic in google-java-format into the jar regardless of what language level is configured for the entire build, and then dynamically enabling it when running on a new enough JDK, while remaining compatible with earlier JDK versions. PiperOrigin-RevId: 490074589 --- .../com/google/googlejavaformat/java/testdata/B20844369.input | 2 +- .../com/google/googlejavaformat/java/testdata/B20844369.output | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.input index 7317f17b9..86e46d50e 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.input @@ -1,6 +1,6 @@ public class B20844369 { private static final String ID_PATTERN = - // TODO(user): add min/max lengths for the numbers here, e.g. android ID + // TODO(daw): add min/max lengths for the numbers here, e.g. android ID "(?:(?\\d+)\\+)?" // optional Android ID + "(?\\d+)" // type + ":" diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.output index 62f9721b6..982dc2b5d 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B20844369.output @@ -1,6 +1,6 @@ public class B20844369 { private static final String ID_PATTERN = - // TODO(user): add min/max lengths for the numbers here, e.g. android ID + // TODO(daw): add min/max lengths for the numbers here, e.g. android ID "(?:(?\\d+)\\+)?" // optional Android ID + "(?\\d+)" // type + ":" From d9ddb94db1d90a240f901949514f35df4e4c3fc4 Mon Sep 17 00:00:00 2001 From: Stephan Schroevers Date: Thu, 15 Dec 2022 14:44:45 -0800 Subject: [PATCH 188/379] Recognize new JSpecify package name So that its `@Nullable` annotation is treated as a type-use annotation and formatted accordingly. See jspecify/jspecify#260. Fixes #869 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/869 from PicnicSupermarket:improvement/support-new-jpecify-package-name 7a0dc20b5cddc4d560b2be25441b1ab26c3229c2 PiperOrigin-RevId: 495701635 --- .../com/google/googlejavaformat/java/JavaInputAstVisitor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 75f36873b..9b6283ece 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -285,6 +285,7 @@ private static ImmutableSetMultimap typeAnnotations() { ImmutableSetMultimap.Builder result = ImmutableSetMultimap.builder(); for (String annotation : ImmutableList.of( + "org.jspecify.annotations.Nullable", "org.jspecify.nullness.Nullable", "org.checkerframework.checker.nullness.qual.Nullable")) { String simpleName = annotation.substring(annotation.lastIndexOf('.') + 1); From d24deb9d982eaae896a57313f7486aaf130bf5aa Mon Sep 17 00:00:00 2001 From: cpovirk Date: Fri, 6 Jan 2023 08:20:43 -0800 Subject: [PATCH 189/379] Recognize a couple `@NonNull` annotations as type-use annotations. PiperOrigin-RevId: 500180559 --- .../com/google/googlejavaformat/java/JavaInputAstVisitor.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 9b6283ece..394d396d9 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -285,8 +285,10 @@ private static ImmutableSetMultimap typeAnnotations() { ImmutableSetMultimap.Builder result = ImmutableSetMultimap.builder(); for (String annotation : ImmutableList.of( + "org.jspecify.annotations.NonNull", "org.jspecify.annotations.Nullable", "org.jspecify.nullness.Nullable", + "org.checkerframework.checker.nullness.qual.NonNull", "org.checkerframework.checker.nullness.qual.Nullable")) { String simpleName = annotation.substring(annotation.lastIndexOf('.') + 1); result.put(simpleName, annotation); From 90f9e5aeff9dde129cd79db386470b54bdec99e3 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 13 Jan 2023 21:53:10 -0500 Subject: [PATCH 190/379] Delete dependabot.yml --- .github/dependabot.yml | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index daec31893..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "maven" - directory: "/" - schedule: - interval: "daily" From 4a22aab7b19a41d6267ea70c76f137a6fd49bc76 Mon Sep 17 00:00:00 2001 From: Zach Date: Mon, 16 Jan 2023 09:48:24 -0800 Subject: [PATCH 191/379] Return a non-zero exit code upon error This brings us in line with the Unix standard of returning non-zero for a failed command: https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html Also, this will allow any callers (like google-java-format-diff.py) to respond appropriately. [A change](http://r.android.com/2257232) needed to be reverted because `google-java-format-diff.py` was failing silently, so the author wasn't aware that their change caused a pre-upload hook to stop working. Fixes #848 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/848 from abstractlyZach:return_nonzero 06b2d3671d77c406be9b6d982321b17b920826df PiperOrigin-RevId: 502399096 --- core/src/main/java/com/google/googlejavaformat/java/Main.java | 3 ++- .../java/GoogleJavaFormatToolProviderTest.java | 2 +- .../test/java/com/google/googlejavaformat/java/MainTest.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 953ca5860..11c019234 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -79,7 +79,8 @@ static int main(PrintWriter out, PrintWriter err, String... args) { return formatter.format(args); } catch (UsageException e) { err.print(e.getMessage()); - return 0; + // We return exit code 2 to differentiate usage issues from code formatting issues. + return 2; } finally { err.flush(); out.flush(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java index 15e452297..d060fef1f 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java @@ -46,7 +46,7 @@ public void testUsageOutputAfterLoadingViaToolName() { int result = format.run(new PrintWriter(out, true), new PrintWriter(err, true), "--help"); - assertThat(result).isEqualTo(0); + assertThat(result).isEqualTo(2); String usage = err.toString(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index ac3eb3966..d4a410904 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -132,7 +132,7 @@ public void testMain() throws Exception { process.waitFor(); String err = new String(ByteStreams.toByteArray(process.getErrorStream()), UTF_8); assertThat(err).contains("Usage: google-java-format"); - assertThat(process.exitValue()).isEqualTo(0); + assertThat(process.exitValue()).isEqualTo(2); } // end to end javadoc formatting test From 91223aa642bd64f973e5b147a7e7d93a2b454fe5 Mon Sep 17 00:00:00 2001 From: Kyle J Stiemann Date: Fri, 3 Feb 2023 16:58:42 -0800 Subject: [PATCH 192/379] Fix #846 Formatter leaks threads and memory I've signed the CLA. Fixes #847 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/847 from stiemannkj1:fix-846-mem-thread-leak 0ca1e9bf9c8cf877509ac39cc50707d0ade7d71c PiperOrigin-RevId: 507026969 --- .../main/java/com/google/googlejavaformat/java/Main.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 11c019234..628c8bb24 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -18,6 +18,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.io.ByteStreams; +import com.google.common.util.concurrent.MoreExecutors; import com.google.googlejavaformat.FormatterDiagnostic; import com.google.googlejavaformat.java.JavaFormatterOptions.Style; import java.io.IOError; @@ -28,6 +29,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.Duration; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; @@ -187,6 +189,10 @@ private int formatFiles(CommandLineOptions parameters, JavaFormatterOptions opti outWriter.write(formatted); } } + if (!MoreExecutors.shutdownAndAwaitTermination(executorService, Duration.ofSeconds(5))) { + errWriter.println("Failed to shut down ExecutorService"); + allOk = false; + } return allOk ? 0 : 1; } From 0a6a85e37f634fa870c920997d9270dca319cc03 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 14 Feb 2023 12:33:08 -0800 Subject: [PATCH 193/379] Refactor formatter's main to use `ExecutorCompletionService` PiperOrigin-RevId: 509606924 --- .../java/FormatFileCallable.java | 57 +++++++++++---- .../google/googlejavaformat/java/Main.java | 69 ++++++++++--------- 2 files changed, 83 insertions(+), 43 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java b/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java index 9d8ae41ca..3d68a23f3 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java +++ b/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java @@ -14,40 +14,73 @@ package com.google.googlejavaformat.java; +import com.google.auto.value.AutoValue; import com.google.common.collect.Range; import com.google.common.collect.RangeSet; import com.google.common.collect.TreeRangeSet; +import java.nio.file.Path; import java.util.concurrent.Callable; +import org.checkerframework.checker.nullness.qual.Nullable; /** * Encapsulates information about a file to be formatted, including which parts of the file to * format. */ -class FormatFileCallable implements Callable { +class FormatFileCallable implements Callable { + + @AutoValue + abstract static class Result { + abstract @Nullable Path path(); + + abstract String input(); + + abstract @Nullable String output(); + + boolean changed() { + return !input().equals(output()); + } + + abstract @Nullable FormatterException exception(); + + static Result create( + @Nullable Path path, + String input, + @Nullable String output, + @Nullable FormatterException exception) { + return new AutoValue_FormatFileCallable_Result(path, input, output, exception); + } + } + + private final Path path; private final String input; private final CommandLineOptions parameters; private final JavaFormatterOptions options; public FormatFileCallable( - CommandLineOptions parameters, String input, JavaFormatterOptions options) { + CommandLineOptions parameters, Path path, String input, JavaFormatterOptions options) { + this.path = path; this.input = input; this.parameters = parameters; this.options = options; } @Override - public String call() throws FormatterException { - if (parameters.fixImportsOnly()) { - return fixImports(input); - } + public Result call() { + try { + if (parameters.fixImportsOnly()) { + return Result.create(path, input, fixImports(input), /* exception= */ null); + } - Formatter formatter = new Formatter(options); - String formatted = formatter.formatSource(input, characterRanges(input).asRanges()); - formatted = fixImports(formatted); - if (parameters.reflowLongStrings()) { - formatted = StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, formatted, formatter); + Formatter formatter = new Formatter(options); + String formatted = formatter.formatSource(input, characterRanges(input).asRanges()); + formatted = fixImports(formatted); + if (parameters.reflowLongStrings()) { + formatted = StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, formatted, formatter); + } + return Result.create(path, input, formatted, /* exception= */ null); + } catch (FormatterException e) { + return Result.create(path, input, /* output= */ null, e); } - return formatted; } private String fixImports(String input) throws FormatterException { diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 628c8bb24..9c60fcb12 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -16,6 +16,7 @@ import static java.lang.Math.min; import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Comparator.comparing; import com.google.common.io.ByteStreams; import com.google.common.util.concurrent.MoreExecutors; @@ -30,13 +31,14 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.time.Duration; +import java.util.ArrayList; import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.Collections; +import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.Future; /** The main class for the Java formatter CLI. */ public final class Main { @@ -123,50 +125,54 @@ private int formatFiles(CommandLineOptions parameters, JavaFormatterOptions opti int numThreads = min(MAX_THREADS, parameters.files().size()); ExecutorService executorService = Executors.newFixedThreadPool(numThreads); - Map inputs = new LinkedHashMap<>(); - Map> results = new LinkedHashMap<>(); + ExecutorCompletionService cs = + new ExecutorCompletionService<>(executorService); boolean allOk = true; + int files = 0; for (String fileName : parameters.files()) { if (!fileName.endsWith(".java")) { errWriter.println("Skipping non-Java file: " + fileName); continue; } Path path = Paths.get(fileName); - String input; try { - input = new String(Files.readAllBytes(path), UTF_8); - inputs.put(path, input); - results.put( - path, executorService.submit(new FormatFileCallable(parameters, input, options))); + cs.submit(new FormatFileCallable(parameters, path, Files.readString(path), options)); + files++; } catch (IOException e) { errWriter.println(fileName + ": could not read file: " + e.getMessage()); allOk = false; } } - for (Map.Entry> result : results.entrySet()) { - Path path = result.getKey(); - String formatted; + List results = new ArrayList<>(); + while (files > 0) { try { - formatted = result.getValue().get(); + files--; + results.add(cs.take().get()); } catch (InterruptedException e) { errWriter.println(e.getMessage()); allOk = false; continue; } catch (ExecutionException e) { - if (e.getCause() instanceof FormatterException) { - for (FormatterDiagnostic diagnostic : ((FormatterException) e.getCause()).diagnostics()) { - errWriter.println(path + ":" + diagnostic); - } - } else { - errWriter.println(path + ": error: " + e.getCause().getMessage()); - e.getCause().printStackTrace(errWriter); + errWriter.println("error: " + e.getCause().getMessage()); + e.getCause().printStackTrace(errWriter); + allOk = false; + continue; + } + } + Collections.sort(results, comparing(FormatFileCallable.Result::path)); + for (FormatFileCallable.Result result : results) { + Path path = result.path(); + if (result.exception() != null) { + for (FormatterDiagnostic diagnostic : result.exception().diagnostics()) { + errWriter.println(path + ":" + diagnostic); } allOk = false; continue; } - boolean changed = !formatted.equals(inputs.get(path)); + String formatted = result.output(); + boolean changed = result.changed(); if (changed && parameters.setExitIfChanged()) { allOk = false; } @@ -205,9 +211,16 @@ private int formatStdin(CommandLineOptions parameters, JavaFormatterOptions opti } String stdinFilename = parameters.assumeFilename().orElse(STDIN_FILENAME); boolean ok = true; - try { - String output = new FormatFileCallable(parameters, input, options).call(); - boolean changed = !input.equals(output); + FormatFileCallable.Result result = + new FormatFileCallable(parameters, null, input, options).call(); + if (result.exception() != null) { + for (FormatterDiagnostic diagnostic : result.exception().diagnostics()) { + errWriter.println(stdinFilename + ":" + diagnostic); + } + ok = false; + } else { + String output = result.output(); + boolean changed = result.changed(); if (changed && parameters.setExitIfChanged()) { ok = false; } @@ -218,12 +231,6 @@ private int formatStdin(CommandLineOptions parameters, JavaFormatterOptions opti } else { outWriter.write(output); } - } catch (FormatterException e) { - for (FormatterDiagnostic diagnostic : e.diagnostics()) { - errWriter.println(stdinFilename + ":" + diagnostic); - } - ok = false; - // TODO(cpovirk): Catch other types of exception (as we do in the formatFiles case). } return ok ? 0 : 1; } From 8c85ac1e3a794cc42362b92fd4fd0de21e23790c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 14 Feb 2023 15:00:23 -0800 Subject: [PATCH 194/379] Follow-up to https://github.com/google/google-java-format/commit/0a6a85e37f634fa870c920997d9270dca319cc03 See investigation in b/269345183 PiperOrigin-RevId: 509647966 --- core/src/main/java/com/google/googlejavaformat/java/Main.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 9c60fcb12..62423f226 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -137,7 +137,8 @@ private int formatFiles(CommandLineOptions parameters, JavaFormatterOptions opti } Path path = Paths.get(fileName); try { - cs.submit(new FormatFileCallable(parameters, path, Files.readString(path), options)); + String input = new String(Files.readAllBytes(path), UTF_8); + cs.submit(new FormatFileCallable(parameters, path, input, options)); files++; } catch (IOException e) { errWriter.println(fileName + ": could not read file: " + e.getMessage()); From 973cbff100aa1277ea97f26ffdbc2afd9cb0cb07 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 24 Feb 2023 13:44:10 -0800 Subject: [PATCH 195/379] Allow modifier reordering to be disabled This is currently the only non-whitespace change made as part of the core formatting logic. This is a requirement for updating the IntelliJ plugin to use the new supported plugin API. PiperOrigin-RevId: 512153706 --- .../googlejavaformat/java/Formatter.java | 4 +- .../java/JavaFormatterOptions.java | 50 +++++++------------ .../googlejavaformat/java/MainTest.java | 23 +++++++++ .../GoogleJavaFormatCodeStyleManager.java | 3 +- 4 files changed, 46 insertions(+), 34 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index 841e88a8a..9ff702d5a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -262,7 +262,9 @@ public ImmutableList getFormatReplacements( // TODO(cushon): this is only safe because the modifier ordering doesn't affect whitespace, // and doesn't change the replacements that are output. This is not true in general for // 'de-linting' changes (e.g. import ordering). - javaInput = ModifierOrderer.reorderModifiers(javaInput, characterRanges); + if (options.reorderModifiers()) { + javaInput = ModifierOrderer.reorderModifiers(javaInput, characterRanges); + } String lineSeparator = Newlines.guessLineSeparator(input); JavaOutput javaOutput = diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java b/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java index fbb6fe7e4..67c13d0b3 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaFormatterOptions.java @@ -14,6 +14,7 @@ package com.google.googlejavaformat.java; +import com.google.auto.value.AutoValue; import com.google.errorprone.annotations.Immutable; /** @@ -27,7 +28,8 @@ * preferences, and in fact it would work directly against our primary goals. */ @Immutable -public class JavaFormatterOptions { +@AutoValue +public abstract class JavaFormatterOptions { public enum Style { /** The default Google Java Style configuration. */ @@ -47,27 +49,17 @@ int indentationMultiplier() { } } - private final Style style; - private final boolean formatJavadoc; - - private JavaFormatterOptions(Style style, boolean formatJavadoc) { - this.style = style; - this.formatJavadoc = formatJavadoc; - } - /** Returns the multiplier for the unit of indent. */ public int indentationMultiplier() { - return style.indentationMultiplier(); + return style().indentationMultiplier(); } - public boolean formatJavadoc() { - return formatJavadoc; - } + public abstract boolean formatJavadoc(); + + public abstract boolean reorderModifiers(); /** Returns the code style. */ - public Style style() { - return style; - } + public abstract Style style(); /** Returns the default formatting options. */ public static JavaFormatterOptions defaultOptions() { @@ -76,28 +68,22 @@ public static JavaFormatterOptions defaultOptions() { /** Returns a builder for {@link JavaFormatterOptions}. */ public static Builder builder() { - return new Builder(); + return new AutoValue_JavaFormatterOptions.Builder() + .style(Style.GOOGLE) + .formatJavadoc(true) + .reorderModifiers(true); } /** A builder for {@link JavaFormatterOptions}. */ - public static class Builder { - private Style style = Style.GOOGLE; - private boolean formatJavadoc = true; + @AutoValue.Builder + public abstract static class Builder { - private Builder() {} + public abstract Builder style(Style style); - public Builder style(Style style) { - this.style = style; - return this; - } + public abstract Builder formatJavadoc(boolean formatJavadoc); - public Builder formatJavadoc(boolean formatJavadoc) { - this.formatJavadoc = formatJavadoc; - return this; - } + public abstract Builder reorderModifiers(boolean reorderModifiers); - public JavaFormatterOptions build() { - return new JavaFormatterOptions(style, formatJavadoc); - } + public abstract JavaFormatterOptions build(); } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index d4a410904..ad91bfa26 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -613,4 +613,27 @@ public void noFormatJavadoc() throws Exception { assertThat(main.format("--skip-javadoc-formatting", "-")).isEqualTo(0); assertThat(out.toString()).isEqualTo(joiner.join(input)); } + + @Test + public void reorderModifiersOptionTest() throws Exception { + String[] input = { + "class Test {", // + " static public void main(String... args) {}", + "}", + "", + }; + String[] fixed = { + "class Test {", // + " public static void main(String... args) {}", + "}", + "", + }; + String source = joiner.join(input); + assertThat(new Formatter(JavaFormatterOptions.builder().build()).formatSource(source)) + .isEqualTo(joiner.join(fixed)); + assertThat( + new Formatter(JavaFormatterOptions.builder().reorderModifiers(false).build()) + .formatSource(source)) + .isEqualTo(source); + } } diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java index 3d56743ee..c9aa64a67 100644 --- a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java +++ b/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java @@ -145,7 +145,8 @@ private void formatInternal(PsiFile file, Collection ranges */ private void format(Document document, Collection ranges) { Style style = GoogleJavaFormatSettings.getInstance(getProject()).getStyle(); - Formatter formatter = new Formatter(JavaFormatterOptions.builder().style(style).build()); + Formatter formatter = + new Formatter(JavaFormatterOptions.builder().style(style).reorderModifiers(false).build()); performReplacements( document, FormatterUtil.getReplacements(formatter, document.getText(), ranges)); } From eb7edafefc0cd2a2b2aaa35dff9ccdbf92d76eb4 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 24 Feb 2023 13:51:57 -0800 Subject: [PATCH 196/379] Update release.yml --- .github/workflows/release.yml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3f066df0..6e72789c7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,16 +12,7 @@ jobs: runs-on: ubuntu-latest permissions: contents: write - steps: - - name: Setup Signing Key - run: | - gpg-agent --daemon --default-cache-ttl 7200 - echo -e "${{ secrets.GPG_SIGNING_KEY }}" | gpg --batch --import --no-tty - echo "hello world" > temp.txt - gpg --detach-sig --yes -v --output=/dev/null --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" temp.txt - rm temp.txt - gpg --list-secret-keys --keyid-format LONG - + steps: - name: Checkout uses: actions/checkout@v2.4.0 @@ -34,6 +25,8 @@ jobs: server-id: sonatype-nexus-staging server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD + gpg-private-key: ${{ secrets.GPG_SIGNING_KEY }} + gpg-passphrase: MAVEN_GPG_PASSPHRASE - name: Bump Version Number run: | @@ -51,6 +44,7 @@ jobs: env: CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} run: mvn --no-transfer-progress -pl '!eclipse_plugin' -P sonatype-oss-release clean deploy -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" From 64f98edf6aeef20a890f09122bb8a5729bc7585a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 27 Feb 2023 11:32:35 -0800 Subject: [PATCH 197/379] Update ci.yml --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79a260eab..716abcc07 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,6 +43,9 @@ jobs: - os: ubuntu-latest java: 20-ea experimental: true + - os: ubuntu-latest + java: 21-ea + experimental: true runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} steps: From a7583fbb7776ee2f9398c280d78a68e161b929b0 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 27 Feb 2023 16:12:44 -0800 Subject: [PATCH 198/379] Prepare for a change to `JCTree.getQualifiedIdentifier ` https://github.com/openjdk/jdk/commit/a917fb3fcf0fe1a4c4de86c08ae4041462848b82 Fixes: https://github.com/google/google-java-format/issues/898 PiperOrigin-RevId: 512759236 --- .../java/RemoveUnusedImports.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index ecb30eed6..a0fc2f54a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -49,7 +49,6 @@ import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; -import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCImport; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Log; @@ -293,9 +292,7 @@ private static RangeMap buildReplacements( } private static String getSimpleName(JCImport importTree) { - return importTree.getQualifiedIdentifier() instanceof JCIdent - ? ((JCIdent) importTree.getQualifiedIdentifier()).getName().toString() - : ((JCFieldAccess) importTree.getQualifiedIdentifier()).getIdentifier().toString(); + return getQualifiedIdentifier(importTree).getIdentifier().toString(); } private static boolean isUnused( @@ -304,18 +301,15 @@ private static boolean isUnused( Multimap> usedInJavadoc, JCImport importTree, String simpleName) { - String qualifier = - ((JCFieldAccess) importTree.getQualifiedIdentifier()).getExpression().toString(); + JCFieldAccess qualifiedIdentifier = getQualifiedIdentifier(importTree); + String qualifier = qualifiedIdentifier.getExpression().toString(); if (qualifier.equals("java.lang")) { return true; } if (unit.getPackageName() != null && unit.getPackageName().toString().equals(qualifier)) { return true; } - if (importTree.getQualifiedIdentifier() instanceof JCFieldAccess - && ((JCFieldAccess) importTree.getQualifiedIdentifier()) - .getIdentifier() - .contentEquals("*")) { + if (qualifiedIdentifier.getIdentifier().contentEquals("*")) { return false; } @@ -328,6 +322,15 @@ private static boolean isUnused( return true; } + private static JCFieldAccess getQualifiedIdentifier(JCImport importTree) { + // Use reflection because the return type is JCTree in some versions and JCFieldAccess in others + try { + return (JCFieldAccess) JCImport.class.getMethod("getQualifiedIdentifier").invoke(importTree); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } + /** Applies the replacements to the given source, and re-format any edited javadoc. */ private static String applyReplacements(String source, RangeMap replacements) { // save non-empty fixed ranges for reformatting after fixes are applied From 9412083f3b42bcafece6d784f5c34da895525b66 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Tue, 28 Feb 2023 06:21:05 -0800 Subject: [PATCH 199/379] Use a standard gradle project structure. I'm going to add tests next, but with this weird file structure I've been using, there's no good place to put them. The only content changes here are in build.gradle. PiperOrigin-RevId: 512914783 --- idea_plugin/build.gradle | 7 ------- .../intellij/CodeStyleManagerDecorator.java | 0 .../google/googlejavaformat/intellij/FormatterUtil.java | 0 .../intellij/GoogleJavaFormatCodeStyleManager.java | 0 .../intellij/GoogleJavaFormatConfigurable.form | 0 .../intellij/GoogleJavaFormatConfigurable.java | 0 .../intellij/GoogleJavaFormatInstaller.java | 0 .../intellij/GoogleJavaFormatSettings.java | 0 .../InitialConfigurationProjectManagerListener.java | 0 .../google/googlejavaformat/intellij/UiFormatterStyle.java | 0 idea_plugin/{ => src/main}/resources/META-INF/plugin.xml | 0 11 files changed, 7 deletions(-) rename idea_plugin/src/{ => main/java}/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java (100%) rename idea_plugin/src/{ => main/java}/com/google/googlejavaformat/intellij/FormatterUtil.java (100%) rename idea_plugin/src/{ => main/java}/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java (100%) rename idea_plugin/src/{ => main/java}/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.form (100%) rename idea_plugin/src/{ => main/java}/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java (100%) rename idea_plugin/src/{ => main/java}/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java (100%) rename idea_plugin/src/{ => main/java}/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java (100%) rename idea_plugin/src/{ => main/java}/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java (100%) rename idea_plugin/src/{ => main/java}/com/google/googlejavaformat/intellij/UiFormatterStyle.java (100%) rename idea_plugin/{ => src/main}/resources/META-INF/plugin.xml (100%) diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 294d77e73..6c9695d47 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -50,13 +50,6 @@ publishPlugin { token = project.ext.properties.jetbrainsPluginRepoToken } -sourceSets { - main { - java.srcDir "src" - resources.srcDir "resources" - } -} - dependencies { implementation "com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}" } diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java similarity index 100% rename from idea_plugin/src/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/FormatterUtil.java similarity index 100% rename from idea_plugin/src/com/google/googlejavaformat/intellij/FormatterUtil.java rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/FormatterUtil.java diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java similarity index 100% rename from idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.form b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.form similarity index 100% rename from idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.form rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.form diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java similarity index 100% rename from idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java similarity index 100% rename from idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java similarity index 100% rename from idea_plugin/src/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java similarity index 100% rename from idea_plugin/src/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java diff --git a/idea_plugin/src/com/google/googlejavaformat/intellij/UiFormatterStyle.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/UiFormatterStyle.java similarity index 100% rename from idea_plugin/src/com/google/googlejavaformat/intellij/UiFormatterStyle.java rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/UiFormatterStyle.java diff --git a/idea_plugin/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml similarity index 100% rename from idea_plugin/resources/META-INF/plugin.xml rename to idea_plugin/src/main/resources/META-INF/plugin.xml From 84b2c9a2ba382ee7a968518b46afb0d6000ada8d Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Thu, 2 Mar 2023 09:40:06 -0800 Subject: [PATCH 200/379] Move the plugin to the FormattingService API. Also support optimizing imports, using the ImportOptimizer API. PiperOrigin-RevId: 513562756 --- idea_plugin/build.gradle | 18 +- .../intellij/CodeStyleManagerDecorator.java | 246 ----------------- .../intellij/FormatterUtil.java | 64 ----- .../GoogleJavaFormatCodeStyleManager.java | 173 ------------ .../GoogleJavaFormatFormattingService.java | 136 ++++++++++ .../GoogleJavaFormatImportOptimizer.java | 65 +++++ .../intellij/GoogleJavaFormatInstaller.java | 57 ---- .../intellij/Notifications.java | 38 +++ .../src/main/resources/META-INF/plugin.xml | 19 +- ...GoogleJavaFormatFormattingServiceTest.java | 250 ++++++++++++++++++ .../GoogleJavaFormatImportOptimizerTest.java | 168 ++++++++++++ 11 files changed, 683 insertions(+), 551 deletions(-) delete mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java delete mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/FormatterUtil.java delete mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java create mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java create mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java delete mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java create mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/Notifications.java create mode 100644 idea_plugin/src/test/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingServiceTest.java create mode 100644 idea_plugin/src/test/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizerTest.java diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 6c9695d47..732148670 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -15,7 +15,7 @@ */ plugins { - id "org.jetbrains.intellij" version "1.4.0" + id "org.jetbrains.intellij" version "1.13.0" } repositories { @@ -23,7 +23,7 @@ repositories { } ext { - googleJavaFormatVersion = "1.15.0" + googleJavaFormatVersion = "1.16.0" } apply plugin: "org.jetbrains.intellij" @@ -35,14 +35,14 @@ targetCompatibility = JavaVersion.VERSION_11 intellij { pluginName = "google-java-format" plugins = ["java"] - version = "221.3427-EAP-CANDIDATE-SNAPSHOT" + version = "2021.3" } patchPluginXml { pluginDescription = "Formats source code using the google-java-format tool. This version of " + "the plugin uses version ${googleJavaFormatVersion} of the tool." version.set("${googleJavaFormatVersion}.0") - sinceBuild = "203" + sinceBuild = "213" untilBuild = "" } @@ -50,6 +50,16 @@ publishPlugin { token = project.ext.properties.jetbrainsPluginRepoToken } +tasks.withType(Test).configureEach { + jvmArgs += "--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED" + jvmArgs += "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED" + jvmArgs += "--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED" + jvmArgs += "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" +} + dependencies { implementation "com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}" + testImplementation "junit:junit:4.13.2" + testImplementation "com.google.truth:truth:1.1.3" + testImplementation "com.google.truth.extensions:truth-java8-extension:1.1.3" } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java deleted file mode 100644 index af5da957a..000000000 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/CodeStyleManagerDecorator.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.googlejavaformat.intellij; - -import com.intellij.formatting.FormattingMode; -import com.intellij.lang.ASTNode; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileTypes.FileType; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.codeStyle.ChangedRangesInfo; -import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.codeStyle.DocCommentSettings; -import com.intellij.psi.codeStyle.FormattingModeAwareIndentAdjuster; -import com.intellij.psi.codeStyle.Indent; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.ThrowableRunnable; -import java.util.Collection; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.jetbrains.annotations.NotNull; - -/** - * Decorates the {@link CodeStyleManager} abstract class by delegating to a concrete implementation - * instance (likely IntelliJ's default instance). - */ -@SuppressWarnings("deprecation") -class CodeStyleManagerDecorator extends CodeStyleManager - implements FormattingModeAwareIndentAdjuster { - - private final CodeStyleManager delegate; - - CodeStyleManagerDecorator(CodeStyleManager delegate) { - this.delegate = delegate; - } - - CodeStyleManager getDelegate() { - return delegate; - } - - @Override - public @NotNull Project getProject() { - return delegate.getProject(); - } - - @Override - public @NotNull PsiElement reformat(@NotNull PsiElement element) - throws IncorrectOperationException { - return delegate.reformat(element); - } - - @Override - public @NotNull PsiElement reformat(@NotNull PsiElement element, boolean canChangeWhiteSpacesOnly) - throws IncorrectOperationException { - return delegate.reformat(element, canChangeWhiteSpacesOnly); - } - - @Override - public PsiElement reformatRange(@NotNull PsiElement element, int startOffset, int endOffset) - throws IncorrectOperationException { - return delegate.reformatRange(element, startOffset, endOffset); - } - - @Override - public PsiElement reformatRange( - @NotNull PsiElement element, int startOffset, int endOffset, boolean canChangeWhiteSpacesOnly) - throws IncorrectOperationException { - return delegate.reformatRange(element, startOffset, endOffset, canChangeWhiteSpacesOnly); - } - - @Override - public void reformatText(@NotNull PsiFile file, int startOffset, int endOffset) - throws IncorrectOperationException { - delegate.reformatText(file, startOffset, endOffset); - } - - @Override - public void reformatText(@NotNull PsiFile file, @NotNull Collection ranges) - throws IncorrectOperationException { - delegate.reformatText(file, ranges); - } - - @Override - public void reformatTextWithContext( - @NotNull PsiFile psiFile, @NotNull ChangedRangesInfo changedRangesInfo) - throws IncorrectOperationException { - delegate.reformatTextWithContext(psiFile, changedRangesInfo); - } - - @Override - public void reformatTextWithContext( - @NotNull PsiFile file, @NotNull Collection ranges) - throws IncorrectOperationException { - delegate.reformatTextWithContext(file, ranges); - } - - @Override - public void adjustLineIndent(@NotNull PsiFile file, TextRange rangeToAdjust) - throws IncorrectOperationException { - delegate.adjustLineIndent(file, rangeToAdjust); - } - - @Override - public int adjustLineIndent(@NotNull PsiFile file, int offset) - throws IncorrectOperationException { - return delegate.adjustLineIndent(file, offset); - } - - @Override - public int adjustLineIndent(@NotNull Document document, int offset) { - return delegate.adjustLineIndent(document, offset); - } - - public void scheduleIndentAdjustment(@NotNull Document document, int offset) { - delegate.scheduleIndentAdjustment(document, offset); - } - - @Override - public boolean isLineToBeIndented(@NotNull PsiFile file, int offset) { - return delegate.isLineToBeIndented(file, offset); - } - - @Override - @Nullable - public String getLineIndent(@NotNull PsiFile file, int offset) { - return delegate.getLineIndent(file, offset); - } - - @Override - @Nullable - public String getLineIndent(@NotNull PsiFile file, int offset, FormattingMode mode) { - return delegate.getLineIndent(file, offset, mode); - } - - @Override - @Nullable - public String getLineIndent(@NotNull Document document, int offset) { - return delegate.getLineIndent(document, offset); - } - - @Override - public Indent getIndent(String text, FileType fileType) { - return delegate.getIndent(text, fileType); - } - - @Override - public String fillIndent(Indent indent, FileType fileType) { - return delegate.fillIndent(indent, fileType); - } - - @Override - public Indent zeroIndent() { - return delegate.zeroIndent(); - } - - @Override - public void reformatNewlyAddedElement(@NotNull ASTNode block, @NotNull ASTNode addedElement) - throws IncorrectOperationException { - delegate.reformatNewlyAddedElement(block, addedElement); - } - - @Override - public boolean isSequentialProcessingAllowed() { - return delegate.isSequentialProcessingAllowed(); - } - - @Override - public void performActionWithFormatterDisabled(Runnable r) { - delegate.performActionWithFormatterDisabled(r); - } - - @Override - public void performActionWithFormatterDisabled(ThrowableRunnable r) - throws T { - delegate.performActionWithFormatterDisabled(r); - } - - @Override - public T performActionWithFormatterDisabled(Computable r) { - return delegate.performActionWithFormatterDisabled(r); - } - - @Override - public int getSpacing(@NotNull PsiFile file, int offset) { - return delegate.getSpacing(file, offset); - } - - @Override - public int getMinLineFeeds(@NotNull PsiFile file, int offset) { - return delegate.getMinLineFeeds(file, offset); - } - - @Override - public void runWithDocCommentFormattingDisabled( - @NotNull PsiFile file, @NotNull Runnable runnable) { - delegate.runWithDocCommentFormattingDisabled(file, runnable); - } - - @Override - public @NotNull DocCommentSettings getDocCommentSettings(@NotNull PsiFile file) { - return delegate.getDocCommentSettings(file); - } - - // From FormattingModeAwareIndentAdjuster - - /** Uses same fallback as {@link CodeStyleManager#getCurrentFormattingMode}. */ - @Override - public FormattingMode getCurrentFormattingMode() { - if (delegate instanceof FormattingModeAwareIndentAdjuster) { - return ((FormattingModeAwareIndentAdjuster) delegate).getCurrentFormattingMode(); - } - return FormattingMode.REFORMAT; - } - - @Override - public int adjustLineIndent( - final @NotNull Document document, final int offset, FormattingMode mode) - throws IncorrectOperationException { - if (delegate instanceof FormattingModeAwareIndentAdjuster) { - return ((FormattingModeAwareIndentAdjuster) delegate) - .adjustLineIndent(document, offset, mode); - } - return offset; - } - - @Override - public void scheduleReformatWhenSettingsComputed(@NotNull PsiFile file) { - delegate.scheduleReformatWhenSettingsComputed(file); - } -} diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/FormatterUtil.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/FormatterUtil.java deleted file mode 100644 index a5e69c93d..000000000 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/FormatterUtil.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.googlejavaformat.intellij; - -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.collect.BoundType; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Range; -import com.google.googlejavaformat.java.Formatter; -import com.google.googlejavaformat.java.FormatterException; -import com.intellij.openapi.util.TextRange; -import java.util.Collection; -import java.util.Map; -import java.util.stream.Collectors; - -final class FormatterUtil { - - private FormatterUtil() {} - - static Map getReplacements( - Formatter formatter, String text, Collection ranges) { - try { - ImmutableMap.Builder replacements = ImmutableMap.builder(); - formatter - .getFormatReplacements(text, toRanges(ranges)) - .forEach( - replacement -> - replacements.put( - toTextRange(replacement.getReplaceRange()), - replacement.getReplacementString())); - return replacements.build(); - } catch (FormatterException e) { - return ImmutableMap.of(); - } - } - - private static Collection> toRanges(Collection textRanges) { - return textRanges.stream() - .map(textRange -> Range.closedOpen(textRange.getStartOffset(), textRange.getEndOffset())) - .collect(Collectors.toList()); - } - - private static TextRange toTextRange(Range range) { - checkState( - range.lowerBoundType().equals(BoundType.CLOSED) - && range.upperBoundType().equals(BoundType.OPEN)); - return new TextRange(range.lowerEndpoint(), range.upperEndpoint()); - } -} diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java deleted file mode 100644 index c9aa64a67..000000000 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatCodeStyleManager.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.googlejavaformat.intellij; - -import static java.util.Comparator.comparing; - -import com.google.common.collect.ImmutableList; -import com.google.googlejavaformat.java.Formatter; -import com.google.googlejavaformat.java.JavaFormatterOptions; -import com.google.googlejavaformat.java.JavaFormatterOptions.Style; -import com.intellij.ide.highlighter.JavaFileType; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.codeStyle.ChangedRangesInfo; -import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.impl.CheckUtil; -import com.intellij.util.IncorrectOperationException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; -import org.jetbrains.annotations.NotNull; - -/** - * A {@link CodeStyleManager} implementation which formats .java files with google-java-format. - * Formatting of all other types of files is delegated to IntelliJ's default implementation. - */ -class GoogleJavaFormatCodeStyleManager extends CodeStyleManagerDecorator { - - public GoogleJavaFormatCodeStyleManager(@NotNull CodeStyleManager original) { - super(original); - } - - @Override - public void reformatText(@NotNull PsiFile file, int startOffset, int endOffset) - throws IncorrectOperationException { - if (overrideFormatterForFile(file)) { - formatInternal(file, ImmutableList.of(new TextRange(startOffset, endOffset))); - } else { - super.reformatText(file, startOffset, endOffset); - } - } - - @Override - public void reformatText(@NotNull PsiFile file, @NotNull Collection ranges) - throws IncorrectOperationException { - if (overrideFormatterForFile(file)) { - formatInternal(file, ranges); - } else { - super.reformatText(file, ranges); - } - } - - @Override - public void reformatTextWithContext(@NotNull PsiFile file, @NotNull ChangedRangesInfo info) - throws IncorrectOperationException { - List ranges = new ArrayList<>(); - if (info.insertedRanges != null) { - ranges.addAll(info.insertedRanges); - } - ranges.addAll(info.allChangedRanges); - reformatTextWithContext(file, ranges); - } - - @Override - public void reformatTextWithContext( - @NotNull PsiFile file, @NotNull Collection ranges) { - if (overrideFormatterForFile(file)) { - formatInternal(file, ranges); - } else { - super.reformatTextWithContext(file, ranges); - } - } - - @Override - public PsiElement reformatRange( - @NotNull PsiElement element, - int startOffset, - int endOffset, - boolean canChangeWhiteSpacesOnly) { - // Only handle elements that are PsiFile for now -- otherwise we need to search for some - // element within the file at new locations given the original startOffset and endOffsets - // to serve as the return value. - PsiFile file = element instanceof PsiFile ? (PsiFile) element : null; - if (file != null && canChangeWhiteSpacesOnly && overrideFormatterForFile(file)) { - formatInternal(file, ImmutableList.of(new TextRange(startOffset, endOffset))); - return file; - } else { - return super.reformatRange(element, startOffset, endOffset, canChangeWhiteSpacesOnly); - } - } - - /** Return whether this formatter can handle formatting the given file. */ - private boolean overrideFormatterForFile(PsiFile file) { - return JavaFileType.INSTANCE.equals(file.getFileType()) - && GoogleJavaFormatSettings.getInstance(getProject()).isEnabled(); - } - - private void formatInternal(PsiFile file, Collection ranges) { - ApplicationManager.getApplication().assertWriteAccessAllowed(); - PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject()); - documentManager.commitAllDocuments(); - CheckUtil.checkWritable(file); - - Document document = documentManager.getDocument(file); - - if (document == null) { - return; - } - // If there are postponed PSI changes (e.g., during a refactoring), just abort. - // If we apply them now, then the incoming text ranges may no longer be valid. - if (documentManager.isDocumentBlockedByPsi(document)) { - return; - } - - format(document, ranges); - } - - /** - * Format the ranges of the given document. - * - *

Overriding methods will need to modify the document with the result of the external - * formatter (usually using {@link #performReplacements(Document, Map)}). - */ - private void format(Document document, Collection ranges) { - Style style = GoogleJavaFormatSettings.getInstance(getProject()).getStyle(); - Formatter formatter = - new Formatter(JavaFormatterOptions.builder().style(style).reorderModifiers(false).build()); - performReplacements( - document, FormatterUtil.getReplacements(formatter, document.getText(), ranges)); - } - - private void performReplacements( - final Document document, final Map replacements) { - - if (replacements.isEmpty()) { - return; - } - - TreeMap sorted = new TreeMap<>(comparing(TextRange::getStartOffset)); - sorted.putAll(replacements); - WriteCommandAction.runWriteCommandAction( - getProject(), - () -> { - for (Entry entry : sorted.descendingMap().entrySet()) { - document.replaceString( - entry.getKey().getStartOffset(), entry.getKey().getEndOffset(), entry.getValue()); - } - PsiDocumentManager.getInstance(getProject()).commitDocument(document); - }); - } -} diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java new file mode 100644 index 000000000..1e7ca1a6f --- /dev/null +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java @@ -0,0 +1,136 @@ +/* + * Copyright 2023 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.googlejavaformat.intellij; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Range; +import com.google.googlejavaformat.java.Formatter; +import com.google.googlejavaformat.java.FormatterException; +import com.google.googlejavaformat.java.JavaFormatterOptions; +import com.google.googlejavaformat.java.JavaFormatterOptions.Style; +import com.intellij.formatting.service.AsyncDocumentFormattingService; +import com.intellij.formatting.service.AsyncFormattingRequest; +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.lang.ImportOptimizer; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiFile; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import org.jetbrains.annotations.NotNull; + +/** Uses {@code google-java-format} to reformat code. */ +public class GoogleJavaFormatFormattingService extends AsyncDocumentFormattingService { + + public static final ImmutableSet IMPORT_OPTIMIZERS = + ImmutableSet.of(new GoogleJavaFormatImportOptimizer()); + + @Override + protected FormattingTask createFormattingTask(AsyncFormattingRequest request) { + Project project = request.getContext().getProject(); + Style style = GoogleJavaFormatSettings.getInstance(project).getStyle(); + Formatter formatter = createFormatter(style, request.canChangeWhitespaceOnly()); + return new GoogleJavaFormatFormattingTask(formatter, request); + } + + @Override + protected String getNotificationGroupId() { + return Notifications.PARSING_ERROR_NOTIFICATION_GROUP; + } + + @Override + protected String getName() { + return "google-java-format"; + } + + private static Formatter createFormatter(Style style, boolean canChangeWhiteSpaceOnly) { + JavaFormatterOptions.Builder optBuilder = JavaFormatterOptions.builder().style(style); + if (canChangeWhiteSpaceOnly) { + optBuilder.formatJavadoc(false).reorderModifiers(false); + } + return new Formatter(optBuilder.build()); + } + + @Override + public @NotNull Set getFeatures() { + return Set.of(Feature.AD_HOC_FORMATTING, Feature.FORMAT_FRAGMENTS, Feature.OPTIMIZE_IMPORTS); + } + + @Override + public boolean canFormat(@NotNull PsiFile file) { + return JavaFileType.INSTANCE.equals(file.getFileType()) + && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled(); + } + + @Override + public @NotNull Set getImportOptimizers(@NotNull PsiFile file) { + return IMPORT_OPTIMIZERS; + } + + private static final class GoogleJavaFormatFormattingTask implements FormattingTask { + private final Formatter formatter; + private final AsyncFormattingRequest request; + + private GoogleJavaFormatFormattingTask(Formatter formatter, AsyncFormattingRequest request) { + this.formatter = formatter; + this.request = request; + } + + @Override + public void run() { + try { + String formattedText = formatter.formatSource(request.getDocumentText(), toRanges(request)); + request.onTextReady(formattedText); + } catch (FormatterException e) { + request.onError( + Notifications.PARSING_ERROR_TITLE, + Notifications.parsingErrorMessage(request.getContext().getContainingFile().getName())); + } + } + + private static Collection> toRanges(AsyncFormattingRequest request) { + if (isWholeFile(request)) { + // The IDE sometimes passes invalid ranges when the file is unsaved before invoking the + // formatter. So this is a workaround for that issue. + return ImmutableList.of(Range.closedOpen(0, request.getDocumentText().length())); + } + return request.getFormattingRanges().stream() + .map(textRange -> Range.closedOpen(textRange.getStartOffset(), textRange.getEndOffset())) + .collect(ImmutableList.toImmutableList()); + } + + private static boolean isWholeFile(AsyncFormattingRequest request) { + List ranges = request.getFormattingRanges(); + return ranges.size() == 1 + && ranges.get(0).getStartOffset() == 0 + // using greater than or equal because ranges are sometimes passed inaccurately + && ranges.get(0).getEndOffset() >= request.getDocumentText().length(); + } + + @Override + public boolean isRunUnderProgress() { + return true; + } + + @Override + public boolean cancel() { + return false; + } + } +} diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java new file mode 100644 index 000000000..3a9a30f49 --- /dev/null +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java @@ -0,0 +1,65 @@ +/* + * Copyright 2023 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.googlejavaformat.intellij; + +import com.google.common.util.concurrent.Runnables; +import com.google.googlejavaformat.java.FormatterException; +import com.google.googlejavaformat.java.ImportOrderer; +import com.google.googlejavaformat.java.JavaFormatterOptions; +import com.google.googlejavaformat.java.RemoveUnusedImports; +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.lang.ImportOptimizer; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +/** Uses {@code google-java-format} to optimize imports. */ +public class GoogleJavaFormatImportOptimizer implements ImportOptimizer { + + @Override + public boolean supports(@NotNull PsiFile file) { + return JavaFileType.INSTANCE.equals(file.getFileType()) + && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled(); + } + + @Override + public @NotNull Runnable processFile(@NotNull PsiFile file) { + Project project = file.getProject(); + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); + Document document = documentManager.getDocument(file); + + if (document == null) { + return Runnables.doNothing(); + } + + JavaFormatterOptions.Style style = GoogleJavaFormatSettings.getInstance(project).getStyle(); + + String text; + try { + text = + ImportOrderer.reorderImports( + RemoveUnusedImports.removeUnusedImports(document.getText()), style); + } catch (FormatterException e) { + Notifications.displayParsingErrorNotification(project, file.getName()); + return Runnables.doNothing(); + } + + return () -> document.setText(text); + } +} diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java deleted file mode 100644 index c60673602..000000000 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatInstaller.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.googlejavaformat.intellij; - -import static com.google.common.base.Preconditions.checkState; - -import com.intellij.ide.plugins.IdeaPluginDescriptor; -import com.intellij.ide.plugins.PluginManagerCore; -import com.intellij.openapi.extensions.PluginId; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManagerListener; -import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.serviceContainer.ComponentManagerImpl; -import org.jetbrains.annotations.NotNull; - -/** - * A component that replaces the default IntelliJ {@link CodeStyleManager} with one that formats via - * google-java-format. - */ -final class GoogleJavaFormatInstaller implements ProjectManagerListener { - - @Override - public void projectOpened(@NotNull Project project) { - installFormatter(project); - } - - private static void installFormatter(Project project) { - CodeStyleManager currentManager = CodeStyleManager.getInstance(project); - - if (currentManager instanceof GoogleJavaFormatCodeStyleManager) { - currentManager = ((GoogleJavaFormatCodeStyleManager) currentManager).getDelegate(); - } - - setManager(project, new GoogleJavaFormatCodeStyleManager(currentManager)); - } - - private static void setManager(Project project, CodeStyleManager newManager) { - ComponentManagerImpl platformComponentManager = (ComponentManagerImpl) project; - IdeaPluginDescriptor plugin = PluginManagerCore.getPlugin(PluginId.getId("google-java-format")); - checkState(plugin != null, "Couldn't locate our own PluginDescriptor."); - platformComponentManager.registerServiceInstance(CodeStyleManager.class, newManager, plugin); - } -} diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/Notifications.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/Notifications.java new file mode 100644 index 000000000..d32aa98b9 --- /dev/null +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/Notifications.java @@ -0,0 +1,38 @@ +/* + * Copyright 2023 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.googlejavaformat.intellij; + +import com.intellij.formatting.service.FormattingNotificationService; +import com.intellij.openapi.project.Project; + +class Notifications { + + static final String PARSING_ERROR_NOTIFICATION_GROUP = "google-java-format parsing error"; + static final String PARSING_ERROR_TITLE = PARSING_ERROR_NOTIFICATION_GROUP; + + static String parsingErrorMessage(String filename) { + return "google-java-format failed. Does " + filename + " have syntax errors?"; + } + + static void displayParsingErrorNotification(Project project, String filename) { + FormattingNotificationService.getInstance(project) + .reportError( + Notifications.PARSING_ERROR_NOTIFICATION_GROUP, + Notifications.PARSING_ERROR_TITLE, + Notifications.parsingErrorMessage(filename)); + } +} diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 42d5f3b31..2a82c9557 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -22,13 +22,16 @@ Google - - com.intellij.java + com.intellij.modules.java + com.intellij.modules.lang + com.intellij.modules.platform +

1.16.0.0
+
Updated to use google-java-format 1.16.0.
+
Use the new IDE formatting APIs for a simplified plugin.
+
Optimize Imports now uses google-java-format.
1.15.0.0
Updated to use google-java-format 1.15.0.
1.14.0.0
@@ -66,11 +69,11 @@ - + + isLogByDefault="false"/> + diff --git a/idea_plugin/src/test/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingServiceTest.java b/idea_plugin/src/test/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingServiceTest.java new file mode 100644 index 000000000..fec086c68 --- /dev/null +++ b/idea_plugin/src/test/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingServiceTest.java @@ -0,0 +1,250 @@ +/* + * Copyright 2023 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.googlejavaformat.intellij; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.googlejavaformat.intellij.GoogleJavaFormatSettings.State; +import com.google.googlejavaformat.java.Formatter; +import com.google.googlejavaformat.java.JavaFormatterOptions; +import com.google.googlejavaformat.java.JavaFormatterOptions.Style; +import com.intellij.formatting.service.AsyncFormattingRequest; +import com.intellij.formatting.service.FormattingService; +import com.intellij.formatting.service.FormattingServiceUtil; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.testFramework.ExtensionTestUtil; +import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; +import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; +import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture; +import com.intellij.testFramework.fixtures.JavaTestFixtureFactory; +import com.intellij.testFramework.fixtures.TestFixtureBuilder; +import java.io.IOException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class GoogleJavaFormatFormattingServiceTest { + private JavaCodeInsightTestFixture fixture; + private GoogleJavaFormatSettings settings; + private DelegatingFormatter delegatingFormatter; + + @Before + public void setUp() throws Exception { + TestFixtureBuilder projectBuilder = + IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getClass().getName()); + fixture = + JavaTestFixtureFactory.getFixtureFactory() + .createCodeInsightFixture(projectBuilder.getFixture()); + fixture.setUp(); + + delegatingFormatter = new DelegatingFormatter(); + ExtensionTestUtil.maskExtensions( + FormattingService.EP_NAME, + ImmutableList.of(delegatingFormatter), + fixture.getProjectDisposable()); + + settings = GoogleJavaFormatSettings.getInstance(fixture.getProject()); + State resetState = new State(); + resetState.setEnabled("true"); + settings.loadState(resetState); + } + + @After + public void tearDown() throws Exception { + fixture.tearDown(); + } + + @Test + public void defaultFormatSettings() throws Exception { + PsiFile file = + createPsiFile( + "com/foo/FormatTest.java", + "package com.foo;", + "public class FormatTest {", + "static final String CONST_STR = \"Hello\";", + "}"); + String origText = file.getText(); + CodeStyleManager manager = CodeStyleManager.getInstance(file.getProject()); + WriteCommandAction.runWriteCommandAction( + file.getProject(), () -> manager.reformatText(file, 0, file.getTextLength())); + + assertThat(file.getText()).isEqualTo(new Formatter().formatSource(origText)); + assertThat(delegatingFormatter.wasInvoked()).isTrue(); + } + + @Test + public void aospStyle() throws Exception { + settings.setStyle(Style.AOSP); + PsiFile file = + createPsiFile( + "com/foo/FormatTest.java", + "package com.foo;", + "public class FormatTest {", + "static final String CONST_STR = \"Hello\";", + "}"); + String origText = file.getText(); + CodeStyleManager manager = CodeStyleManager.getInstance(file.getProject()); + WriteCommandAction.runWriteCommandAction( + file.getProject(), () -> manager.reformatText(file, 0, file.getTextLength())); + + assertThat(file.getText()) + .isEqualTo( + new Formatter(JavaFormatterOptions.builder().style(Style.AOSP).build()) + .formatSource(origText)); + assertThat(delegatingFormatter.wasInvoked()).isTrue(); + } + + @Test + public void canChangeWhitespaceOnlyDoesNotReorderModifiers() throws Exception { + settings.setStyle(Style.GOOGLE); + PsiFile file = + createPsiFile( + "com/foo/FormatTest.java", + "package com.foo;", + "public class FormatTest {", + "final static String CONST_STR = \"Hello\";", + "}"); + CodeStyleManager manager = CodeStyleManager.getInstance(file.getProject()); + var offset = file.getText().indexOf("final static"); + WriteCommandAction.runWriteCommandAction( + file.getProject(), + () -> + FormattingServiceUtil.formatElement( + file.findElementAt(offset), /* canChangeWhitespaceOnly= */ true)); + + // In non-whitespace mode, this would flip the order of these modifiers. (Also check for leading + // spaces to make sure the formatter actually ran. + assertThat(file.getText()).containsMatch(" final static"); + assertThat(delegatingFormatter.wasInvoked()).isTrue(); + } + + @Test + public void canChangeWhitespaceOnlyDoesNotReformatJavadoc() throws Exception { + settings.setStyle(Style.GOOGLE); + PsiFile file = + createPsiFile( + "com/foo/FormatTest.java", + "package com.foo;", + "public class FormatTest {", + "/**", + " * hello", + " */", + "static final String CONST_STR = \"Hello\";", + "}"); + CodeStyleManager manager = CodeStyleManager.getInstance(file.getProject()); + var offset = file.getText().indexOf("hello"); + WriteCommandAction.runWriteCommandAction( + file.getProject(), + () -> + FormattingServiceUtil.formatElement( + file.findElementAt(offset), /* canChangeWhitespaceOnly= */ true)); + + // In non-whitespace mode, this would join the Javadoc into a single line. + assertThat(file.getText()).containsMatch(" \\* hello"); + // Also check for leading spaces to make sure the formatter actually ran. (Technically, this is + // outside the range that we asked to be formatted, but gjf will still format it.) + assertThat(file.getText()).containsMatch(" static final"); + assertThat(delegatingFormatter.wasInvoked()).isTrue(); + } + + @Test + public void canChangeNonWhitespaceReordersModifiers() throws Exception { + settings.setStyle(Style.GOOGLE); + PsiFile file = + createPsiFile( + "com/foo/FormatTest.java", + "package com.foo;", + "public class FormatTest {", + "final static String CONST_STR = \"Hello\";", + "}"); + CodeStyleManager manager = CodeStyleManager.getInstance(file.getProject()); + var offset = file.getText().indexOf("final static"); + WriteCommandAction.runWriteCommandAction( + file.getProject(), + () -> + FormattingServiceUtil.formatElement( + file.findElementAt(offset), /* canChangeWhitespaceOnly= */ false)); + + assertThat(file.getText()).containsMatch("static final"); + assertThat(delegatingFormatter.wasInvoked()).isTrue(); + } + + @Test + public void canChangeNonWhitespaceReformatsJavadoc() throws Exception { + settings.setStyle(Style.GOOGLE); + PsiFile file = + createPsiFile( + "com/foo/FormatTest.java", + "package com.foo;", + "public class FormatTest {", + "/**", + " * hello", + " */", + "static final String CONST_STR = \"Hello\";", + "}"); + CodeStyleManager manager = CodeStyleManager.getInstance(file.getProject()); + var offset = file.getText().indexOf("hello"); + WriteCommandAction.runWriteCommandAction( + file.getProject(), + () -> + FormattingServiceUtil.formatElement( + file.findElementAt(offset), /* canChangeWhitespaceOnly= */ false)); + + assertThat(file.getText()).containsMatch("/\\*\\* hello \\*/"); + assertThat(delegatingFormatter.wasInvoked()).isTrue(); + } + + private PsiFile createPsiFile(String path, String... contents) throws IOException { + VirtualFile virtualFile = + fixture.getTempDirFixture().createFile(path, String.join("\n", contents)); + fixture.configureFromExistingVirtualFile(virtualFile); + PsiFile psiFile = fixture.getFile(); + assertThat(psiFile).isNotNull(); + return psiFile; + } + + private static final class DelegatingFormatter extends GoogleJavaFormatFormattingService { + + private boolean invoked = false; + + private boolean wasInvoked() { + return invoked; + } + + @Override + protected FormattingTask createFormattingTask(AsyncFormattingRequest request) { + FormattingTask delegateTask = super.createFormattingTask(request); + return new FormattingTask() { + @Override + public boolean cancel() { + return delegateTask.cancel(); + } + + @Override + public void run() { + invoked = true; + delegateTask.run(); + } + }; + } + } +} diff --git a/idea_plugin/src/test/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizerTest.java b/idea_plugin/src/test/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizerTest.java new file mode 100644 index 000000000..ad9fe2744 --- /dev/null +++ b/idea_plugin/src/test/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizerTest.java @@ -0,0 +1,168 @@ +/* + * Copyright 2023 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.googlejavaformat.intellij; + +import static com.google.common.collect.ImmutableSet.toImmutableSet; +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.googlejavaformat.intellij.GoogleJavaFormatSettings.State; +import com.intellij.codeInsight.actions.OptimizeImportsProcessor; +import com.intellij.formatting.service.FormattingService; +import com.intellij.lang.ImportOptimizer; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.testFramework.ExtensionTestUtil; +import com.intellij.testFramework.fixtures.IdeaProjectTestFixture; +import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; +import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture; +import com.intellij.testFramework.fixtures.JavaTestFixtureFactory; +import com.intellij.testFramework.fixtures.TestFixtureBuilder; +import java.io.IOException; +import java.util.Set; +import org.jetbrains.annotations.NotNull; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class GoogleJavaFormatImportOptimizerTest { + private JavaCodeInsightTestFixture fixture; + private DelegatingFormatter delegatingFormatter; + + @Before + public void setUp() throws Exception { + TestFixtureBuilder projectBuilder = + IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getClass().getName()); + fixture = + JavaTestFixtureFactory.getFixtureFactory() + .createCodeInsightFixture(projectBuilder.getFixture()); + fixture.setUp(); + + delegatingFormatter = new DelegatingFormatter(); + ExtensionTestUtil.maskExtensions( + FormattingService.EP_NAME, + ImmutableList.of(delegatingFormatter), + fixture.getProjectDisposable()); + + var settings = GoogleJavaFormatSettings.getInstance(fixture.getProject()); + State resetState = new State(); + resetState.setEnabled("true"); + settings.loadState(resetState); + } + + @After + public void tearDown() throws Exception { + fixture.tearDown(); + } + + @Test + public void removesUnusedImports() throws Exception { + PsiFile file = + createPsiFile( + "com/foo/ImportTest.java", + "package com.foo;", + "import java.util.List;", + "import java.util.ArrayList;", + "import java.util.Map;", + "public class ImportTest {", + "static final Map map;", + "}"); + OptimizeImportsProcessor processor = new OptimizeImportsProcessor(file.getProject(), file); + WriteCommandAction.runWriteCommandAction( + file.getProject(), + () -> { + processor.run(); + PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments(); + }); + + assertThat(file.getText()).doesNotContain("List"); + assertThat(file.getText()).contains("import java.util.Map;"); + assertThat(delegatingFormatter.wasInvoked()).isTrue(); + } + + @Test + public void reordersImports() throws Exception { + PsiFile file = + createPsiFile( + "com/foo/ImportTest.java", + "package com.foo;", + "import java.util.List;", + "import java.util.ArrayList;", + "import java.util.Map;", + "public class ImportTest {", + "static final ArrayList arrayList;", + "static final List list;", + "static final Map map;", + "}"); + OptimizeImportsProcessor processor = new OptimizeImportsProcessor(file.getProject(), file); + WriteCommandAction.runWriteCommandAction( + file.getProject(), + () -> { + processor.run(); + PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments(); + }); + + assertThat(file.getText()) + .contains( + "import java.util.ArrayList;\n" + + "import java.util.List;\n" + + "import java.util.Map;\n"); + assertThat(delegatingFormatter.wasInvoked()).isTrue(); + } + + private PsiFile createPsiFile(String path, String... contents) throws IOException { + VirtualFile virtualFile = + fixture.getTempDirFixture().createFile(path, String.join("\n", contents)); + fixture.configureFromExistingVirtualFile(virtualFile); + PsiFile psiFile = fixture.getFile(); + assertThat(psiFile).isNotNull(); + return psiFile; + } + + private static final class DelegatingFormatter extends GoogleJavaFormatFormattingService { + + private boolean invoked = false; + + private boolean wasInvoked() { + return invoked; + } + + @Override + public @NotNull Set getImportOptimizers(@NotNull PsiFile file) { + return super.getImportOptimizers(file).stream().map(this::wrap).collect(toImmutableSet()); + } + + private ImportOptimizer wrap(ImportOptimizer delegate) { + return new ImportOptimizer() { + @Override + public boolean supports(@NotNull PsiFile file) { + return delegate.supports(file); + } + + @Override + public @NotNull Runnable processFile(@NotNull PsiFile file) { + return () -> { + invoked = true; + delegate.processFile(file).run(); + }; + } + }; + } + } +} From 0644d4c67ba42845f82eb23405f09fc1b97a7cff Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 2 Mar 2023 11:14:37 -0800 Subject: [PATCH 201/379] Make the `-add-exports=` passed to g-j-f consistent PiperOrigin-RevId: 513589436 --- README.md | 1 + core/pom.xml | 5 ++--- .../java/com/google/googlejavaformat/java/MainTest.java | 7 +++---- pom.xml | 5 +---- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2d53f8ae5..f2c61e3dd 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ following JVM flags are required when running on JDK 16 and newer, due to ``` --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED diff --git a/core/pom.xml b/core/pom.xml index 10565c66a..038e4eda6 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -102,13 +102,12 @@ https://docs.oracle.com/en/java/javase/11/docs/api + --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,com.google.googlejavaformat + --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED,com.google.googlejavaformat --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED,com.google.googlejavaformat - --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED,com.google.googlejavaformat --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED,com.google.googlejavaformat --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED,com.google.googlejavaformat --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED,com.google.googlejavaformat - --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED,com.google.googlejavaformat - --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED,com.google.googlejavaformat diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index ad91bfa26..42e12d860 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -54,13 +54,12 @@ public class MainTest { private static final ImmutableList ADD_EXPORTS = ImmutableList.of( + "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", "--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", - "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", "--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", - "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", - "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", - "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED"); + "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED"); @Test public void testUsageOutput() { diff --git a/pom.xml b/pom.xml index 150173ee6..243da54d3 100644 --- a/pom.xml +++ b/pom.xml @@ -235,15 +235,12 @@ jdk.compiler/com.sun.tools.javac.api jdk.compiler/com.sun.tools.javac.code jdk.compiler/com.sun.tools.javac.file jdk.compiler/com.sun.tools.javac.main jdk.compiler/com.sun.tools.javac.model jdk.compiler/com.sun.tools.javac.parser jdk.compiler/com.sun.tools.javac.processing jdk.compiler/com.sun.tools.javac.tree jdk.compiler/com.sun.tools.javac.util - jdk.compiler/com.sun.tools.javac.code jdk.compiler/com.sun.tools.javac.comp From 32a6c00ff4cfdc3697d556c43968d58602f3cac3 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Fri, 3 Mar 2023 06:23:10 -0800 Subject: [PATCH 202/379] Switch (deprecated) ProjectManagerListener#onProjectOpened to StartupActivity. PiperOrigin-RevId: 513811140 --- ...=> InitialConfigurationStartupActivity.java} | 17 +++++++++-------- .../src/main/resources/META-INF/plugin.xml | 7 +------ 2 files changed, 10 insertions(+), 14 deletions(-) rename idea_plugin/src/main/java/com/google/googlejavaformat/intellij/{InitialConfigurationProjectManagerListener.java => InitialConfigurationStartupActivity.java} (83%) diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java similarity index 83% rename from idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java rename to idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java index 1906347f7..7cedbbec7 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationProjectManagerListener.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java @@ -21,17 +21,17 @@ import com.intellij.notification.NotificationGroupManager; import com.intellij.notification.NotificationType; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.startup.StartupActivity; import org.jetbrains.annotations.NotNull; -final class InitialConfigurationProjectManagerListener implements ProjectManagerListener { +final class InitialConfigurationStartupActivity implements StartupActivity.Background { private static final String NOTIFICATION_TITLE = "Enable google-java-format"; private static final NotificationGroup NOTIFICATION_GROUP = NotificationGroupManager.getInstance().getNotificationGroup(NOTIFICATION_TITLE); @Override - public void projectOpened(@NotNull Project project) { + public void runActivity(@NotNull Project project) { GoogleJavaFormatSettings settings = GoogleJavaFormatSettings.getInstance(project); if (settings.isUninitialized()) { @@ -47,11 +47,12 @@ private void displayNewUserNotification(Project project, GoogleJavaFormatSetting NOTIFICATION_TITLE, "The google-java-format plugin is disabled by default. " + "Enable for this project.", - NotificationType.INFORMATION, - (n, e) -> { - settings.setEnabled(true); - n.expire(); - }); + NotificationType.INFORMATION); + notification.setListener( + (n, e) -> { + settings.setEnabled(true); + n.expire(); + }); notification.notify(project); } } diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 2a82c9557..f272ab26d 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -65,15 +65,10 @@ ]]>
- - - - + Date: Fri, 3 Mar 2023 07:30:57 -0800 Subject: [PATCH 203/379] Link to instructions for properly configuring the IDE's JRE. Pop up this warning once per-project per-launch, only when the Formatter is enabled (or at startup if the formatter is already enabled in the project). PiperOrigin-RevId: 513822794 --- README.md | 27 +++-- idea_plugin/build.gradle | 10 +- .../GoogleJavaFormatFormattingService.java | 3 +- .../GoogleJavaFormatImportOptimizer.java | 3 +- .../intellij/GoogleJavaFormatSettings.java | 9 ++ .../InitialConfigurationStartupActivity.java | 2 + .../intellij/JreConfigurationChecker.java | 102 ++++++++++++++++++ .../src/main/resources/META-INF/plugin.xml | 3 + 8 files changed, 145 insertions(+), 14 deletions(-) create mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java diff --git a/README.md b/README.md index f2c61e3dd..376863fff 100644 --- a/README.md +++ b/README.md @@ -44,14 +44,25 @@ presented when you first open a project offering to do this for you.) To enable it by default in new projects, use `File→Other Settings→Default Settings...`. -When enabled, it will replace the normal `Reformat Code` action, which can be -triggered from the `Code` menu or with the Ctrl-Alt-L (by default) keyboard -shortcut. - -The import ordering is not handled by this plugin, unfortunately. To fix the -import order, download the -[IntelliJ Java Google Style file](https://raw.githubusercontent.com/google/styleguide/gh-pages/intellij-java-google-style.xml) -and import it into File→Settings→Editor→Code Style. +When enabled, it will replace the normal `Reformat Code` and `Optimize Imports` +actions. + +#### IntelliJ JRE Config + +The google-java-format plugin uses some internal classes that aren't available +without extra configuration. To use the plugin, go to `Help→Edit Custom VM +Options...` and paste in these lines: + +``` +--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +``` + +Once you've done that, restart the IDE. ### Eclipse diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle index 732148670..3032dd54d 100644 --- a/idea_plugin/build.gradle +++ b/idea_plugin/build.gradle @@ -51,10 +51,12 @@ publishPlugin { } tasks.withType(Test).configureEach { - jvmArgs += "--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED" - jvmArgs += "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED" - jvmArgs += "--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED" - jvmArgs += "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" + jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED" + jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED" + jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED" + jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED" + jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED" + jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" } dependencies { diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java index 1e7ca1a6f..50dc5d008 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java @@ -75,7 +75,8 @@ private static Formatter createFormatter(Style style, boolean canChangeWhiteSpac @Override public boolean canFormat(@NotNull PsiFile file) { return JavaFileType.INSTANCE.equals(file.getFileType()) - && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled(); + && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled() + && JreConfigurationChecker.checkJreConfiguration(file.getProject()); } @Override diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java index 3a9a30f49..5b5175069 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java @@ -35,7 +35,8 @@ public class GoogleJavaFormatImportOptimizer implements ImportOptimizer { @Override public boolean supports(@NotNull PsiFile file) { return JavaFileType.INSTANCE.equals(file.getFileType()) - && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled(); + && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled() + && JreConfigurationChecker.checkJreConfiguration(file.getProject()); } @Override diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java index 1e92a4bdd..ad740b2fd 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java @@ -30,8 +30,14 @@ storages = {@Storage("google-java-format.xml")}) class GoogleJavaFormatSettings implements PersistentStateComponent { + private final Project project; + private State state = new State(); + GoogleJavaFormatSettings(Project project) { + this.project = project; + } + static GoogleJavaFormatSettings getInstance(Project project) { return ServiceManager.getService(project, GoogleJavaFormatSettings.class); } @@ -56,6 +62,9 @@ void setEnabled(boolean enabled) { } void setEnabled(EnabledState enabled) { + if (enabled.equals(EnabledState.ENABLED)) { + JreConfigurationChecker.checkJreConfiguration(project); + } state.enabled = enabled; } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java index 7cedbbec7..940def655 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java @@ -37,6 +37,8 @@ public void runActivity(@NotNull Project project) { if (settings.isUninitialized()) { settings.setEnabled(false); displayNewUserNotification(project, settings); + } else if (settings.isEnabled()) { + JreConfigurationChecker.checkJreConfiguration(project); } } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java new file mode 100644 index 000000000..bf8e6ce8f --- /dev/null +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java @@ -0,0 +1,102 @@ +/* + * Copyright 2023 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.googlejavaformat.intellij; + +import com.google.common.base.Suppliers; +import com.intellij.ide.ui.IdeUiService; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import java.util.function.Supplier; + +class JreConfigurationChecker { + + private final Supplier hasAccess = Suppliers.memoize(this::checkJreConfiguration); + + private final Project project; + private final Logger logger = Logger.getInstance(JreConfigurationChecker.class); + + public JreConfigurationChecker(Project project) { + this.project = project; + } + + static boolean checkJreConfiguration(Project project) { + return project.getService(JreConfigurationChecker.class).hasAccess.get(); + } + + /** + * Determine whether the JRE is configured to work with the google-java-format plugin. If not, + * display a notification with instructions and return false. + */ + private boolean checkJreConfiguration() { + try { + boolean hasAccess = + testClassAccess( + "com.sun.tools.javac.api.JavacTrees", + "com.sun.tools.javac.code.Flags", + "com.sun.tools.javac.file.JavacFileManager", + "com.sun.tools.javac.parser.JavacParser", + "com.sun.tools.javac.tree.JCTree", + "com.sun.tools.javac.util.Log"); + if (!hasAccess) { + displayConfigurationErrorNotification(); + } + return hasAccess; + } catch (ClassNotFoundException e) { + logger.error("Error checking jre configuration for google-java-format", e); + return false; + } + } + + private boolean testClassAccess(String... classNames) throws ClassNotFoundException { + for (String className : classNames) { + if (!testClassAccess(className)) { + return false; + } + } + return true; + } + + private boolean testClassAccess(String className) throws ClassNotFoundException { + Class klass = Class.forName(className); + return klass + .getModule() + // isExported returns true if the package is either open or exported. Either one is + // sufficient + // to run the google-java-format code (even though the documentation specifies --add-opens). + .isExported(klass.getPackageName(), getClass().getClassLoader().getUnnamedModule()); + } + + private void displayConfigurationErrorNotification() { + Notification notification = + new Notification( + "Configure JRE for google-java-format", + "Configure the JRE for google-java-format", + "The google-java-format plugin needs additional configuration before it can be used. " + + "Follow the instructions here.", + NotificationType.INFORMATION); + notification.setListener( + (n, e) -> { + IdeUiService.getInstance() + .browse( + "https://github.com/google/google-java-format/blob/master/README.md#intellij-jre-config"); + n.expire(); + }); + notification.notify(project); + } +} diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index f272ab26d..cd4009912 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -75,8 +75,11 @@ displayName="google-java-format Settings"/> + + From 1651dea8d2d55e4f3ba68c582b9f7f9f13127ff5 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Fri, 3 Mar 2023 12:10:34 -0800 Subject: [PATCH 204/379] Convert the gradle config to kotlin. I moved the description out of the Gradle config and into the XML. (It was just in the gradle so we could add the gjf version number, but that seems unnecessary since I changed the versioning so that the plugin version matches the gjf version.) I also updated the IntelliJ Gradle plugin to 1.13.1 because plugin publishing is broken in 1.13.0. PiperOrigin-RevId: 513888985 --- idea_plugin/build.gradle | 67 ------------------- idea_plugin/build.gradle.kts | 66 ++++++++++++++++++ .../src/main/resources/META-INF/plugin.xml | 7 ++ 3 files changed, 73 insertions(+), 67 deletions(-) delete mode 100644 idea_plugin/build.gradle create mode 100644 idea_plugin/build.gradle.kts diff --git a/idea_plugin/build.gradle b/idea_plugin/build.gradle deleted file mode 100644 index 3032dd54d..000000000 --- a/idea_plugin/build.gradle +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2017 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -plugins { - id "org.jetbrains.intellij" version "1.13.0" -} - -repositories { - mavenCentral() -} - -ext { - googleJavaFormatVersion = "1.16.0" -} - -apply plugin: "org.jetbrains.intellij" -apply plugin: "java" - -sourceCompatibility = JavaVersion.VERSION_11 -targetCompatibility = JavaVersion.VERSION_11 - -intellij { - pluginName = "google-java-format" - plugins = ["java"] - version = "2021.3" -} - -patchPluginXml { - pluginDescription = "Formats source code using the google-java-format tool. This version of " + - "the plugin uses version ${googleJavaFormatVersion} of the tool." - version.set("${googleJavaFormatVersion}.0") - sinceBuild = "213" - untilBuild = "" -} - -publishPlugin { - token = project.ext.properties.jetbrainsPluginRepoToken -} - -tasks.withType(Test).configureEach { - jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED" - jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED" - jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED" - jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED" - jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED" - jvmArgs += "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" -} - -dependencies { - implementation "com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}" - testImplementation "junit:junit:4.13.2" - testImplementation "com.google.truth:truth:1.1.3" - testImplementation "com.google.truth.extensions:truth-java8-extension:1.1.3" -} diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts new file mode 100644 index 000000000..46a697e8c --- /dev/null +++ b/idea_plugin/build.gradle.kts @@ -0,0 +1,66 @@ +/* + * Copyright 2017 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { id("org.jetbrains.intellij") version "1.13.1" } + +apply(plugin = "org.jetbrains.intellij") + +apply(plugin = "java") + +repositories { mavenCentral() } + +val googleJavaFormatVersion = "1.16.0" + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +intellij { + pluginName.set("google-java-format") + plugins.set(listOf("java")) + version.set("2021.3") +} + +tasks { + patchPluginXml { + version.set("${googleJavaFormatVersion}.0") + sinceBuild.set("213") + untilBuild.set("") + } + + publishPlugin { + val jetbrainsPluginRepoToken: String by project + token.set(jetbrainsPluginRepoToken) + } + + withType().configureEach { + jvmArgs( + "--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + ) + } +} + +dependencies { + implementation("com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}") + testImplementation("junit:junit:4.13.2") + testImplementation("com.google.truth:truth:1.1.3") +} diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index cd4009912..99b286db5 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -26,6 +26,13 @@ com.intellij.modules.lang com.intellij.modules.platform + + + This plugin requires additional IDE configuration. For more information, + read + the documentation. + ]]>
1.16.0.0
From 20527aa56f5068f921ca2110a3fb50d48bdb1c8a Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Mon, 6 Mar 2023 09:49:54 -0800 Subject: [PATCH 205/379] Update the `--add-exports` instructions. I don't really understand _why_ this works. I'm able to (easily) reproduce the problem by not including the `=` in my `idea64.options` file. But then if I copy/paste the command line out of `ps`, it works fine. And since it's easy enough to change this, I'm inclined to just do that? Fixes #908. PiperOrigin-RevId: 514440074 --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 376863fff..4fe0e2126 100644 --- a/README.md +++ b/README.md @@ -54,12 +54,12 @@ without extra configuration. To use the plugin, go to `Help→Edit Custom VM Options...` and paste in these lines: ``` ---add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED ``` Once you've done that, restart the IDE. @@ -105,12 +105,12 @@ following JVM flags are required when running on JDK 16 and newer, due to [JEP 396: Strongly Encapsulate JDK Internals by Default](https://openjdk.java.net/jeps/396): ``` ---add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED ---add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED ``` #### Maven From 1a0065696b4f408313dbd24f9d6606d758e98868 Mon Sep 17 00:00:00 2001 From: nickreid Date: Tue, 7 Mar 2023 13:06:49 -0800 Subject: [PATCH 206/379] Allow blank lines inserted before comments. Previously, blank lines could only be emitted before comments if they were there in the input. This was irrespective of BlankLineWanted.YES hints in the OpBuilder. These hints are already being set by some paths in GJF, so now that they're respected, blank lines will be added to some existing files. Eval in unknown commit PiperOrigin-RevId: 514817708 --- .../java/com/google/googlejavaformat/java/JavaOutput.java | 2 +- .../googlejavaformat/java/PartialFormattingTest.java | 1 + .../googlejavaformat/java/testdata/B27246427.output | 1 + .../google/googlejavaformat/java/testdata/Fields.input | 7 +++++++ .../google/googlejavaformat/java/testdata/Fields.output | 8 ++++++++ 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java index c43a91ad1..656b65c83 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java @@ -111,7 +111,7 @@ public void append(String text, Range range) { * there's a blank line here and it's a comment. */ BlankLineWanted wanted = blankLines.getOrDefault(lastK, BlankLineWanted.NO); - if (isComment(text) ? sawNewlines : wanted.wanted().orElse(sawNewlines)) { + if ((sawNewlines && isComment(text)) || wanted.wanted().orElse(sawNewlines)) { ++newlinesPending; } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/PartialFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/PartialFormattingTest.java index b1142b3b2..1750049d7 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/PartialFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/PartialFormattingTest.java @@ -679,6 +679,7 @@ public void noTokensOnLine() throws Exception { String input = lines( " package com.google.googlejavaformat.java;", + "", "/*", " * Copyright 2015 Google Inc.", " *", diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B27246427.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B27246427.output index b1e33e904..3d591f8f6 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B27246427.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B27246427.output @@ -6,6 +6,7 @@ enum TrailingComment { /** a */ Object a; + /** b */ Object b; } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Fields.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Fields.input index 9dc342663..d012d17a3 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Fields.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Fields.input @@ -1,5 +1,12 @@ class Fields { + int a = 1; + int b = 1; + + int c = 1; + /** Javadoc */ + int d = 1; + int x = 1; int y = 1; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Fields.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Fields.output index 376e8b620..81ebd2ac4 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Fields.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Fields.output @@ -1,5 +1,13 @@ class Fields { + int a = 1; + int b = 1; + + int c = 1; + + /** Javadoc */ + int d = 1; + int x = 1; int y = 1; From 4c1aeffc8b0ea3d4e18ffe21162b835f2c51cc3d Mon Sep 17 00:00:00 2001 From: nickreid Date: Fri, 10 Mar 2023 10:55:13 -0800 Subject: [PATCH 207/379] Make OpsBuilder::add public final PiperOrigin-RevId: 515682100 --- core/src/main/java/com/google/googlejavaformat/OpsBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java index db431c040..a45e83b9e 100644 --- a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java +++ b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java @@ -159,7 +159,7 @@ public BlankLineWanted merge(BlankLineWanted other) { int depth = 0; /** Add an {@link Op}, and record open/close ops for later validation of unclosed levels. */ - private void add(Op op) { + public final void add(Op op) { if (op instanceof OpenOp) { depth++; } else if (op instanceof CloseOp) { From 401d5c96946c856353a0edf83631f694303ae3ee Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Fri, 10 Mar 2023 13:22:52 -0800 Subject: [PATCH 208/379] Be louder about telling users they need to modify their IDE config to use gjf. Right now if your IDE isn't set up properly and you have gjf enabled in a project, you get a single warning. Any uses of the code formatter after that will instead use the built-in formatter. This is confusing to people who don't notice the notification. They think gjf is formatting their code strangely. Instead, let's warn on every single invocation of the formatter until they either fix the configuration issue or disable gjf in the project. Fixes #914 #919. PiperOrigin-RevId: 515722447 --- idea_plugin/build.gradle.kts | 4 +- .../GoogleJavaFormatFormattingService.java | 8 +++- .../GoogleJavaFormatImportOptimizer.java | 8 +++- .../intellij/JreConfigurationChecker.java | 40 ++++++++++--------- .../src/main/resources/META-INF/plugin.xml | 4 ++ 5 files changed, 39 insertions(+), 25 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 46a697e8c..a05b0cb93 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -plugins { id("org.jetbrains.intellij") version "1.13.1" } +plugins { id("org.jetbrains.intellij") version "1.13.2" } apply(plugin = "org.jetbrains.intellij") @@ -37,7 +37,7 @@ intellij { tasks { patchPluginXml { - version.set("${googleJavaFormatVersion}.0") + version.set("${googleJavaFormatVersion}.1") sinceBuild.set("213") untilBuild.set("") } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java index 50dc5d008..150a7391c 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java @@ -44,6 +44,11 @@ public class GoogleJavaFormatFormattingService extends AsyncDocumentFormattingSe @Override protected FormattingTask createFormattingTask(AsyncFormattingRequest request) { Project project = request.getContext().getProject(); + + if (!JreConfigurationChecker.checkJreConfiguration(project)) { + return null; + } + Style style = GoogleJavaFormatSettings.getInstance(project).getStyle(); Formatter formatter = createFormatter(style, request.canChangeWhitespaceOnly()); return new GoogleJavaFormatFormattingTask(formatter, request); @@ -75,8 +80,7 @@ private static Formatter createFormatter(Style style, boolean canChangeWhiteSpac @Override public boolean canFormat(@NotNull PsiFile file) { return JavaFileType.INSTANCE.equals(file.getFileType()) - && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled() - && JreConfigurationChecker.checkJreConfiguration(file.getProject()); + && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled(); } @Override diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java index 5b5175069..498c88526 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java @@ -35,13 +35,17 @@ public class GoogleJavaFormatImportOptimizer implements ImportOptimizer { @Override public boolean supports(@NotNull PsiFile file) { return JavaFileType.INSTANCE.equals(file.getFileType()) - && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled() - && JreConfigurationChecker.checkJreConfiguration(file.getProject()); + && GoogleJavaFormatSettings.getInstance(file.getProject()).isEnabled(); } @Override public @NotNull Runnable processFile(@NotNull PsiFile file) { Project project = file.getProject(); + + if (!JreConfigurationChecker.checkJreConfiguration(file.getProject())) { + return Runnables.doNothing(); + } + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); Document document = documentManager.getDocument(file); diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java index bf8e6ce8f..5084b6a39 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java @@ -26,44 +26,44 @@ class JreConfigurationChecker { - private final Supplier hasAccess = Suppliers.memoize(this::checkJreConfiguration); + private static final Supplier hasAccess = + Suppliers.memoize(JreConfigurationChecker::checkJreConfiguration); + private static final Logger logger = Logger.getInstance(JreConfigurationChecker.class); private final Project project; - private final Logger logger = Logger.getInstance(JreConfigurationChecker.class); public JreConfigurationChecker(Project project) { this.project = project; } static boolean checkJreConfiguration(Project project) { - return project.getService(JreConfigurationChecker.class).hasAccess.get(); + var success = hasAccess.get(); + if (!success) { + project.getService(JreConfigurationChecker.class).displayConfigurationErrorNotification(); + } + return success; } /** * Determine whether the JRE is configured to work with the google-java-format plugin. If not, * display a notification with instructions and return false. */ - private boolean checkJreConfiguration() { + private static boolean checkJreConfiguration() { try { - boolean hasAccess = - testClassAccess( - "com.sun.tools.javac.api.JavacTrees", - "com.sun.tools.javac.code.Flags", - "com.sun.tools.javac.file.JavacFileManager", - "com.sun.tools.javac.parser.JavacParser", - "com.sun.tools.javac.tree.JCTree", - "com.sun.tools.javac.util.Log"); - if (!hasAccess) { - displayConfigurationErrorNotification(); - } - return hasAccess; + return testClassAccess( + "com.sun.tools.javac.api.JavacTrees", + "com.sun.tools.javac.code.Flags", + "com.sun.tools.javac.file.JavacFileManager", + "com.sun.tools.javac.parser.JavacParser", + "com.sun.tools.javac.tree.JCTree", + "com.sun.tools.javac.util.Log"); } catch (ClassNotFoundException e) { logger.error("Error checking jre configuration for google-java-format", e); return false; } } - private boolean testClassAccess(String... classNames) throws ClassNotFoundException { + private static boolean testClassAccess(String... classNames) throws ClassNotFoundException { for (String className : classNames) { if (!testClassAccess(className)) { return false; @@ -72,14 +72,16 @@ private boolean testClassAccess(String... classNames) throws ClassNotFoundExcept return true; } - private boolean testClassAccess(String className) throws ClassNotFoundException { + private static boolean testClassAccess(String className) throws ClassNotFoundException { Class klass = Class.forName(className); return klass .getModule() // isExported returns true if the package is either open or exported. Either one is // sufficient // to run the google-java-format code (even though the documentation specifies --add-opens). - .isExported(klass.getPackageName(), getClass().getClassLoader().getUnnamedModule()); + .isExported( + klass.getPackageName(), + JreConfigurationChecker.class.getClassLoader().getUnnamedModule()); } private void displayConfigurationErrorNotification() { diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 99b286db5..d59c3c210 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,10 @@ ]]> +
1.16.0.1
+
When the plugin isn't configured correctly, show the error on every + format command. Previously it was only being shown at startup and going + unnoticed.
1.16.0.0
Updated to use google-java-format 1.16.0.
Use the new IDE formatting APIs for a simplified plugin.
From 25ce685ffbc1143f3e7d93c8655e8590cfaaf61b Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Mon, 3 Apr 2023 22:10:40 -0700 Subject: [PATCH 209/379] Remove AD_HOC_FORMATTING from the IntelliJ plugin. I have a feeling this is causing a lot of the issues people are seeing where it's constantly trying to reformat and failing because of syntax errors. Hopefully this will make it only try to reformat when a user specifically requests it. PiperOrigin-RevId: 521657519 --- idea_plugin/build.gradle.kts | 4 ++-- .../intellij/GoogleJavaFormatFormattingService.java | 2 +- .../googlejavaformat/intellij/GoogleJavaFormatSettings.java | 3 +-- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index a05b0cb93..474c24d79 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -plugins { id("org.jetbrains.intellij") version "1.13.2" } +plugins { id("org.jetbrains.intellij") version "1.13.3" } apply(plugin = "org.jetbrains.intellij") @@ -37,7 +37,7 @@ intellij { tasks { patchPluginXml { - version.set("${googleJavaFormatVersion}.1") + version.set("${googleJavaFormatVersion}.2") sinceBuild.set("213") untilBuild.set("") } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java index 150a7391c..9d2d7a595 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatFormattingService.java @@ -74,7 +74,7 @@ private static Formatter createFormatter(Style style, boolean canChangeWhiteSpac @Override public @NotNull Set getFeatures() { - return Set.of(Feature.AD_HOC_FORMATTING, Feature.FORMAT_FRAGMENTS, Feature.OPTIMIZE_IMPORTS); + return Set.of(Feature.FORMAT_FRAGMENTS, Feature.OPTIMIZE_IMPORTS); } @Override diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java index ad740b2fd..ee187c00d 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java @@ -18,7 +18,6 @@ import com.google.googlejavaformat.java.JavaFormatterOptions; import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.project.Project; @@ -39,7 +38,7 @@ class GoogleJavaFormatSettings implements PersistentStateComponent +
1.16.0.2
+
Disable AD_HOC_FORMATTING, which should stop the formatter from running so often when it wasn't specifically requested.
1.16.0.1
When the plugin isn't configured correctly, show the error on every format command. Previously it was only being shown at startup and going From 18f835849551f81d60d582300a0a3c585b5774b4 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 20 Apr 2023 09:56:25 -0700 Subject: [PATCH 210/379] Remove tests for handling of extra semi-colons javac no longer accepts these, see https://bugs.openjdk.org/browse/JDK-8027682 PiperOrigin-RevId: 525775880 --- .../google/googlejavaformat/java/testdata/B28788559.input | 7 ------- .../googlejavaformat/java/testdata/B28788559.output | 8 -------- .../googlejavaformat/java/testdata/CL240367479.input | 6 ------ .../googlejavaformat/java/testdata/CL240367479.output | 6 ------ 4 files changed, 27 deletions(-) delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B28788559.input delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B28788559.output delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/CL240367479.input delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/CL240367479.output diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B28788559.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B28788559.input deleted file mode 100644 index a38d10b73..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B28788559.input +++ /dev/null @@ -1,7 +0,0 @@ -import a.A;; -import b.B; - -class Test { - A a; - B b; -} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B28788559.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B28788559.output deleted file mode 100644 index 8a1db808f..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B28788559.output +++ /dev/null @@ -1,8 +0,0 @@ -import a.A; -; -import b.B; - -class Test { - A a; - B b; -} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/CL240367479.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/CL240367479.input deleted file mode 100644 index be76390d7..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/CL240367479.input +++ /dev/null @@ -1,6 +0,0 @@ -package foo;; - -import com.google.second.Foo; -import com.google.first.Bar; - -public class Blim {} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/CL240367479.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/CL240367479.output deleted file mode 100644 index 025d2370e..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/CL240367479.output +++ /dev/null @@ -1,6 +0,0 @@ -package foo; -; -import com.google.second.Foo; -import com.google.first.Bar; - -public class Blim {} From 4eb2a4da83d3929842263fed4fb50d9f4fa73ad7 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 26 Jul 2023 18:14:02 -0700 Subject: [PATCH 211/379] Update Guava version https://github.com/google/google-java-format/issues/950 PiperOrigin-RevId: 551370402 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 243da54d3..1fe2803eb 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ UTF-8 1.8 - 31.1-jre + 32.1.1-jre 1.1.3 3.21.2 2.16 From 4ebb6f5a00d0f933dcc68ad8673e740700fcf436 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sun, 6 Aug 2023 09:31:43 -0700 Subject: [PATCH 212/379] Update ci.yml Update latest STS from 19 to 20, add 22-ea --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 716abcc07..3b735636a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,22 +29,22 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest ] - java: [ 19, 17, 11 ] + java: [ 20, 17, 11 ] experimental: [ false ] include: # Only test on macos and windows with a single recent JDK to avoid a # combinatorial explosion of test configurations. - os: macos-latest - java: 19 + java: 20 experimental: false - os: windows-latest - java: 19 + java: 20 experimental: false - os: ubuntu-latest - java: 20-ea + java: 21-ea experimental: true - os: ubuntu-latest - java: 21-ea + java: 22-ea experimental: true runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} From 28b199c54957bb10d203bb5d7a0e3ed82603f5e8 Mon Sep 17 00:00:00 2001 From: Christopher Ng Date: Wed, 6 Sep 2023 11:23:56 -0700 Subject: [PATCH 213/379] Fix `java.lang.RuntimeException: Document is locked by write PSI operations` errors Also update to `google-java-format` 1.17.0 Fixes #960 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/960 from facboy:master e0925a2e7d7c94e84a1c1fd6bb95ff9ca1b66c79 PiperOrigin-RevId: 563163224 --- idea_plugin/build.gradle.kts | 18 ++++++------ .../GoogleJavaFormatImportOptimizer.java | 28 ++++++++++++++++--- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 474c24d79..0aec5a7b6 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -plugins { id("org.jetbrains.intellij") version "1.13.3" } +plugins { id("org.jetbrains.intellij") version "1.15.0" } apply(plugin = "org.jetbrains.intellij") @@ -22,7 +22,7 @@ apply(plugin = "java") repositories { mavenCentral() } -val googleJavaFormatVersion = "1.16.0" +val googleJavaFormatVersion = "1.17.0" java { sourceCompatibility = JavaVersion.VERSION_11 @@ -37,7 +37,7 @@ intellij { tasks { patchPluginXml { - version.set("${googleJavaFormatVersion}.2") + version.set("${googleJavaFormatVersion}.0") sinceBuild.set("213") untilBuild.set("") } @@ -49,12 +49,12 @@ tasks { withType().configureEach { jvmArgs( - "--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", - "--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", ) } } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java index 498c88526..bad03457a 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java @@ -55,16 +55,36 @@ public boolean supports(@NotNull PsiFile file) { JavaFormatterOptions.Style style = GoogleJavaFormatSettings.getInstance(project).getStyle(); + final String origText = document.getText(); String text; try { - text = - ImportOrderer.reorderImports( - RemoveUnusedImports.removeUnusedImports(document.getText()), style); + text = ImportOrderer.reorderImports(RemoveUnusedImports.removeUnusedImports(origText), style); } catch (FormatterException e) { Notifications.displayParsingErrorNotification(project, file.getName()); return Runnables.doNothing(); } - return () -> document.setText(text); + /* pointless to change document text if it hasn't changed, plus this can interfere with + e.g. GoogleJavaFormattingService's output, i.e. it can overwrite the results from the main + formatter. */ + if (text.equals(origText)) { + return Runnables.doNothing(); + } + + return () -> { + if (documentManager.isDocumentBlockedByPsi(document)) { + documentManager.doPostponedOperationsAndUnblockDocument(document); + } + + /* similarly to above, don't overwrite new document text if it has changed - we use + getCharsSequence() as we should have `writeAction()` (which I think means effectively a + write-lock) and it saves calling getText(), which apparently is expensive. */ + CharSequence newText = document.getCharsSequence(); + if (CharSequence.compare(origText, newText) != 0) { + return; + } + + document.setText(text); + }; } } From 9f2cd6827d016a3b55b7f9f39e054a69b0deb168 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 6 Sep 2023 12:25:02 -0700 Subject: [PATCH 214/379] Make google-java-format friendlier to TSAN This code does deliberate racy initialization of some memoized values, and there is a static final instance of the `Space` subclass that ends up being shared across multiple threads. Tested: sponge/1777b644-2dd8-420b-ad06-b4f17c893d8f PiperOrigin-RevId: 563181626 --- .../java/com/google/googlejavaformat/Doc.java | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Doc.java b/core/src/main/java/com/google/googlejavaformat/Doc.java index d638ddb40..e755bc67e 100644 --- a/core/src/main/java/com/google/googlejavaformat/Doc.java +++ b/core/src/main/java/com/google/googlejavaformat/Doc.java @@ -19,6 +19,7 @@ import static java.lang.Math.max; import com.google.common.base.MoreObjects; +import com.google.common.base.Suppliers; import com.google.common.collect.DiscreteDomain; import com.google.common.collect.Iterators; import com.google.common.collect.Range; @@ -26,6 +27,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.function.Supplier; /** * {@link com.google.googlejavaformat.java.JavaInputAstVisitor JavaInputAstVisitor} outputs a @@ -102,16 +104,13 @@ public String toString() { private static final DiscreteDomain INTEGERS = DiscreteDomain.integers(); // Memoized width; Float.POSITIVE_INFINITY if contains forced breaks. - private boolean widthComputed = false; - private float width = 0.0F; + private final Supplier width = Suppliers.memoize(this::computeWidth); // Memoized flat; not defined (and never computed) if contains forced breaks. - private boolean flatComputed = false; - private String flat = ""; + private final Supplier flat = Suppliers.memoize(this::computeFlat); // Memoized Range. - private boolean rangeComputed = false; - private Range range = EMPTY_RANGE; + private final Supplier> range = Suppliers.memoize(this::computeRange); /** * Return the width of a {@code Doc}, or {@code Float.POSITIVE_INFINITY} if it must be broken. @@ -119,11 +118,7 @@ public String toString() { * @return the width */ final float getWidth() { - if (!widthComputed) { - width = computeWidth(); - widthComputed = true; - } - return width; + return width.get(); } /** @@ -133,11 +128,7 @@ final float getWidth() { * @return the flat-string value */ final String getFlat() { - if (!flatComputed) { - flat = computeFlat(); - flatComputed = true; - } - return flat; + return flat.get(); } /** @@ -146,11 +137,7 @@ final String getFlat() { * @return the {@code Doc}'s {@link Range} */ final Range range() { - if (!rangeComputed) { - range = computeRange(); - rangeComputed = true; - } - return range; + return range.get(); } /** From 915b78fb245aba6fa8236c2e8c928f5d91a73295 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Thu, 7 Sep 2023 08:31:10 -0700 Subject: [PATCH 215/379] Update the release notes for the IntelliJ plugin. (Also updated a dependency and tweaked the comment formatting.) PiperOrigin-RevId: 563439879 --- idea_plugin/build.gradle.kts | 2 +- .../intellij/GoogleJavaFormatImportOptimizer.java | 12 ++++++------ idea_plugin/src/main/resources/META-INF/plugin.xml | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 0aec5a7b6..5e965823f 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -62,5 +62,5 @@ tasks { dependencies { implementation("com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}") testImplementation("junit:junit:4.13.2") - testImplementation("com.google.truth:truth:1.1.3") + testImplementation("com.google.truth:truth:1.1.5") } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java index bad03457a..425124219 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatImportOptimizer.java @@ -64,9 +64,9 @@ public boolean supports(@NotNull PsiFile file) { return Runnables.doNothing(); } - /* pointless to change document text if it hasn't changed, plus this can interfere with - e.g. GoogleJavaFormattingService's output, i.e. it can overwrite the results from the main - formatter. */ + // pointless to change document text if it hasn't changed, plus this can interfere with + // e.g. GoogleJavaFormattingService's output, i.e. it can overwrite the results from the main + // formatter. if (text.equals(origText)) { return Runnables.doNothing(); } @@ -76,9 +76,9 @@ public boolean supports(@NotNull PsiFile file) { documentManager.doPostponedOperationsAndUnblockDocument(document); } - /* similarly to above, don't overwrite new document text if it has changed - we use - getCharsSequence() as we should have `writeAction()` (which I think means effectively a - write-lock) and it saves calling getText(), which apparently is expensive. */ + // similarly to above, don't overwrite new document text if it has changed - we use + // getCharsSequence() as we should have `writeAction()` (which I think means effectively a + // write-lock) and it saves calling getText(), which apparently is expensive. CharSequence newText = document.getCharsSequence(); if (CharSequence.compare(origText, newText) != 0) { return; diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 42011a208..1b1e67ffa 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,9 @@ ]]> +
1.17.0.0
+
Updated to use google-java-format 1.17.0.
+
Fixed "Document is locked" errors (Thanks, @facboy!)
1.16.0.2
Disable AD_HOC_FORMATTING, which should stop the formatter from running so often when it wasn't specifically requested.
1.16.0.1
From d0e44e5d6120dfab4f4833dc4331986d726a2ce1 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 7 Sep 2023 08:57:02 -0700 Subject: [PATCH 216/379] Follow-up to https://github.com/google/google-java-format/commit/9f2cd6827d016a3b55b7f9f39e054a69b0deb168 Use `com.google.common.base.Supplier`, for compatibility with clients that are using the Android version of Guava. Fixes e.g. ``` Exception in thread "main" java.lang.IncompatibleClassChangeError: Class com.google.common.base.Suppliers$NonSerializableMemoizingSupplier does not implement the requested interface java.util.function.Supplier ``` PiperOrigin-RevId: 563446857 --- core/src/main/java/com/google/googlejavaformat/Doc.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Doc.java b/core/src/main/java/com/google/googlejavaformat/Doc.java index e755bc67e..cab688558 100644 --- a/core/src/main/java/com/google/googlejavaformat/Doc.java +++ b/core/src/main/java/com/google/googlejavaformat/Doc.java @@ -19,6 +19,7 @@ import static java.lang.Math.max; import com.google.common.base.MoreObjects; +import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.collect.DiscreteDomain; import com.google.common.collect.Iterators; @@ -27,7 +28,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.function.Supplier; /** * {@link com.google.googlejavaformat.java.JavaInputAstVisitor JavaInputAstVisitor} outputs a From 1fe678942551b446d589c0fe0ad5319ccf17ffa3 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 12 Sep 2023 07:03:59 -0700 Subject: [PATCH 217/379] Handle `final var` lambda variables The start position of `final` variable is apparently after the token for `final`, this works around that by inlining a call to `visitVariable` and dropping the `sync` call that asserts the start position of the current node matches the next token. Fixes https://github.com/google/google-java-format/issues/959 PiperOrigin-RevId: 564710136 --- .../google/googlejavaformat/java/JavaInputAstVisitor.java | 5 ++++- .../com/google/googlejavaformat/java/testdata/I959.input | 5 +++++ .../com/google/googlejavaformat/java/testdata/I959.output | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I959.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I959.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 394d396d9..89c944c5b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -1250,7 +1250,10 @@ public Void visitLambdaExpression(LambdaExpressionTree node, Void unused) { token(","); builder.breakOp(" "); } - scan(parameter, null); + visitVariables( + ImmutableList.of(parameter), + DeclarationKind.NONE, + fieldAnnotationDirection(parameter.getModifiers())); first = false; } if (parens) { diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I959.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I959.input new file mode 100644 index 000000000..0660079d7 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I959.input @@ -0,0 +1,5 @@ +class I959 { + public void test() { + new File(".").listFiles((final var dir, final var name) -> true); + } +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I959.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I959.output new file mode 100644 index 000000000..76a07f48b --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I959.output @@ -0,0 +1,5 @@ +class I959 { + public void test() { + new File(".").listFiles((final var dir, final var name) -> true); + } +} From 4ade3471b7978af553f425bfc28b36c425e12a67 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 21 Sep 2023 08:44:47 -0700 Subject: [PATCH 218/379] Update ci.yml for JDK 21 release --- .github/workflows/ci.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b735636a..8018665aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,20 +29,17 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest ] - java: [ 20, 17, 11 ] + java: [ 21, 17, 11 ] experimental: [ false ] include: # Only test on macos and windows with a single recent JDK to avoid a # combinatorial explosion of test configurations. - os: macos-latest - java: 20 + java: 21 experimental: false - os: windows-latest - java: 20 + java: 21 experimental: false - - os: ubuntu-latest - java: 21-ea - experimental: true - os: ubuntu-latest java: 22-ea experimental: true From c47ebbb6207e412d012a2a65e2ce5ee679902997 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 29 Sep 2023 17:44:09 -0700 Subject: [PATCH 219/379] Update ci.yml --- .github/workflows/ci.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8018665aa..ee1174dfb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: java: 21 experimental: false - os: ubuntu-latest - java: 22-ea + java: EA experimental: true runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} @@ -52,7 +52,15 @@ jobs: access_token: ${{ github.token }} - name: 'Check out repository' uses: actions/checkout@v2 + - name: 'Set up JDK ${{ matrix.java }} from jdk.java.net' + if: ${{ matrix.java == 'EA' }} + uses: oracle-actions/setup-java@v1 + with: + website: jdk.java.net + release: ${{ matrix.java }} + cache: 'maven' - name: 'Set up JDK ${{ matrix.java }}' + if: ${{ matrix.java != 'EA' }} uses: actions/setup-java@v2 with: java-version: ${{ matrix.java }} From b4eade8a9cd8599d551829b16ca5afeb9f2b86e2 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 4 Oct 2023 17:36:31 -0700 Subject: [PATCH 220/379] Update release.yml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6e72789c7..211290671 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: run: | mvn --no-transfer-progress versions:set versions:commit -DnewVersion="${{ github.event.inputs.version }}" mvn tycho-versions:update-eclipse-metadata -pl eclipse_plugin - git ls-files | grep 'pom.xml$' | xargs git add + git ls-files | grep -E '(pom.xml|MANIFEST.MF)$' | xargs git add git config --global user.email "${{ github.actor }}@users.noreply.github.com" git config --global user.name "${{ github.actor }}" git commit -m "Release google-java-format ${{ github.event.inputs.version }}" From 685a6c9ebd43aab9ef458379de7d3883bfee970f Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 4 Oct 2023 19:16:12 -0700 Subject: [PATCH 221/379] Update release.yml --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 211290671..3176f73c6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,7 @@ jobs: - name: Bump Version Number run: | mvn --no-transfer-progress versions:set versions:commit -DnewVersion="${{ github.event.inputs.version }}" + mvn --no-transfer-progress versions:set versions:commit -DnewVersion="${{ github.event.inputs.version }}" -pl eclipse_plugin mvn tycho-versions:update-eclipse-metadata -pl eclipse_plugin git ls-files | grep -E '(pom.xml|MANIFEST.MF)$' | xargs git add git config --global user.email "${{ github.actor }}@users.noreply.github.com" From 295e7a43f8a84d31c9e39fd853c8c4e52f586240 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 27 Oct 2023 11:00:13 -0700 Subject: [PATCH 222/379] Don't try to reflow text blocks Fixes https://github.com/google/google-java-format/issues/976 PiperOrigin-RevId: 577249036 --- .../googlejavaformat/java/StringWrapper.java | 5 +++++ .../java/StringWrapperTest.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index d801c9b86..f241ae47f 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -15,6 +15,7 @@ package com.google.googlejavaformat.java; import static com.google.common.collect.Iterables.getLast; +import static java.lang.Math.min; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.stream.Collectors.joining; @@ -122,6 +123,10 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) { if (literalTree.getKind() != Kind.STRING_LITERAL) { return null; } + int pos = getStartPosition(literalTree); + if (input.substring(pos, min(input.length(), pos + 3)).equals("\"\"\"")) { + return null; + } Tree parent = getCurrentPath().getParentPath().getLeaf(); if (parent instanceof MemberSelectTree && ((MemberSelectTree) parent).getExpression().equals(literalTree)) { diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java index 99e1b2fc5..f7be369f1 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -15,6 +15,7 @@ package com.google.googlejavaformat.java; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assume.assumeTrue; import com.google.common.base.Joiner; import org.junit.Test; @@ -52,6 +53,26 @@ public void testAwkwardLineEndWrapping() throws Exception { assertThat(StringWrapper.wrap(100, input, new Formatter())).isEqualTo(output); } + @Test + public void textBlock() throws Exception { + assumeTrue(Runtime.version().feature() >= 15); + String input = + lines( + "package com.mypackage;", + "public class ReproBug {", + " private String myString;", + " private ReproBug() {", + " String str =", + " \"\"\"", + " " + + " {\"sourceEndpoint\":\"ri.something.1-1.object-internal.1\",\"targetEndpoint\":\"ri.some" + + "thing.1-1.object-internal.2\",\"typeId\":\"typeId\"}\"\"\";", + " myString = str;", + " }", + "}"); + assertThat(StringWrapper.wrap(100, input, new Formatter())).isEqualTo(input); + } + private static String lines(String... line) { return Joiner.on('\n').join(line) + '\n'; } From 53390d99b56edae23cfab5adcafd7df28d9984c8 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 30 Oct 2023 08:22:01 -0700 Subject: [PATCH 223/379] Handle type annotations on method reference qualifiers e.g. ``` Supplier> a = @A(0x45) ArrayList::new; Supplier> b = @A(0x46) ImmutableList::of; ``` The necessary logic is already there, but the start position information for the method reference doesn't include the leading type annotations, which was resulting in an assertion to fail. PiperOrigin-RevId: 577850593 --- .../java/JavaInputAstVisitor.java | 1 - .../java/testdata/B308157568.input | 23 +++++++++++++++++++ .../java/testdata/B308157568.output | 23 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B308157568.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B308157568.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 89c944c5b..5a75afa0e 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -930,7 +930,6 @@ public boolean visitEnumDeclaration(ClassTree node) { @Override public Void visitMemberReference(MemberReferenceTree node, Void unused) { - sync(node); builder.open(plusFour); scan(node.getQualifierExpression(), null); builder.breakOp(); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B308157568.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B308157568.input new file mode 100644 index 000000000..089a3f1e8 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B308157568.input @@ -0,0 +1,23 @@ +class C { + @A(0x14) + int f(Object o) { + @A(0x40) + int local; + try (@A(0x41) + JarFile jarFile = new JarFile("hello.jar")) { + } catch ( + @A(0x42) + IOException e) { + } + if (o instanceof @A(0x43) String) {} + new @A(0x44) ArrayList<>(); + Supplier> a = @A(0x45) ArrayList::new; + Supplier> b = @A(0x46) ImmutableList::of; + String s = (@A(0x47) String) o; + List xs = new ArrayList<@A(0x48) String>(); + xs = ImmutableList.<@A(0x49) String>of(); + Supplier> c = ArrayList<@A(0x4A) String>::new; + Supplier> d = ImmutableList::<@A(0x4B) String>of; + return 0; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B308157568.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B308157568.output new file mode 100644 index 000000000..089a3f1e8 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B308157568.output @@ -0,0 +1,23 @@ +class C { + @A(0x14) + int f(Object o) { + @A(0x40) + int local; + try (@A(0x41) + JarFile jarFile = new JarFile("hello.jar")) { + } catch ( + @A(0x42) + IOException e) { + } + if (o instanceof @A(0x43) String) {} + new @A(0x44) ArrayList<>(); + Supplier> a = @A(0x45) ArrayList::new; + Supplier> b = @A(0x46) ImmutableList::of; + String s = (@A(0x47) String) o; + List xs = new ArrayList<@A(0x48) String>(); + xs = ImmutableList.<@A(0x49) String>of(); + Supplier> c = ArrayList<@A(0x4A) String>::new; + Supplier> d = ImmutableList::<@A(0x4B) String>of; + return 0; + } +} From 205b85f2315c48b2d6280a18c6ea9dbe814d3709 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Thu, 30 Nov 2023 13:11:50 -0800 Subject: [PATCH 224/379] Add javax.tools.Tool implementation for google-java-format. PiperOrigin-RevId: 586765411 --- .../java/GoogleJavaFormatTool.java | 53 +++++++++++++++ .../java/GoogleJavaFormatToolProvider.java | 5 +- .../google/googlejavaformat/java/Main.java | 23 +++++-- .../GoogleJavaFormatToolProviderTest.java | 2 +- .../java/GoogleJavaFormatToolTest.java | 65 +++++++++++++++++++ 5 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatTool.java create mode 100644 core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java diff --git a/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatTool.java b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatTool.java new file mode 100644 index 000000000..3c315aaf1 --- /dev/null +++ b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatTool.java @@ -0,0 +1,53 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java; + +import static com.google.common.collect.Sets.toImmutableEnumSet; + +import com.google.auto.service.AutoService; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Set; +import javax.lang.model.SourceVersion; +import javax.tools.Tool; + +/** Provide a way to be invoked without necessarily starting a new VM. */ +@AutoService(Tool.class) +public class GoogleJavaFormatTool implements Tool { + @Override + public String name() { + return "google-java-format"; + } + + @Override + public Set getSourceVersions() { + return Arrays.stream(SourceVersion.values()).collect(toImmutableEnumSet()); + } + + @Override + public int run(InputStream in, OutputStream out, OutputStream err, String... args) { + PrintStream outStream = new PrintStream(out); + PrintStream errStream = new PrintStream(err); + try { + return Main.main(in, outStream, errStream, args); + } catch (RuntimeException e) { + errStream.print(e.getMessage()); + errStream.flush(); + return 1; // pass non-zero value back indicating an error has happened + } + } +} diff --git a/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java index 7bcad4cc5..438eac596 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java +++ b/core/src/main/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProvider.java @@ -29,10 +29,11 @@ public String name() { @Override public int run(PrintWriter out, PrintWriter err, String... args) { try { - return Main.main(out, err, args); + return Main.main(System.in, out, err, args); } catch (RuntimeException e) { err.print(e.getMessage()); - return -1; // pass non-zero value back indicating an error has happened + err.flush(); + return 1; // pass non-zero value back indicating an error has happened } } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 62423f226..0845e0ec2 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -26,6 +26,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; +import java.io.PrintStream; import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; @@ -66,20 +67,28 @@ public Main(PrintWriter outWriter, PrintWriter errWriter, InputStream inStream) * * @param args the command-line arguments */ - public static void main(String[] args) { - PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out, UTF_8)); - PrintWriter err = new PrintWriter(new OutputStreamWriter(System.err, UTF_8)); - int result = main(out, err, args); + public static void main(String... args) { + int result = main(System.in, System.out, System.err, args); System.exit(result); } /** - * Package-private main entry point used this CLI program and the java.util.spi.ToolProvider + * Package-private main entry point used by the {@link javax.tools.Tool Tool} implementation in + * the same package as this Main class. + */ + static int main(InputStream in, PrintStream out, PrintStream err, String... args) { + PrintWriter outWriter = new PrintWriter(new OutputStreamWriter(out, UTF_8)); + PrintWriter errWriter = new PrintWriter(new OutputStreamWriter(err, UTF_8)); + return main(in, outWriter, errWriter, args); + } + + /** + * Package-private main entry point used by the {@link java.util.spi.ToolProvider ToolProvider} * implementation in the same package as this Main class. */ - static int main(PrintWriter out, PrintWriter err, String... args) { + static int main(InputStream in, PrintWriter out, PrintWriter err, String... args) { try { - Main formatter = new Main(out, err, System.in); + Main formatter = new Main(out, err, in); return formatter.format(args); } catch (UsageException e) { err.print(e.getMessage()); diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java index d060fef1f..3d41a0733 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java @@ -46,7 +46,7 @@ public void testUsageOutputAfterLoadingViaToolName() { int result = format.run(new PrintWriter(out, true), new PrintWriter(err, true), "--help"); - assertThat(result).isEqualTo(2); + assertThat(result).isNotEqualTo(0); String usage = err.toString(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java new file mode 100644 index 000000000..691bb2234 --- /dev/null +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2021 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth8.assertThat; +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.ServiceLoader; +import javax.tools.Tool; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for {@link GoogleJavaFormatToolProvider}. */ +@RunWith(JUnit4.class) +public class GoogleJavaFormatToolTest { + + @Test + public void testUsageOutputAfterLoadingViaToolName() { + String name = "google-java-format"; + + assertThat( + ServiceLoader.load(Tool.class).stream() + .map(ServiceLoader.Provider::get) + .map(Tool::name)) + .contains(name); + + Tool format = + ServiceLoader.load(Tool.class).stream() + .filter(provider -> name.equals(provider.get().name())) + .findFirst() + .get() + .get(); + + InputStream in = new ByteArrayInputStream(new byte[0]); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayOutputStream err = new ByteArrayOutputStream(); + + int result = format.run(in, out, err, "--help"); + + assertThat(result).isNotEqualTo(0); + + String usage = new String(err.toByteArray(), UTF_8); + + // Check that doc links are included. + assertThat(usage).containsMatch("http.*/google-java-format"); + assertThat(usage).contains("Usage: google-java-format"); + } +} From ad771541474eebceb2c6666cb61d4836bf6d8560 Mon Sep 17 00:00:00 2001 From: Goooler Date: Thu, 7 Dec 2023 09:50:25 -0800 Subject: [PATCH 225/379] Bump Guava to 32.1.3 There is an issue about resolving transitive dependencies in Guava breaks GJF 1.18.1 integration in [Spotless](https://github.com/diffplug/spotless), which has been fixed in Guava 32.1.3, it would be nice to follow this update. See: - https://github.com/google/guava/issues/6657. - https://github.com/google/guava/releases/tag/v32.1.3. Fixes #996 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/996 from Goooler:bump-guava 1e5ed85f3daa885a90a4d375918ed382e176f5c9 PiperOrigin-RevId: 588824173 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1fe2803eb..8b3ca51cd 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ UTF-8 1.8 - 32.1.1-jre + 32.1.3-jre 1.1.3 3.21.2 2.16 From b86c508be5f42e7ed0d55cd1abe2c04d2db66676 Mon Sep 17 00:00:00 2001 From: CK Date: Thu, 7 Dec 2023 14:38:12 -0800 Subject: [PATCH 226/379] Add support for guard clauses in Java 21 switch expressions This PR adds support for `switch` statements where a `case` has a guard clause. See Issue #983 Fixes #988 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/988 from TheCK:master 4771486db7d8aab84eb4ecf8e68af2612d0c2b5c PiperOrigin-RevId: 588913297 --- core/pom.xml | 29 ++++++++++++++- .../googlejavaformat/java/Formatter.java | 30 ++++++++++------ .../java/java17/Java17InputAstVisitor.java | 14 ++++++++ .../java/java21/Java21InputAstVisitor.java | 36 +++++++++++++++++++ .../java/FormatterIntegrationTest.java | 1 + .../java/testdata/SwitchGuardClause.input | 9 +++++ .../java/testdata/SwitchGuardClause.output | 9 +++++ 7 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output diff --git a/core/pom.xml b/core/pom.xml index 038e4eda6..d1363fed1 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -226,7 +226,7 @@ jdk11 - (,17) + [11,17) @@ -236,6 +236,7 @@ **/Java17InputAstVisitor.java + **/Java21InputAstVisitor.java @@ -243,6 +244,32 @@ maven-javadoc-plugin com.google.googlejavaformat.java.java17 + com.google.googlejavaformat.java.java21 + + + + + + + jdk17 + + [17,21) + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + **/Java21InputAstVisitor.java + + + + + maven-javadoc-plugin + + com.google.googlejavaformat.java.java21 diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index 9ff702d5a..5aa7a1233 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -151,16 +151,14 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept OpsBuilder builder = new OpsBuilder(javaInput, javaOutput); // Output the compilation unit. JavaInputAstVisitor visitor; - if (Runtime.version().feature() >= 17) { - try { - visitor = - Class.forName("com.google.googlejavaformat.java.java17.Java17InputAstVisitor") - .asSubclass(JavaInputAstVisitor.class) - .getConstructor(OpsBuilder.class, int.class) - .newInstance(builder, options.indentationMultiplier()); - } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); - } + if (Runtime.version().feature() >= 21) { + visitor = + createVisitor( + "com.google.googlejavaformat.java.java21.Java21InputAstVisitor", builder, options); + } else if (Runtime.version().feature() >= 17) { + visitor = + createVisitor( + "com.google.googlejavaformat.java.java17.Java17InputAstVisitor", builder, options); } else { visitor = new JavaInputAstVisitor(builder, options.indentationMultiplier()); } @@ -173,6 +171,18 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept javaOutput.flush(); } + private static JavaInputAstVisitor createVisitor( + final String className, final OpsBuilder builder, final JavaFormatterOptions options) { + try { + return Class.forName(className) + .asSubclass(JavaInputAstVisitor.class) + .getConstructor(OpsBuilder.class, int.class) + .newInstance(builder, options.indentationMultiplier()); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } + static boolean errorDiagnostic(Diagnostic input) { if (input.getKind() != Diagnostic.Kind.ERROR) { return false; diff --git a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java index a0561e2fe..97bb2ffe5 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java @@ -29,6 +29,7 @@ import com.sun.source.tree.CaseTree; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.InstanceOfTree; import com.sun.source.tree.ModifiersTree; import com.sun.source.tree.ModuleTree; @@ -238,6 +239,15 @@ public Void visitCase(CaseTree node, Void unused) { } builder.close(); } + + final ExpressionTree guard = getGuard(node); + if (guard != null) { + builder.space(); + token("when"); + builder.space(); + scan(guard, null); + } + switch (node.getCaseKind()) { case STATEMENT: token(":"); @@ -267,4 +277,8 @@ public Void visitCase(CaseTree node, Void unused) { } return null; } + + protected ExpressionTree getGuard(final CaseTree node) { + return null; + } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java new file mode 100644 index 000000000..a96ef99e2 --- /dev/null +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -0,0 +1,36 @@ +/* + * Copyright 2023 The google-java-format Authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java.java21; + +import com.google.googlejavaformat.OpsBuilder; +import com.google.googlejavaformat.java.java17.Java17InputAstVisitor; +import com.sun.source.tree.CaseTree; +import com.sun.source.tree.ExpressionTree; + +/** + * Extends {@link Java17InputAstVisitor} with support for AST nodes that were added or modified in + * Java 21. + */ +public class Java21InputAstVisitor extends Java17InputAstVisitor { + + public Java21InputAstVisitor(OpsBuilder builder, int indentMultiplier) { + super(builder, indentMultiplier); + } + + @Override + protected ExpressionTree getGuard(final CaseTree node) { + return node.getGuard(); + } +} diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 61a43468a..688b24d8e 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -52,6 +52,7 @@ public class FormatterIntegrationTest { .putAll(15, "I603") .putAll(16, "I588") .putAll(17, "I683", "I684", "I696") + .putAll(21, "SwitchGuardClause") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input new file mode 100644 index 000000000..25df58096 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input @@ -0,0 +1,9 @@ +class SwitchGuardClause { + boolean test(Object x) { + return switch (x) { + case String s when s.length() < 5 -> true; + case Integer i -> false; + default -> true; + }; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output new file mode 100644 index 000000000..25df58096 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output @@ -0,0 +1,9 @@ +class SwitchGuardClause { + boolean test(Object x) { + return switch (x) { + case String s when s.length() < 5 -> true; + case Integer i -> false; + default -> true; + }; + } +} From 430ba3b0e237b746157a3392663da4b4bb7c733d Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 8 Dec 2023 08:33:22 -0800 Subject: [PATCH 227/379] Initial support for pattern matching in switches Fixes https://github.com/google/google-java-format/issues/937, https://github.com/google/google-java-format/issues/880 PiperOrigin-RevId: 589140113 --- .../java/java17/Java17InputAstVisitor.java | 17 ++++++- .../java/java21/Java21InputAstVisitor.java | 43 +++++++++++++++++ .../java/FormatterIntegrationTest.java | 5 +- .../googlejavaformat/java/testdata/I880.input | 19 ++++++++ .../java/testdata/I880.output | 21 +++++++++ .../java/testdata/SwitchDouble.input | 7 +++ .../java/testdata/SwitchDouble.output | 7 +++ .../java/testdata/SwitchRecord.input | 21 +++++++++ .../java/testdata/SwitchRecord.output | 46 +++++++++++++++++++ .../java/testdata/SwitchUnderscore.input | 8 ++++ .../java/testdata/SwitchUnderscore.output | 8 ++++ 11 files changed, 198 insertions(+), 4 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I880.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I880.output create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchDouble.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchDouble.output create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchRecord.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchRecord.output create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchUnderscore.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchUnderscore.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java index 97bb2ffe5..6818f4a03 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java @@ -83,6 +83,7 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { } private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) { + builder.open(plusFour); if (modifiers != null) { List annotations = visitModifiers(modifiers, Direction.HORIZONTAL, Optional.empty()); @@ -90,7 +91,12 @@ private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) } scan(type, null); builder.breakOp(" "); - visit(name); + if (name.isEmpty()) { + token("_"); + } else { + visit(name); + } + builder.close(); } @Override @@ -222,6 +228,11 @@ public Void visitCase(CaseTree node, Void unused) { List labels = node.getLabels(); boolean isDefault = labels.size() == 1 && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL"); + builder.open( + node.getCaseKind().equals(CaseTree.CaseKind.RULE) + && !node.getBody().getKind().equals(Tree.Kind.BLOCK) + ? plusFour + : ZERO); if (isDefault) { token("default", plusTwo); } else { @@ -259,8 +270,8 @@ public Void visitCase(CaseTree node, Void unused) { builder.space(); token("-"); token(">"); - builder.space(); if (node.getBody().getKind() == Tree.Kind.BLOCK) { + builder.space(); // Explicit call with {@link CollapseEmptyOrNot.YES} to handle empty case blocks. visitBlock( (BlockTree) node.getBody(), @@ -268,6 +279,7 @@ public Void visitCase(CaseTree node, Void unused) { AllowLeadingBlankLine.NO, AllowTrailingBlankLine.NO); } else { + builder.breakOp(" "); scan(node.getBody(), null); } builder.guessToken(";"); @@ -275,6 +287,7 @@ public Void visitCase(CaseTree node, Void unused) { default: throw new AssertionError(node.getCaseKind()); } + builder.close(); return null; } diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java index a96ef99e2..ad936cae4 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -17,7 +17,12 @@ import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.java.java17.Java17InputAstVisitor; import com.sun.source.tree.CaseTree; +import com.sun.source.tree.ConstantCaseLabelTree; +import com.sun.source.tree.DeconstructionPatternTree; +import com.sun.source.tree.DefaultCaseLabelTree; import com.sun.source.tree.ExpressionTree; +import com.sun.source.tree.PatternCaseLabelTree; +import com.sun.source.tree.PatternTree; /** * Extends {@link Java17InputAstVisitor} with support for AST nodes that were added or modified in @@ -33,4 +38,42 @@ public Java21InputAstVisitor(OpsBuilder builder, int indentMultiplier) { protected ExpressionTree getGuard(final CaseTree node) { return node.getGuard(); } + + @Override + public Void visitDefaultCaseLabel(DefaultCaseLabelTree node, Void unused) { + token("default"); + return null; + } + + @Override + public Void visitPatternCaseLabel(PatternCaseLabelTree node, Void unused) { + scan(node.getPattern(), null); + return null; + } + + @Override + public Void visitConstantCaseLabel(ConstantCaseLabelTree node, Void aVoid) { + scan(node.getConstantExpression(), null); + return null; + } + + @Override + public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unused) { + scan(node.getDeconstructor(), null); + builder.open(plusFour); + token("("); + builder.breakOp(); + boolean first = true; + for (PatternTree pattern : node.getNestedPatterns()) { + if (!first) { + token(","); + builder.breakOp(" "); + } + first = false; + scan(pattern, null); + } + builder.close(); + token(")"); + return null; + } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 688b24d8e..67f0eec9a 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -52,7 +52,8 @@ public class FormatterIntegrationTest { .putAll(15, "I603") .putAll(16, "I588") .putAll(17, "I683", "I684", "I696") - .putAll(21, "SwitchGuardClause") + .putAll( + 21, "SwitchGuardClause", "SwitchRecord", "SwitchDouble", "SwitchUnderscore", "I880") .build(); @Parameters(name = "{index}: {0}") @@ -94,7 +95,7 @@ public static Iterable data() throws IOException { String expectedOutput = outputs.get(fileName); Optional version = VERSIONED_TESTS.inverse().get(fileName).stream().collect(toOptional()); - if (version.isPresent() && Runtime.version().feature() < version.get()) { + if (Runtime.version().feature() < version.orElse(Integer.MAX_VALUE)) { continue; } testInputs.add(new Object[] {fileName, input, expectedOutput}); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I880.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I880.input new file mode 100644 index 000000000..dfc8a4cf5 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I880.input @@ -0,0 +1,19 @@ +class I880 { + public String f(int i) { + return switch (i) { + case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 -> "looooooooooooooooooooooooooooooooooooooooong expression"; + default -> "looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong expression"; + }; + } + + public boolean test(int i) { + return switch (i) { + case 0 -> // zero + false; + case 1 -> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".length() + == 0; + default -> // otherwise + true; + }; + } +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I880.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I880.output new file mode 100644 index 000000000..f918665f4 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I880.output @@ -0,0 +1,21 @@ +class I880 { + public String f(int i) { + return switch (i) { + case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 -> + "looooooooooooooooooooooooooooooooooooooooong expression"; + default -> + "looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong expression"; + }; + } + + public boolean test(int i) { + return switch (i) { + case 0 -> // zero + false; + case 1 -> + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".length() == 0; + default -> // otherwise + true; + }; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchDouble.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchDouble.input new file mode 100644 index 000000000..54e22a768 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchDouble.input @@ -0,0 +1,7 @@ +class SwitchDouble { + void x(Object o) { + switch (o) { + case null, default: + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchDouble.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchDouble.output new file mode 100644 index 000000000..54e22a768 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchDouble.output @@ -0,0 +1,7 @@ +class SwitchDouble { + void x(Object o) { + switch (o) { + case null, default: + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchRecord.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchRecord.input new file mode 100644 index 000000000..2f4fb35d9 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchRecord.input @@ -0,0 +1,21 @@ +record SwitchRecord(int i) { + int x(Object o) { + return switch (o) { + case SwitchRecord(int i) -> i; + default -> 0; + }; + } + int f(Object o) { + return switch (o) { + case SwitchRecord(int one, int two, int three, int four, int five, int six, int seven, int eight, int nine) -> nine; + default -> 0; + }; + } + int g(Object o) { + return switch (o) { + case SwitchRecord(int one, int two, int three, int four, int five, int six, int seven, int eight, int nine) -> + System.err.println("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); + default -> 0; + }; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchRecord.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchRecord.output new file mode 100644 index 000000000..89d212f8c --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchRecord.output @@ -0,0 +1,46 @@ +record SwitchRecord(int i) { + int x(Object o) { + return switch (o) { + case SwitchRecord(int i) -> i; + default -> 0; + }; + } + + int f(Object o) { + return switch (o) { + case SwitchRecord( + int one, + int two, + int three, + int four, + int five, + int six, + int seven, + int eight, + int nine) -> + nine; + default -> 0; + }; + } + + int g(Object o) { + return switch (o) { + case SwitchRecord( + int one, + int two, + int three, + int four, + int five, + int six, + int seven, + int eight, + int nine) -> + System.err.println( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor" + + " incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis" + + " nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo" + + " consequat."); + default -> 0; + }; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchUnderscore.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchUnderscore.input new file mode 100644 index 000000000..8d611d24a --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchUnderscore.input @@ -0,0 +1,8 @@ +public class SwitchUnderscore { + void x(Object o) { + switch (o) { + case String _: + default: + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchUnderscore.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchUnderscore.output new file mode 100644 index 000000000..8d611d24a --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchUnderscore.output @@ -0,0 +1,8 @@ +public class SwitchUnderscore { + void x(Object o) { + switch (o) { + case String _: + default: + } + } +} From b92435acb86e549300bf74bb75ff674db70682e7 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 8 Dec 2023 10:44:11 -0800 Subject: [PATCH 228/379] Support unnamed variables Fixes https://github.com/google/google-java-format/issues/978 PiperOrigin-RevId: 589179786 --- .../java/JavaInputAstVisitor.java | 8 +++- .../java/java21/Java21InputAstVisitor.java | 10 ++++ .../java/FormatterIntegrationTest.java | 8 +++- .../java/testdata/Unnamed.input | 44 +++++++++++++++++ .../java/testdata/Unnamed.output | 48 +++++++++++++++++++ 5 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/Unnamed.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/Unnamed.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 5a75afa0e..ea967b3d8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -3563,7 +3563,7 @@ int declareOne( if (receiverExpression.isPresent()) { scan(receiverExpression.get(), null); } else { - visit(name); + variableName(name); } builder.op(op); } @@ -3606,6 +3606,10 @@ int declareOne( return baseDims; } + protected void variableName(Name name) { + visit(name); + } + private void maybeAddDims(Deque> annotations) { maybeAddDims(new ArrayDeque<>(), annotations); } @@ -3696,7 +3700,7 @@ private void declareMany(List fragments, Direction annotationDirec builder.breakOp(" "); builder.open(ZERO); maybeAddDims(dims); - visit(fragment.getName()); + variableName(fragment.getName()); maybeAddDims(dims); ExpressionTree initializer = fragment.getInitializer(); if (initializer != null) { diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java index ad936cae4..6abb93bba 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -23,6 +23,7 @@ import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.PatternCaseLabelTree; import com.sun.source.tree.PatternTree; +import javax.lang.model.element.Name; /** * Extends {@link Java17InputAstVisitor} with support for AST nodes that were added or modified in @@ -76,4 +77,13 @@ public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unus token(")"); return null; } + + @Override + protected void variableName(Name name) { + if (name.isEmpty()) { + token("_"); + } else { + visit(name); + } + } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 67f0eec9a..ffcfd2185 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -53,7 +53,13 @@ public class FormatterIntegrationTest { .putAll(16, "I588") .putAll(17, "I683", "I684", "I696") .putAll( - 21, "SwitchGuardClause", "SwitchRecord", "SwitchDouble", "SwitchUnderscore", "I880") + 21, + "SwitchGuardClause", + "SwitchRecord", + "SwitchDouble", + "SwitchUnderscore", + "I880", + "Unnamed") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Unnamed.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Unnamed.input new file mode 100644 index 000000000..6c5efd12b --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Unnamed.input @@ -0,0 +1,44 @@ +class Unnamed { + { + int acc = 0; + for (Order _ : orders) { + if (acc < LIMIT) { + acc++; + } + } + + for (int i = 0, _ = sideEffect(); i < 10; i++) { } + + Queue q = null; + while (q.size() >= 3) { + var x = q.remove(); + var y = q.remove(); + var _ = q.remove(); + new Point(x, y); + } + + while (q.size() >= 3) { + var x = q.remove(); + var _ = q.remove(); + var _ = q.remove(); + new Point(x, 0) ; + } + + String s = null; + try { + int i = Integer.parseInt(s); + } catch (NumberFormatException _) { + System.out.println("Bad number: " + s); + } + + try { doSomething(); } + catch (Exception _) { doSomething(); } + catch (Throwable _) { doSomething(); } + + try (var _ = ScopedContext.acquire()) { + doSomething(); + } + + stream.collect(Collectors.toMap(String::toUpperCase, _ -> "NODATA")); + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Unnamed.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Unnamed.output new file mode 100644 index 000000000..84d8f872e --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Unnamed.output @@ -0,0 +1,48 @@ +class Unnamed { + { + int acc = 0; + for (Order _ : orders) { + if (acc < LIMIT) { + acc++; + } + } + + for (int i = 0, _ = sideEffect(); i < 10; i++) {} + + Queue q = null; + while (q.size() >= 3) { + var x = q.remove(); + var y = q.remove(); + var _ = q.remove(); + new Point(x, y); + } + + while (q.size() >= 3) { + var x = q.remove(); + var _ = q.remove(); + var _ = q.remove(); + new Point(x, 0); + } + + String s = null; + try { + int i = Integer.parseInt(s); + } catch (NumberFormatException _) { + System.out.println("Bad number: " + s); + } + + try { + doSomething(); + } catch (Exception _) { + doSomething(); + } catch (Throwable _) { + doSomething(); + } + + try (var _ = ScopedContext.acquire()) { + doSomething(); + } + + stream.collect(Collectors.toMap(String::toUpperCase, _ -> "NODATA")); + } +} From dc8b461b8599df1f043d6a1efaadfc44dfa6b823 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 8 Dec 2023 12:27:55 -0800 Subject: [PATCH 229/379] Make g-j-f native image more compatible I was reminded of this by https://github.com/bazelbuild/bazel/pull/20306 PiperOrigin-RevId: 589210771 --- .../META-INF/native-image/reflect-config.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/core/src/main/resources/META-INF/native-image/reflect-config.json b/core/src/main/resources/META-INF/native-image/reflect-config.json index 2c6580345..4d30840f1 100644 --- a/core/src/main/resources/META-INF/native-image/reflect-config.json +++ b/core/src/main/resources/META-INF/native-image/reflect-config.json @@ -2,5 +2,23 @@ { "name": "com.sun.tools.javac.parser.UnicodeReader", "allDeclaredMethods": true + }, + { + "name": "com.google.googlejavaformat.java.java17.Java17InputAstVisitor", + "methods": [ + { + "name": "", + "parameterTypes": ["com.google.googlejavaformat.OpsBuilder", "int"] + } + ] + }, + { + "name": "com.google.googlejavaformat.java.java21.Java21InputAstVisitor", + "methods": [ + { + "name": "", + "parameterTypes": ["com.google.googlejavaformat.OpsBuilder", "int"] + } + ] } ] From b5feefe4ab4dbdbba393d769eb1815f26896104b Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 18 Dec 2023 12:40:05 -0800 Subject: [PATCH 230/379] Initial support for string templates Fixes https://github.com/google/google-java-format/issues/981 PiperOrigin-RevId: 591982309 --- .../googlejavaformat/java/JavaInput.java | 13 +++-- .../googlejavaformat/java/JavacTokens.java | 52 ++++++++++++++++--- .../java/java21/Java21InputAstVisitor.java | 12 +++++ .../java/FormatterIntegrationTest.java | 3 +- .../googlejavaformat/java/testdata/I981.input | 12 +++++ .../java/testdata/I981.output | 14 +++++ 6 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index eee210e20..7b5eb841f 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -387,7 +387,14 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept final boolean isNumbered; // Is this tok numbered? (tokens and comments) String extraNewline = null; // Extra newline at end? List strings = new ArrayList<>(); - if (Character.isWhitespace(tokText0)) { + if (tokText.startsWith("'") + || tokText.startsWith("\"") + || JavacTokens.isStringFragment(t.kind())) { + // Perform this check first, STRINGFRAGMENT tokens can start with arbitrary characters. + isToken = true; + isNumbered = true; + strings.add(originalTokText); + } else if (Character.isWhitespace(tokText0)) { isToken = false; isNumbered = false; Iterator it = Newlines.lineIterator(originalTokText); @@ -404,10 +411,6 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept strings.add(line); } } - } else if (tokText.startsWith("'") || tokText.startsWith("\"")) { - isToken = true; - isNumbered = true; - strings.add(originalTokText); } else if (tokText.startsWith("//") || tokText.startsWith("/*")) { // For compatibility with an earlier lexer, the newline after a // comment is its own tok. if (tokText.startsWith("//") diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java index ba7e3b774..dd8760b25 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java @@ -15,6 +15,7 @@ package com.google.googlejavaformat.java; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Arrays.stream; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -27,6 +28,7 @@ import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.parser.UnicodeReader; import com.sun.tools.javac.util.Context; +import java.util.Objects; import java.util.Set; /** A wrapper around javac's lexer. */ @@ -71,6 +73,16 @@ public String stringVal() { } } + private static final TokenKind STRINGFRAGMENT = + stream(TokenKind.values()) + .filter(t -> t.name().contentEquals("STRINGFRAGMENT")) + .findFirst() + .orElse(null); + + static boolean isStringFragment(TokenKind kind) { + return STRINGFRAGMENT != null && Objects.equals(kind, STRINGFRAGMENT); + } + /** Lex the input and return a list of {@link RawTok}s. */ public static ImmutableList getTokens( String source, Context context, Set stopTokens) { @@ -106,13 +118,39 @@ public static ImmutableList getTokens( if (last < t.pos) { tokens.add(new RawTok(null, null, last, t.pos)); } - tokens.add( - new RawTok( - t.kind == TokenKind.STRINGLITERAL ? "\"" + t.stringVal() + "\"" : null, - t.kind, - t.pos, - t.endPos)); - last = t.endPos; + int pos = t.pos; + int endPos = t.endPos; + if (isStringFragment(t.kind)) { + // A string template is tokenized as a series of STRINGFRAGMENT tokens containing the string + // literal values, followed by the tokens for the template arguments. For the formatter, we + // want the stream of tokens to appear in order by their start position, and also to have + // all the content from the original source text (including leading and trailing ", and the + // \ escapes from template arguments). This logic processes the token stream from javac to + // meet those requirements. + while (isStringFragment(t.kind)) { + endPos = t.endPos; + scanner.nextToken(); + t = scanner.token(); + } + // Read tokens for the string template arguments, until we read the end of the string + // template. The last token in a string template is always a trailing string fragment. Use + // lookahead to defer reading the token after the template until the next iteration of the + // outer loop. + while (scanner.token(/* lookahead= */ 1).endPos < endPos) { + scanner.nextToken(); + t = scanner.token(); + } + tokens.add(new RawTok(source.substring(pos, endPos), t.kind, pos, endPos)); + last = endPos; + } else { + tokens.add( + new RawTok( + t.kind == TokenKind.STRINGLITERAL ? "\"" + t.stringVal() + "\"" : null, + t.kind, + t.pos, + t.endPos)); + last = t.endPos; + } } while (scanner.token().kind != TokenKind.EOF); if (last < end) { tokens.add(new RawTok(null, null, last, end)); diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java index 6abb93bba..897d6ffc7 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -23,6 +23,7 @@ import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.PatternCaseLabelTree; import com.sun.source.tree.PatternTree; +import com.sun.source.tree.StringTemplateTree; import javax.lang.model.element.Name; /** @@ -60,6 +61,7 @@ public Void visitConstantCaseLabel(ConstantCaseLabelTree node, Void aVoid) { @Override public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unused) { + sync(node); scan(node.getDeconstructor(), null); builder.open(plusFour); token("("); @@ -78,6 +80,16 @@ public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unus return null; } + @SuppressWarnings("preview") + @Override + public Void visitStringTemplate(StringTemplateTree node, Void aVoid) { + sync(node); + scan(node.getProcessor(), null); + token("."); + token(builder.peekToken().get()); + return null; + } + @Override protected void variableName(Name name) { if (name.isEmpty()) { diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index ffcfd2185..cf15ecbc7 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -59,7 +59,8 @@ public class FormatterIntegrationTest { "SwitchDouble", "SwitchUnderscore", "I880", - "Unnamed") + "Unnamed", + "I981") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.input new file mode 100644 index 000000000..bba0b7267 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.input @@ -0,0 +1,12 @@ +class Foo { + private static final int X = 42; + private static final String A = STR."\{X} = \{X}"; + private static final String B = STR.""; + private static final String C = STR."\{X}"; + private static final String D = STR."\{X}\{X}"; + private static final String E = STR."\{X}\{X}\{X}"; + private static final String F = STR." \{X}"; + private static final String G = STR."\{X} "; + private static final String H = STR."\{X} one long incredibly unbroken sentence moving from "+"topic to topic so that no-one had a chance to interrupt"; + private static final String I = STR."\{X} \uD83D\uDCA9 "; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.output new file mode 100644 index 000000000..ff173fb6a --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.output @@ -0,0 +1,14 @@ +class Foo { + private static final int X = 42; + private static final String A = STR."\{X} = \{X}"; + private static final String B = STR.""; + private static final String C = STR."\{X}"; + private static final String D = STR."\{X}\{X}"; + private static final String E = STR."\{X}\{X}\{X}"; + private static final String F = STR." \{X}"; + private static final String G = STR."\{X} "; + private static final String H = + STR."\{X} one long incredibly unbroken sentence moving from " + + "topic to topic so that no-one had a chance to interrupt"; + private static final String I = STR."\{X} \uD83D\uDCA9 "; +} From 0e7cc6ff3763621f3dd9d28fbac74b857bb73c19 Mon Sep 17 00:00:00 2001 From: Claudio Nave Date: Tue, 19 Dec 2023 02:58:13 +0100 Subject: [PATCH 231/379] Upgrade jdk used by release action to 21 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3176f73c6..f81286571 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@v2.5.0 with: - java-version: 17 + java-version: 21 distribution: 'zulu' cache: 'maven' server-id: sonatype-nexus-staging From 627c97e63c563ae04eca9aa1baeca99eac6c365a Mon Sep 17 00:00:00 2001 From: Rui Chen Date: Tue, 19 Dec 2023 08:38:41 -0800 Subject: [PATCH 232/379] chore: fix `SyntaxWarning: invalid escape sequence +` for py3.12 ``` /opt/homebrew/Cellar/google-java-format/1.19.0/bin/google-java-format-diff:78: SyntaxWarning: invalid escape sequence '\+' match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) /opt/homebrew/Cellar/google-java-format/1.19.0/bin/google-java-format-diff:91: SyntaxWarning: invalid escape sequence '\+' match = re.search('^@@.*\+(\d+)(,(\d+))?', line) ``` relates to https://github.com/Homebrew/homebrew-core/pull/157669 cc @cushon Fixes #1017 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1017 from chenrui333:py3.12 36d80d13a9b76b11d0ffbafb0ab5d87e1101d5ba PiperOrigin-RevId: 592246854 --- scripts/google-java-format-diff.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/google-java-format-diff.py b/scripts/google-java-format-diff.py index 151ae33d9..2c75edac7 100755 --- a/scripts/google-java-format-diff.py +++ b/scripts/google-java-format-diff.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 # -#===- google-java-format-diff.py - google-java-format Diff Reformatter -----===# +# ===- google-java-format-diff.py - google-java-format Diff Reformatter -----===# # # The LLVM Compiler Infrastructure # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. # -#===------------------------------------------------------------------------===# +# ===------------------------------------------------------------------------===# """ google-java-format Diff Reformatter @@ -75,7 +75,7 @@ def main(): lines_by_file = {} for line in sys.stdin: - match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) + match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) if match: filename = match.group(2) if filename == None: @@ -88,7 +88,7 @@ def main(): if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE): continue - match = re.search('^@@.*\+(\d+)(,(\d+))?', line) + match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line) if match: start_line = int(match.group(1)) line_count = 1 From 8afdfcad56c41637fe946c80764355d6788099ba Mon Sep 17 00:00:00 2001 From: Rui Chen Date: Tue, 19 Dec 2023 10:00:49 -0500 Subject: [PATCH 233/379] chore: bump checkout/setup-java to v4 (use nodejs20 runtime) Signed-off-by: Rui Chen --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee1174dfb..51ecf6e80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,7 +51,7 @@ jobs: with: access_token: ${{ github.token }} - name: 'Check out repository' - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: 'Set up JDK ${{ matrix.java }} from jdk.java.net' if: ${{ matrix.java == 'EA' }} uses: oracle-actions/setup-java@v1 @@ -61,7 +61,7 @@ jobs: cache: 'maven' - name: 'Set up JDK ${{ matrix.java }}' if: ${{ matrix.java != 'EA' }} - uses: actions/setup-java@v2 + uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} distribution: 'zulu' @@ -80,9 +80,9 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Check out repository' - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: 'Set up JDK 17' - uses: actions/setup-java@v2 + uses: actions/setup-java@v4 with: java-version: 17 distribution: 'zulu' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f81286571..cf50d61c6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,12 +12,12 @@ jobs: runs-on: ubuntu-latest permissions: contents: write - steps: + steps: - name: Checkout - uses: actions/checkout@v2.4.0 + uses: actions/checkout@v4 - name: Set up JDK - uses: actions/setup-java@v2.5.0 + uses: actions/setup-java@v4 with: java-version: 21 distribution: 'zulu' @@ -27,7 +27,7 @@ jobs: server-password: CI_DEPLOY_PASSWORD gpg-private-key: ${{ secrets.GPG_SIGNING_KEY }} gpg-passphrase: MAVEN_GPG_PASSPHRASE - + - name: Bump Version Number run: | mvn --no-transfer-progress versions:set versions:commit -DnewVersion="${{ github.event.inputs.version }}" @@ -40,7 +40,7 @@ jobs: git tag "v${{ github.event.inputs.version }}" echo "TARGET_COMMITISH=$(git rev-parse HEAD)" >> $GITHUB_ENV git remote set-url origin https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/google/google-java-format.git - + - name: Deploy to Sonatype staging env: CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} @@ -56,12 +56,12 @@ jobs: - name: Push tag run: | git push origin "v${{ github.event.inputs.version }}" - + - name: Add Jars to Release Entry uses: softprops/action-gh-release@v0.1.14 with: draft: true - name: ${{ github.event.input.version }} + name: ${{ github.event.input.version }} tag_name: "v${{ github.event.inputs.version }}" target_commitish: ${{ env.TARGET_COMMITISH }} files: | From 38de9c4e05bc871496c232c1ccbfc4be06a580e2 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 21 Dec 2023 13:40:10 -0800 Subject: [PATCH 234/379] Improve support for string templates The initial implementation passed through the entire string unmodified, this allows formatting the Java expressions inside the `\{...}`. See https://github.com/google/google-java-format/pull/1010 Co-authored-by: butterunderflow PiperOrigin-RevId: 592940163 --- .../googlejavaformat/java/JavacTokens.java | 75 ++++++++++++------- .../java/java21/Java21InputAstVisitor.java | 11 ++- .../java/FormatterIntegrationTest.java | 3 +- .../googlejavaformat/java/FormatterTest.java | 24 ++++++ .../java/testdata/StringTemplate.input | 10 +++ .../java/testdata/StringTemplate.output | 9 +++ 6 files changed, 103 insertions(+), 29 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java index dd8760b25..da77cf82c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java @@ -28,6 +28,11 @@ import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.parser.UnicodeReader; import com.sun.tools.javac.util.Context; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; import java.util.Objects; import java.util.Set; @@ -83,9 +88,8 @@ static boolean isStringFragment(TokenKind kind) { return STRINGFRAGMENT != null && Objects.equals(kind, STRINGFRAGMENT); } - /** Lex the input and return a list of {@link RawTok}s. */ - public static ImmutableList getTokens( - String source, Context context, Set stopTokens) { + private static ImmutableList readAllTokens( + String source, Context context, Set nonTerminalStringFragments) { if (source == null) { return ImmutableList.of(); } @@ -93,12 +97,44 @@ public static ImmutableList getTokens( char[] buffer = (source + EOF_COMMENT).toCharArray(); Scanner scanner = new AccessibleScanner(fac, new CommentSavingTokenizer(fac, buffer, buffer.length)); + List tokens = new ArrayList<>(); + do { + scanner.nextToken(); + tokens.add(scanner.token()); + } while (scanner.token().kind != TokenKind.EOF); + for (int i = 0; i < tokens.size(); i++) { + if (isStringFragment(tokens.get(i).kind)) { + int start = i; + while (isStringFragment(tokens.get(i).kind)) { + i++; + } + for (int j = start; j < i - 1; j++) { + nonTerminalStringFragments.add(tokens.get(j).pos); + } + } + } + // A string template is tokenized as a series of STRINGFRAGMENT tokens containing the string + // literal values, followed by the tokens for the template arguments. For the formatter, we + // want the stream of tokens to appear in order by their start position. + if (Runtime.version().feature() >= 21) { + Collections.sort(tokens, Comparator.comparingInt(t -> t.pos)); + } + return ImmutableList.copyOf(tokens); + } + + /** Lex the input and return a list of {@link RawTok}s. */ + public static ImmutableList getTokens( + String source, Context context, Set stopTokens) { + if (source == null) { + return ImmutableList.of(); + } + Set nonTerminalStringFragments = new HashSet<>(); + ImmutableList javacTokens = readAllTokens(source, context, nonTerminalStringFragments); + ImmutableList.Builder tokens = ImmutableList.builder(); int end = source.length(); int last = 0; - do { - scanner.nextToken(); - Token t = scanner.token(); + for (Token t : javacTokens) { if (t.comments != null) { for (Comment c : Lists.reverse(t.comments)) { if (last < c.getSourcePos(0)) { @@ -118,27 +154,12 @@ public static ImmutableList getTokens( if (last < t.pos) { tokens.add(new RawTok(null, null, last, t.pos)); } - int pos = t.pos; - int endPos = t.endPos; if (isStringFragment(t.kind)) { - // A string template is tokenized as a series of STRINGFRAGMENT tokens containing the string - // literal values, followed by the tokens for the template arguments. For the formatter, we - // want the stream of tokens to appear in order by their start position, and also to have - // all the content from the original source text (including leading and trailing ", and the - // \ escapes from template arguments). This logic processes the token stream from javac to - // meet those requirements. - while (isStringFragment(t.kind)) { - endPos = t.endPos; - scanner.nextToken(); - t = scanner.token(); - } - // Read tokens for the string template arguments, until we read the end of the string - // template. The last token in a string template is always a trailing string fragment. Use - // lookahead to defer reading the token after the template until the next iteration of the - // outer loop. - while (scanner.token(/* lookahead= */ 1).endPos < endPos) { - scanner.nextToken(); - t = scanner.token(); + int endPos = t.endPos; + int pos = t.pos; + if (nonTerminalStringFragments.contains(t.pos)) { + // Include the \ escape from \{...} in the preceding string fragment + endPos++; } tokens.add(new RawTok(source.substring(pos, endPos), t.kind, pos, endPos)); last = endPos; @@ -151,7 +172,7 @@ public static ImmutableList getTokens( t.endPos)); last = t.endPos; } - } while (scanner.token().kind != TokenKind.EOF); + } if (last < end) { tokens.add(new RawTok(null, null, last, end)); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java index 897d6ffc7..5ef81fad6 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -82,11 +82,20 @@ public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unus @SuppressWarnings("preview") @Override - public Void visitStringTemplate(StringTemplateTree node, Void aVoid) { + public Void visitStringTemplate(StringTemplateTree node, Void unused) { sync(node); + builder.open(plusFour); scan(node.getProcessor(), null); token("."); token(builder.peekToken().get()); + for (int i = 0; i < node.getFragments().size() - 1; i++) { + token("{"); + builder.breakOp(); + scan(node.getExpressions().get(i), null); + token("}"); + token(builder.peekToken().get()); + } + builder.close(); return null; } diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index cf15ecbc7..b31e7bb15 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -60,7 +60,8 @@ public class FormatterIntegrationTest { "SwitchUnderscore", "I880", "Unnamed", - "I981") + "I981", + "StringTemplate") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java index 1653e5645..9bbca496a 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java @@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; import com.google.common.base.Joiner; import com.google.common.io.CharStreams; @@ -492,4 +493,27 @@ public void removeTrailingTabsInComments() throws Exception { + " }\n" + "}\n"); } + + @Test + public void stringTemplateTests() throws Exception { + assumeTrue(Runtime.version().feature() >= 21); + assertThat( + new Formatter() + .formatSource( + "public class Foo {\n" + + " String test(){\n" + + " var simple = STR.\"mytemplate1XXXX \\{exampleXXXX.foo()}yyy\";\n" + + " var nested = STR.\"template \\{example. foo()+" + + " STR.\"templateInner\\{ example}\"}xxx }\";\n" + + " }\n" + + "}\n")) + .isEqualTo( + "public class Foo {\n" + + " String test() {\n" + + " var simple = STR.\"mytemplate1XXXX \\{exampleXXXX.foo()}yyy\";\n" + + " var nested = STR.\"template \\{example.foo() +" + + " STR.\"templateInner\\{example}\"}xxx }\";\n" + + " }\n" + + "}\n"); + } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.input new file mode 100644 index 000000000..98a19bba7 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.input @@ -0,0 +1,10 @@ +public class StringTemplates { + void test(){ + var m = STR."template \{example}xxx"; + var nested = STR."template \{example.foo()+ STR."templateInner\{example}"}xxx }"; + var nestNested = STR."template \{example0. + foo() + + STR."templateInner\{example1.test(STR."\{example2 + }")}"}xxx }"; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.output new file mode 100644 index 000000000..e60bab70b --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.output @@ -0,0 +1,9 @@ +public class StringTemplates { + void test() { + var m = STR."template \{example}xxx"; + var nested = STR."template \{example.foo() + STR."templateInner\{example}"}xxx }"; + var nestNested = + STR."template \{ + example0.foo() + STR."templateInner\{example1.test(STR."\{example2}")}"}xxx }"; + } +} From d157ec879b43c4837f71eaafb45a6e6d58071a9a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 3 Jan 2024 16:49:38 -0800 Subject: [PATCH 235/379] Handle `var` in record patterns https://github.com/google/google-java-format/issues/1020 PiperOrigin-RevId: 595537430 --- .../java/JavaInputAstVisitor.java | 5 ++-- .../java/java17/Java17InputAstVisitor.java | 25 +++++++++---------- .../java/FormatterIntegrationTest.java | 3 ++- .../java/testdata/I1020.input | 15 +++++++++++ .../java/testdata/I1020.output | 16 ++++++++++++ 5 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I1020.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I1020.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index ea967b3d8..8914c8ea2 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -3475,14 +3475,15 @@ private static boolean expressionsAreParallel( // General helper functions. - enum DeclarationKind { + /** Kind of declaration. */ + protected enum DeclarationKind { NONE, FIELD, PARAMETER } /** Declare one variable or variable-like thing. */ - int declareOne( + protected int declareOne( DeclarationKind kind, Direction annotationsDirection, Optional modifiers, diff --git a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java index 6818f4a03..a7b5dbc44 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java @@ -22,7 +22,6 @@ import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.OpsBuilder.BlankLineWanted; import com.google.googlejavaformat.java.JavaInputAstVisitor; -import com.sun.source.tree.AnnotationTree; import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.BlockTree; import com.sun.source.tree.CaseLabelTree; @@ -84,18 +83,18 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) { builder.open(plusFour); - if (modifiers != null) { - List annotations = - visitModifiers(modifiers, Direction.HORIZONTAL, Optional.empty()); - visitAnnotations(annotations, BreakOrNot.NO, BreakOrNot.YES); - } - scan(type, null); - builder.breakOp(" "); - if (name.isEmpty()) { - token("_"); - } else { - visit(name); - } + declareOne( + DeclarationKind.PARAMETER, + Direction.HORIZONTAL, + Optional.of(modifiers), + type, + name, + /* op= */ "", + /* equals= */ "", + /* initializer= */ Optional.empty(), + /* trailing= */ Optional.empty(), + /* receiverExpression= */ Optional.empty(), + /* typeWithDims= */ Optional.empty()); builder.close(); } diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index b31e7bb15..5fb356750 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -61,7 +61,8 @@ public class FormatterIntegrationTest { "I880", "Unnamed", "I981", - "StringTemplate") + "StringTemplate", + "I1020") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1020.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1020.input new file mode 100644 index 000000000..8ff084265 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1020.input @@ -0,0 +1,15 @@ +public sealed interface A { + record AA(Long a) implements A {} + record AAA(String b) implements A {} + static Long mySwitch(A a) { + switch (a) { + case AA(var aa) -> { + return aa; + } + case AAA(var b) -> { + return Long.parseLong(b); + } + } + } +} + diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1020.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1020.output new file mode 100644 index 000000000..21e4a5156 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1020.output @@ -0,0 +1,16 @@ +public sealed interface A { + record AA(Long a) implements A {} + + record AAA(String b) implements A {} + + static Long mySwitch(A a) { + switch (a) { + case AA(var aa) -> { + return aa; + } + case AAA(var b) -> { + return Long.parseLong(b); + } + } + } +} From b1dce94186e290358b74f42418b5e43119ef723c Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Thu, 11 Jan 2024 13:37:05 -0800 Subject: [PATCH 236/379] Update the IntelliJ plugin to gfj 1.19.2. PiperOrigin-RevId: 597641894 --- idea_plugin/build.gradle.kts | 6 +++--- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 5e965823f..2247893c1 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -plugins { id("org.jetbrains.intellij") version "1.15.0" } +plugins { id("org.jetbrains.intellij") version "1.16.1" } apply(plugin = "org.jetbrains.intellij") @@ -22,7 +22,7 @@ apply(plugin = "java") repositories { mavenCentral() } -val googleJavaFormatVersion = "1.17.0" +val googleJavaFormatVersion = "1.19.2" java { sourceCompatibility = JavaVersion.VERSION_11 @@ -62,5 +62,5 @@ tasks { dependencies { implementation("com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}") testImplementation("junit:junit:4.13.2") - testImplementation("com.google.truth:truth:1.1.5") + testImplementation("com.google.truth:truth:1.2.0") } diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 1b1e67ffa..a5600b00d 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
1.19.2.0
+
Updated to use google-java-format 1.19.2.
1.17.0.0
Updated to use google-java-format 1.17.0.
Fixed "Document is locked" errors (Thanks, @facboy!)
From 412d761b687629df55cadef6ba1f846dee48a6d5 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 24 Jan 2024 15:24:53 -0800 Subject: [PATCH 237/379] Fix a test bug introduced by https://github.com/google/google-java-format/commit/430ba3b0e237b746157a3392663da4b4bb7c733d PiperOrigin-RevId: 601252048 --- .../googlejavaformat/java/FormatterIntegrationTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 5fb356750..26493b022 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -104,10 +104,9 @@ public static Iterable data() throws IOException { String expectedOutput = outputs.get(fileName); Optional version = VERSIONED_TESTS.inverse().get(fileName).stream().collect(toOptional()); - if (Runtime.version().feature() < version.orElse(Integer.MAX_VALUE)) { - continue; + if (Runtime.version().feature() >= version.orElse(Integer.MIN_VALUE)) { + testInputs.add(new Object[] {fileName, input, expectedOutput}); } - testInputs.add(new Object[] {fileName, input, expectedOutput}); } return testInputs; } From 03efe44d9affc989eee8623651fbdf1bcc7240dc Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 26 Jan 2024 10:20:00 -0800 Subject: [PATCH 238/379] Keep type-use annotation with type when wrapping PiperOrigin-RevId: 601800310 --- .../java/JavaInputAstVisitor.java | 18 ++++++++++++++---- .../java/testdata/B322210626.input | 11 +++++++++++ .../java/testdata/B322210626.output | 11 +++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B322210626.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B322210626.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 8914c8ea2..1f51a7632 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -1407,6 +1407,14 @@ public Void visitMethod(MethodTree node, Void unused) { annotations, Direction.VERTICAL, /* declarationAnnotationBreak= */ Optional.empty()); + if (node.getTypeParameters().isEmpty() && node.getReturnType() != null) { + // If there are type parameters, we use a heuristic above to format annotations after the + // type parameter declarations as type-use annotations. If there are no type parameters, + // use the heuristics in visitModifiers for recognizing well known type-use annotations and + // formatting them as annotations on the return type. + returnTypeAnnotations = typeAnnotations; + typeAnnotations = ImmutableList.of(); + } Tree baseReturnType = null; Deque> dims = null; @@ -1436,10 +1444,6 @@ public Void visitMethod(MethodTree node, Void unused) { } token("<"); typeParametersRest(node.getTypeParameters(), plusFour); - if (!returnTypeAnnotations.isEmpty()) { - builder.breakToFill(" "); - visitAnnotations(returnTypeAnnotations, BreakOrNot.NO, BreakOrNot.NO); - } first = false; } @@ -1456,8 +1460,14 @@ public Void visitMethod(MethodTree node, Void unused) { builder.open(make(breakBeforeType, plusFour, ZERO)); openedNameAndTypeScope = true; } + builder.open(ZERO); + if (!returnTypeAnnotations.isEmpty()) { + visitAnnotations(returnTypeAnnotations, BreakOrNot.NO, BreakOrNot.NO); + builder.breakOp(" "); + } scan(baseReturnType, null); maybeAddDims(dims); + builder.close(); } if (!first) { builder.breakOp(Doc.FillMode.INDEPENDENT, " ", ZERO, Optional.of(breakBeforeName)); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B322210626.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B322210626.input new file mode 100644 index 000000000..931a7d726 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B322210626.input @@ -0,0 +1,11 @@ +class WrapTypeUse { + public static final @Nullable + WrapTypeUse get() { + return null; + } + + public @Nullable + Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx getXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx() { + return null; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B322210626.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B322210626.output new file mode 100644 index 000000000..b34bdb38c --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B322210626.output @@ -0,0 +1,11 @@ +class WrapTypeUse { + public static final + @Nullable WrapTypeUse get() { + return null; + } + + public @Nullable Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + getXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx() { + return null; + } +} From a110c89f698886fe90f4f7139b23c84e0f963312 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 26 Jan 2024 10:54:24 -0800 Subject: [PATCH 239/379] Rename `first` to `afterFirstToken` See unknown commit PiperOrigin-RevId: 601810198 --- .../java/JavaInputAstVisitor.java | 214 +++++++++--------- .../java/java17/Java17InputAstVisitor.java | 16 +- .../java/java21/Java21InputAstVisitor.java | 6 +- 3 files changed, 119 insertions(+), 117 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 1f51a7632..1123ac01c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -368,16 +368,16 @@ public Void scan(Tree tree, Void unused) { @Override public Void visitCompilationUnit(CompilationUnitTree node, Void unused) { - boolean first = true; + boolean afterFirstToken = false; if (node.getPackageName() != null) { markForPartialFormat(); visitPackage(node.getPackageName(), node.getPackageAnnotations()); builder.forcedBreak(); - first = false; + afterFirstToken = true; } dropEmptyDeclarations(); if (!node.getImports().isEmpty()) { - if (!first) { + if (afterFirstToken) { builder.blankLineWanted(BlankLineWanted.YES); } for (ImportTree importDeclaration : node.getImports()) { @@ -386,7 +386,7 @@ public Void visitCompilationUnit(CompilationUnitTree node, Void unused) { scan(importDeclaration, null); builder.forcedBreak(); } - first = false; + afterFirstToken = true; } dropEmptyDeclarations(); for (Tree type : node.getTypeDecls()) { @@ -395,22 +395,22 @@ public Void visitCompilationUnit(CompilationUnitTree node, Void unused) { // TODO(cushon): remove this if https://bugs.openjdk.java.net/browse/JDK-8027682 is fixed continue; } - if (!first) { + if (afterFirstToken) { builder.blankLineWanted(BlankLineWanted.YES); } markForPartialFormat(); scan(type, null); builder.forcedBreak(); - first = false; + afterFirstToken = true; dropEmptyDeclarations(); } - handleModule(first, node); + handleModule(afterFirstToken, node); // set a partial format marker at EOF to make sure we can format the entire file markForPartialFormat(); return null; } - protected void handleModule(boolean first, CompilationUnitTree node) {} + protected void handleModule(boolean afterFirstToken, CompilationUnitTree node) {} /** Skips over extra semi-colons at the top-level, or in a class member declaration lists. */ protected void dropEmptyDeclarations() { @@ -514,9 +514,9 @@ public boolean visitArrayInitializer(List expressions) builder.open(plusTwo); token("{"); builder.forcedBreak(); - boolean first = true; + boolean afterFirstToken = false; for (Iterable row : Iterables.partition(expressions, cols)) { - if (!first) { + if (afterFirstToken) { builder.forcedBreak(); } builder.open(row.iterator().next().getKind() == NEW_ARRAY || cols == 1 ? ZERO : plusFour); @@ -531,7 +531,7 @@ public boolean visitArrayInitializer(List expressions) } builder.guessToken(","); builder.close(); - first = false; + afterFirstToken = true; } builder.breakOp(minusTwo); builder.close(); @@ -562,15 +562,15 @@ public boolean visitArrayInitializer(List expressions) if (allowFilledElementsOnOwnLine) { builder.open(ZERO); } - boolean first = true; + boolean afterFirstToken = false; FillMode fillMode = shortItems ? FillMode.INDEPENDENT : FillMode.UNIFIED; for (ExpressionTree expression : expressions) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(fillMode, " ", ZERO); } scan(expression, null); - first = false; + afterFirstToken = true; } builder.guessToken(","); if (allowFilledElementsOnOwnLine) { @@ -842,14 +842,14 @@ public boolean visitEnumDeclaration(ClassTree node) { token("implements"); builder.breakOp(" "); builder.open(ZERO); - boolean first = true; + boolean afterFirstToken = false; for (Tree superInterfaceType : node.getImplementsClause()) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakToFill(" "); } scan(superInterfaceType, null); - first = false; + afterFirstToken = true; } builder.close(); builder.close(); @@ -893,16 +893,16 @@ public boolean visitEnumDeclaration(ClassTree node) { builder.blankLineWanted(BlankLineWanted.NO); builder.forcedBreak(); builder.open(ZERO); - boolean first = true; + boolean afterFirstToken = false; for (VariableTree enumConstant : enumConstants) { - if (!first) { + if (afterFirstToken) { token(","); builder.forcedBreak(); builder.blankLineWanted(BlankLineWanted.PRESERVE); } markForPartialFormat(); visitEnumConstantDeclaration(enumConstant); - first = false; + afterFirstToken = true; } if (builder.peekToken().orElse("").equals(",")) { token(","); @@ -984,18 +984,19 @@ void visitVariables( Optional.ofNullable(fragment.getInitializer()), Optional.of(";"), /* receiverExpression= */ Optional.empty(), - Optional.ofNullable(variableFragmentDims(true, 0, fragment.getType()))); + Optional.ofNullable(variableFragmentDims(false, 0, fragment.getType()))); } else { declareMany(fragments, annotationDirection); } } - private static TypeWithDims variableFragmentDims(boolean first, int leadingDims, Tree type) { + private static TypeWithDims variableFragmentDims( + boolean afterFirstToken, int leadingDims, Tree type) { if (type == null) { return null; } - if (first) { + if (!afterFirstToken) { return DimensionHelpers.extractDims(type, SortedDims.YES); } TypeWithDims dims = DimensionHelpers.extractDims(type, SortedDims.NO); @@ -1022,15 +1023,15 @@ public Void visitForLoop(ForLoopTree node, Void unused) { visitVariables( variableFragments(it, it.next()), DeclarationKind.NONE, Direction.HORIZONTAL); } else { - boolean first = true; + boolean afterFirstToken = false; builder.open(ZERO); for (StatementTree t : node.getInitializer()) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(" "); } scan(((ExpressionStatementTree) t).getExpression(), null); - first = false; + afterFirstToken = true; } token(";"); builder.close(); @@ -1087,11 +1088,11 @@ public Void visitIf(IfTree node, Void unused) { } } builder.open(ZERO); - boolean first = true; + boolean afterFirstToken = false; boolean followingBlock = false; int expressionsN = expressions.size(); for (int i = 0; i < expressionsN; i++) { - if (!first) { + if (afterFirstToken) { if (followingBlock) { builder.space(); } else { @@ -1115,7 +1116,7 @@ public Void visitIf(IfTree node, Void unused) { AllowLeadingBlankLine.YES, AllowTrailingBlankLine.valueOf(trailingClauses)); followingBlock = statements.get(i).getKind() == BLOCK; - first = false; + afterFirstToken = true; } if (node.getElseStatement() != null) { if (followingBlock) { @@ -1208,15 +1209,15 @@ public Void visitInstanceOf(InstanceOfTree node, Void unused) { public Void visitIntersectionType(IntersectionTypeTree node, Void unused) { sync(node); builder.open(plusFour); - boolean first = true; + boolean afterFirstToken = false; for (Tree type : node.getBounds()) { - if (!first) { + if (afterFirstToken) { builder.breakToFill(" "); token("&"); builder.space(); } scan(type, null); - first = false; + afterFirstToken = true; } builder.close(); return null; @@ -1243,9 +1244,9 @@ public Void visitLambdaExpression(LambdaExpressionTree node, Void unused) { if (parens) { token("("); } - boolean first = true; + boolean afterFirstToken = false; for (VariableTree parameter : node.getParameters()) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(" "); } @@ -1253,7 +1254,7 @@ public Void visitLambdaExpression(LambdaExpressionTree node, Void unused) { ImmutableList.of(parameter), DeclarationKind.NONE, fieldAnnotationDirection(parameter.getModifiers())); - first = false; + afterFirstToken = true; } if (parens) { token(")"); @@ -1295,14 +1296,14 @@ public Void visitAnnotation(AnnotationTree node, Void unused) { builder.open(plusFour); token("("); builder.breakOp(); - boolean first = true; + boolean afterFirstToken = false; // Format the member value pairs one-per-line if any of them are // initialized with arrays. boolean hasArrayInitializer = Iterables.any(node.getArguments(), JavaInputAstVisitor::isArrayValue); for (ExpressionTree argument : node.getArguments()) { - if (!first) { + if (afterFirstToken) { token(","); if (hasArrayInitializer) { builder.forcedBreak(); @@ -1315,7 +1316,7 @@ public Void visitAnnotation(AnnotationTree node, Void unused) { } else { scan(argument, null); } - first = false; + afterFirstToken = true; } token(")"); builder.close(); @@ -1433,28 +1434,28 @@ public Void visitMethod(MethodTree node, Void unused) { BreakTag breakBeforeType = genSym(); builder.open(ZERO); { - boolean first = true; + boolean afterFirstToken = false; if (!typeAnnotations.isEmpty()) { visitAnnotations(typeAnnotations, BreakOrNot.NO, BreakOrNot.NO); - first = false; + afterFirstToken = true; } if (!node.getTypeParameters().isEmpty()) { - if (!first) { + if (afterFirstToken) { builder.breakToFill(" "); } token("<"); typeParametersRest(node.getTypeParameters(), plusFour); - first = false; + afterFirstToken = true; } boolean openedNameAndTypeScope = false; // constructor-like declarations that don't match the name of the enclosing class are // parsed as method declarations with a null return type if (baseReturnType != null) { - if (!first) { + if (afterFirstToken) { builder.breakOp(INDEPENDENT, " ", ZERO, Optional.of(breakBeforeType)); } else { - first = false; + afterFirstToken = true; } if (!openedNameAndTypeScope) { builder.open(make(breakBeforeType, plusFour, ZERO)); @@ -1469,10 +1470,10 @@ public Void visitMethod(MethodTree node, Void unused) { maybeAddDims(dims); builder.close(); } - if (!first) { + if (afterFirstToken) { builder.breakOp(Doc.FillMode.INDEPENDENT, " ", ZERO, Optional.of(breakBeforeName)); } else { - first = false; + afterFirstToken = true; } if (!openedNameAndTypeScope) { builder.open(ZERO); @@ -1712,14 +1713,14 @@ public Void visitParameterizedType(ParameterizedTypeTree node, Void unused) { token("<"); builder.breakOp(); builder.open(ZERO); - boolean first = true; + boolean afterFirstToken = false; for (Tree typeArgument : node.getTypeArguments()) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(" "); } scan(typeArgument, null); - first = false; + afterFirstToken = true; } builder.close(); builder.close(); @@ -1905,13 +1906,13 @@ protected void visitSwitch(ExpressionTree expression, List c tokenBreakTrailingComment("{", plusTwo); builder.blankLineWanted(BlankLineWanted.NO); builder.open(plusTwo); - boolean first = true; + boolean afterFirstToken = false; for (CaseTree caseTree : cases) { - if (!first) { + if (afterFirstToken) { builder.blankLineWanted(BlankLineWanted.PRESERVE); } scan(caseTree, null); - first = false; + afterFirstToken = true; } builder.close(); builder.forcedBreak(); @@ -1954,9 +1955,9 @@ public Void visitTry(TryTree node, Void unused) { if (!node.getResources().isEmpty()) { token("("); builder.open(node.getResources().size() > 1 ? plusFour : ZERO); - boolean first = true; + boolean afterFirstToken = false; for (Tree resource : node.getResources()) { - if (!first) { + if (afterFirstToken) { builder.forcedBreak(); } if (resource instanceof VariableTree) { @@ -1981,7 +1982,7 @@ public Void visitTry(TryTree node, Void unused) { token(";"); builder.space(); } - first = false; + afterFirstToken = true; } if (builder.peekToken().equals(Optional.of(";"))) { token(";"); @@ -2070,15 +2071,15 @@ public Void visitTypeParameter(TypeParameterTree node, Void unused) { builder.open(plusFour); builder.breakOp(" "); builder.open(plusFour); - boolean first = true; + boolean afterFirstToken = false; for (Tree typeBound : node.getBounds()) { - if (!first) { + if (afterFirstToken) { builder.breakToFill(" "); token("&"); builder.space(); } scan(typeBound, null); - first = false; + afterFirstToken = true; } builder.close(); builder.close(); @@ -2134,13 +2135,13 @@ protected void visitAnnotations( if (breakBefore.isYes()) { builder.breakToFill(" "); } - boolean first = true; + boolean afterFirstToken = false; for (AnnotationTree annotation : annotations) { - if (!first) { + if (afterFirstToken) { builder.breakToFill(" "); } scan(annotation, null); - first = false; + afterFirstToken = true; } if (breakAfter.isYes()) { builder.breakToFill(" "); @@ -2220,17 +2221,17 @@ private void visitStatement( } protected void visitStatements(List statements) { - boolean first = true; + boolean afterFirstToken = false; PeekingIterator it = Iterators.peekingIterator(statements.iterator()); dropEmptyDeclarations(); while (it.hasNext()) { StatementTree tree = it.next(); builder.forcedBreak(); - if (!first) { + if (afterFirstToken) { builder.blankLineWanted(BlankLineWanted.PRESERVE); } markForPartialFormat(); - first = false; + afterFirstToken = true; List fragments = variableFragments(it, tree); if (!fragments.isEmpty()) { visitVariables( @@ -2300,17 +2301,17 @@ private ImmutableList visitModifiers( Deque declarationModifiers = new ArrayDeque<>(splitModifiers.declarationModifiers()); builder.open(ZERO); - boolean first = true; + boolean afterFirstToken = false; boolean lastWasAnnotation = false; while (!declarationModifiers.isEmpty() && !declarationModifiers.peekFirst().isModifier()) { - if (!first) { + if (afterFirstToken) { builder.addAll( annotationsDirection.isVertical() ? forceBreakList(declarationAnnotationBreak) : breakList(declarationAnnotationBreak)); } formatAnnotationOrModifier(declarationModifiers); - first = false; + afterFirstToken = true; lastWasAnnotation = true; } builder.close(); @@ -2327,13 +2328,13 @@ private ImmutableList visitModifiers( } builder.open(ZERO); - first = true; + afterFirstToken = false; while (!declarationModifiers.isEmpty()) { - if (!first) { + if (afterFirstToken) { builder.addAll(breakFillList(Optional.empty())); } formatAnnotationOrModifier(declarationModifiers); - first = false; + afterFirstToken = true; } builder.close(); builder.addAll(breakFillList(Optional.empty())); @@ -2556,14 +2557,14 @@ private void visitUnionType(VariableTree declaration) { Direction.HORIZONTAL, /* declarationAnnotationBreak= */ Optional.empty()); List union = type.getTypeAlternatives(); - boolean first = true; + boolean afterFirstToken = false; for (int i = 0; i < union.size() - 1; i++) { - if (!first) { + if (afterFirstToken) { builder.breakOp(" "); token("|"); builder.space(); } else { - first = false; + afterFirstToken = true; } scan(union.get(i), null); } @@ -2612,7 +2613,7 @@ protected void visitFormals( return; } builder.open(ZERO); - boolean first = true; + boolean afterFirstToken = false; if (receiver.isPresent()) { // TODO(user): Use builders. declareOne( @@ -2627,11 +2628,11 @@ protected void visitFormals( !parameters.isEmpty() ? Optional.of(",") : Optional.empty(), Optional.of(receiver.get().getNameExpression()), /* typeWithDims= */ Optional.empty()); - first = false; + afterFirstToken = true; } for (int i = 0; i < parameters.size(); i++) { VariableTree parameter = parameters.get(i); - if (!first) { + if (afterFirstToken) { builder.breakOp(" "); } visitToDeclare( @@ -2641,7 +2642,7 @@ protected void visitFormals( /* initializer= */ Optional.empty(), "=", i < parameters.size() - 1 ? Optional.of(",") : /* a= */ Optional.empty()); - first = false; + afterFirstToken = true; } builder.close(); } @@ -2650,14 +2651,14 @@ protected void visitFormals( private void visitThrowsClause(List thrownExceptionTypes) { token("throws"); builder.breakToFill(" "); - boolean first = true; + boolean afterFirstToken = false; for (ExpressionTree thrownExceptionType : thrownExceptionTypes) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(" "); } scan(thrownExceptionType, null); - first = false; + afterFirstToken = true; } } @@ -2721,14 +2722,14 @@ private void visitDirective( builder.space(); token(separator); builder.forcedBreak(); - boolean first = true; + boolean afterFirstToken = false; for (ExpressionTree item : items) { - if (!first) { + if (afterFirstToken) { token(","); builder.forcedBreak(); } scan(item, null); - first = false; + afterFirstToken = true; } token(";"); builder.close(); @@ -2791,13 +2792,13 @@ private void visitName(Tree node) { stack.addFirst(((MemberSelectTree) node).getIdentifier()); } stack.addFirst(((IdentifierTree) node).getName()); - boolean first = true; + boolean afterFirstToken = false; for (Name name : stack) { - if (!first) { + if (afterFirstToken) { token("."); } token(name.toString()); - first = false; + afterFirstToken = true; } } @@ -2839,14 +2840,14 @@ protected void typeParametersRest( builder.open(plusIndent); builder.breakOp(); builder.open(ZERO); - boolean first = true; + boolean afterFirstToken = false; for (TypeParameterTree typeParameter : typeParameters) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(" "); } scan(typeParameter, null); - first = false; + afterFirstToken = true; } token(">"); builder.close(); @@ -3238,14 +3239,14 @@ void addTypeArguments(List typeArguments, Indent plusIndent) { } token("<"); builder.open(plusIndent); - boolean first = true; + boolean afterFirstToken = false; for (Tree typeArgument : typeArguments) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakToFill(" "); } scan(typeArgument, null); - first = false; + afterFirstToken = true; } builder.close(); token(">"); @@ -3266,11 +3267,11 @@ void addArguments(List arguments, Indent plusIndent) { if (arguments.size() % 2 == 0 && argumentsAreTabular(arguments) == 2) { builder.forcedBreak(); builder.open(ZERO); - boolean first = true; + boolean afterFirstToken = false; for (int i = 0; i < arguments.size() - 1; i += 2) { ExpressionTree argument0 = arguments.get(i); ExpressionTree argument1 = arguments.get(i + 1); - if (!first) { + if (afterFirstToken) { token(","); builder.forcedBreak(); } @@ -3280,7 +3281,7 @@ void addArguments(List arguments, Indent plusIndent) { builder.breakOp(" "); scan(argument1, null); builder.close(); - first = false; + afterFirstToken = true; } builder.close(); } else if (isFormatMethod(arguments)) { @@ -3304,15 +3305,15 @@ void addArguments(List arguments, Indent plusIndent) { private void argList(List arguments) { builder.open(ZERO); - boolean first = true; + boolean afterFirstToken = false; FillMode fillMode = hasOnlyShortItems(arguments) ? FillMode.INDEPENDENT : FillMode.UNIFIED; for (ExpressionTree argument : arguments) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(fillMode, " ", ZERO); } scan(argument, null); - first = false; + afterFirstToken = true; } builder.close(); } @@ -3701,12 +3702,13 @@ private void declareMany(List fragments, Direction annotationDirec int baseDims = dims.size(); maybeAddDims(dims); baseDims = baseDims - dims.size(); - boolean first = true; + boolean afterFirstToken = false; for (VariableTree fragment : fragments) { - if (!first) { + if (afterFirstToken) { token(","); } - TypeWithDims fragmentDims = variableFragmentDims(first, baseDims, fragment.getType()); + TypeWithDims fragmentDims = + variableFragmentDims(afterFirstToken, baseDims, fragment.getType()); dims = new ArrayDeque<>(fragmentDims.dims); builder.breakOp(" "); builder.open(ZERO); @@ -3723,10 +3725,10 @@ private void declareMany(List fragments, Direction annotationDirec builder.close(); } builder.close(); - if (first) { + if (!afterFirstToken) { builder.close(); } - first = false; + afterFirstToken = true; } builder.close(); token(";"); @@ -3805,14 +3807,14 @@ private void classDeclarationTypeList(String token, List types) builder.open(types.size() > 1 ? plusFour : ZERO); token(token); builder.space(); - boolean first = true; + boolean afterFirstToken = false; for (Tree type : types) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(" "); } scan(type, null); - first = false; + afterFirstToken = true; } builder.close(); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java index a7b5dbc44..e502f49a1 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java @@ -55,10 +55,10 @@ public Java17InputAstVisitor(OpsBuilder builder, int indentMultiplier) { } @Override - protected void handleModule(boolean first, CompilationUnitTree node) { + protected void handleModule(boolean afterFirstToken, CompilationUnitTree node) { ModuleTree module = node.getModule(); if (module != null) { - if (!first) { + if (afterFirstToken) { builder.blankLineWanted(BlankLineWanted.YES); } markForPartialFormat(); @@ -167,14 +167,14 @@ public void visitRecordDeclaration(ClassTree node) { builder.open(node.getImplementsClause().size() > 1 ? plusFour : ZERO); token("implements"); builder.space(); - boolean first = true; + boolean afterFirstToken = false; for (Tree superInterfaceType : node.getImplementsClause()) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(" "); } scan(superInterfaceType, null); - first = false; + afterFirstToken = true; } builder.close(); } @@ -238,14 +238,14 @@ public Void visitCase(CaseTree node, Void unused) { token("case", plusTwo); builder.open(labels.size() > 1 ? plusFour : ZERO); builder.space(); - boolean first = true; + boolean afterFirstToken = false; for (Tree expression : labels) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(" "); } scan(expression, null); - first = false; + afterFirstToken = true; } builder.close(); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java index 5ef81fad6..8ab04e665 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -66,13 +66,13 @@ public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unus builder.open(plusFour); token("("); builder.breakOp(); - boolean first = true; + boolean afterFirstToken = false; for (PatternTree pattern : node.getNestedPatterns()) { - if (!first) { + if (afterFirstToken) { token(","); builder.breakOp(" "); } - first = false; + afterFirstToken = true; scan(pattern, null); } builder.close(); From 3366df281b9ed431b9c9681ddabc6392ac36c22b Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 30 Jan 2024 12:17:45 -0800 Subject: [PATCH 240/379] Update Truth version https://github.com/google/truth/releases/tag/v1.3.0 PiperOrigin-RevId: 602804747 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8b3ca51cd..453519191 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ UTF-8 1.8 32.1.3-jre - 1.1.3 + 1.3.0 3.21.2 2.16 1.9 From c20a02715cf8be569515857d96fd558eb71cfa72 Mon Sep 17 00:00:00 2001 From: cpovirk Date: Tue, 30 Jan 2024 12:47:17 -0800 Subject: [PATCH 241/379] Automatic code cleanup. PiperOrigin-RevId: 602812501 --- .../java/CommandLineOptionsParserTest.java | 6 ++-- .../GoogleJavaFormatToolProviderTest.java | 4 +-- .../java/GoogleJavaFormatToolTest.java | 4 +-- .../java/TypeNameClassifierTest.java | 31 ++++++++++--------- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java index 1a4ed09b4..2b7f3af3a 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java @@ -15,12 +15,12 @@ package com.google.googlejavaformat.java; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; +import com.google.common.truth.Truth8; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -181,11 +181,11 @@ public void paramsFile() throws IOException { @Test public void assumeFilename() { - assertThat( + Truth8.assertThat( CommandLineOptionsParser.parse(Arrays.asList("--assume-filename", "Foo.java")) .assumeFilename()) .hasValue("Foo.java"); - assertThat(CommandLineOptionsParser.parse(Arrays.asList("Foo.java")).assumeFilename()) + Truth8.assertThat(CommandLineOptionsParser.parse(Arrays.asList("Foo.java")).assumeFilename()) .isEmpty(); } diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java index 3d41a0733..3fab11770 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java @@ -15,8 +15,8 @@ package com.google.googlejavaformat.java; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; +import com.google.common.truth.Truth8; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ServiceLoader; @@ -33,7 +33,7 @@ public class GoogleJavaFormatToolProviderTest { public void testUsageOutputAfterLoadingViaToolName() { String name = "google-java-format"; - assertThat( + Truth8.assertThat( ServiceLoader.load(ToolProvider.class).stream() .map(ServiceLoader.Provider::get) .map(ToolProvider::name)) diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java index 691bb2234..e73b84cdb 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java @@ -15,9 +15,9 @@ package com.google.googlejavaformat.java; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import static java.nio.charset.StandardCharsets.UTF_8; +import com.google.common.truth.Truth8; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -35,7 +35,7 @@ public class GoogleJavaFormatToolTest { public void testUsageOutputAfterLoadingViaToolName() { String name = "google-java-format"; - assertThat( + Truth8.assertThat( ServiceLoader.load(Tool.class).stream() .map(ServiceLoader.Provider::get) .map(Tool::name)) diff --git a/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java b/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java index 3270bc64e..be47e9f4e 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java @@ -15,9 +15,9 @@ package com.google.googlejavaformat.java; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth8.assertThat; import com.google.common.base.Splitter; +import com.google.common.truth.Truth8; import com.google.googlejavaformat.java.TypeNameClassifier.JavaCaseFormat; import java.util.Optional; import org.junit.Test; @@ -52,25 +52,26 @@ private static Optional getPrefix(String qualifiedName) { @Test public void typePrefixLength() { - assertThat(getPrefix("fieldName")).isEmpty(); - assertThat(getPrefix("CONST")).isEmpty(); - assertThat(getPrefix("ClassName")).hasValue(0); - assertThat(getPrefix("com.ClassName")).hasValue(1); - assertThat(getPrefix("ClassName.foo")).hasValue(1); - assertThat(getPrefix("com.ClassName.foo")).hasValue(2); - assertThat(getPrefix("ClassName.foo.bar")).hasValue(1); - assertThat(getPrefix("com.ClassName.foo.bar")).hasValue(2); - assertThat(getPrefix("ClassName.CONST")).hasValue(1); - assertThat(getPrefix("ClassName.varName")).hasValue(1); - assertThat(getPrefix("ClassName.Inner.varName")).hasValue(2); - assertThat(getPrefix("com.R.foo")).hasValue(2); + Truth8.assertThat(getPrefix("fieldName")).isEmpty(); + Truth8.assertThat(getPrefix("CONST")).isEmpty(); + Truth8.assertThat(getPrefix("ClassName")).hasValue(0); + Truth8.assertThat(getPrefix("com.ClassName")).hasValue(1); + Truth8.assertThat(getPrefix("ClassName.foo")).hasValue(1); + Truth8.assertThat(getPrefix("com.ClassName.foo")).hasValue(2); + Truth8.assertThat(getPrefix("ClassName.foo.bar")).hasValue(1); + Truth8.assertThat(getPrefix("com.ClassName.foo.bar")).hasValue(2); + Truth8.assertThat(getPrefix("ClassName.CONST")).hasValue(1); + Truth8.assertThat(getPrefix("ClassName.varName")).hasValue(1); + Truth8.assertThat(getPrefix("ClassName.Inner.varName")).hasValue(2); + Truth8.assertThat(getPrefix("com.R.foo")).hasValue(2); } @Test public void ambiguousClass() { - assertThat(getPrefix("com.google.security.acl.proto2api.ACL.Entry.newBuilder")).hasValue(7); + Truth8.assertThat(getPrefix("com.google.security.acl.proto2api.ACL.Entry.newBuilder")) + .hasValue(7); // A human would probably identify this as "class-shaped", but just looking // at the case we have to assume it could be something like `field1.field2.CONST`. - assertThat(getPrefix("com.google.security.acl.proto2api.ACL.newBuilder")).isEmpty(); + Truth8.assertThat(getPrefix("com.google.security.acl.proto2api.ACL.newBuilder")).isEmpty(); } } From e260fa9ca1ec69a0aa2d2ac658b5084f079ad7bf Mon Sep 17 00:00:00 2001 From: cpovirk Date: Mon, 5 Feb 2024 11:13:48 -0800 Subject: [PATCH 242/379] Update Truth to [1.4.0](https://github.com/google/truth/releases/tag/v1.4.0). PiperOrigin-RevId: 604375179 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 453519191..c6dc8bafd 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ UTF-8 1.8 32.1.3-jre - 1.3.0 + 1.4.0 3.21.2 2.16 1.9 From f0a6b1478ad43df32e9e5c16f847deedee4658f2 Mon Sep 17 00:00:00 2001 From: cpovirk Date: Tue, 6 Feb 2024 12:11:12 -0800 Subject: [PATCH 243/379] Automatic code cleanup. PiperOrigin-RevId: 604725069 --- .../java/CommandLineOptionsParserTest.java | 5 ++-- .../GoogleJavaFormatToolProviderTest.java | 3 +- .../java/GoogleJavaFormatToolTest.java | 3 +- .../java/TypeNameClassifierTest.java | 30 +++++++++---------- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java index 2b7f3af3a..08fbbbab3 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java @@ -20,7 +20,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; -import com.google.common.truth.Truth8; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -181,11 +180,11 @@ public void paramsFile() throws IOException { @Test public void assumeFilename() { - Truth8.assertThat( + assertThat( CommandLineOptionsParser.parse(Arrays.asList("--assume-filename", "Foo.java")) .assumeFilename()) .hasValue("Foo.java"); - Truth8.assertThat(CommandLineOptionsParser.parse(Arrays.asList("Foo.java")).assumeFilename()) + assertThat(CommandLineOptionsParser.parse(Arrays.asList("Foo.java")).assumeFilename()) .isEmpty(); } diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java index 3fab11770..461bd6793 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolProviderTest.java @@ -16,7 +16,6 @@ import static com.google.common.truth.Truth.assertThat; -import com.google.common.truth.Truth8; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ServiceLoader; @@ -33,7 +32,7 @@ public class GoogleJavaFormatToolProviderTest { public void testUsageOutputAfterLoadingViaToolName() { String name = "google-java-format"; - Truth8.assertThat( + assertThat( ServiceLoader.load(ToolProvider.class).stream() .map(ServiceLoader.Provider::get) .map(ToolProvider::name)) diff --git a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java index e73b84cdb..e3a7573a7 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/GoogleJavaFormatToolTest.java @@ -17,7 +17,6 @@ import static com.google.common.truth.Truth.assertThat; import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.common.truth.Truth8; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -35,7 +34,7 @@ public class GoogleJavaFormatToolTest { public void testUsageOutputAfterLoadingViaToolName() { String name = "google-java-format"; - Truth8.assertThat( + assertThat( ServiceLoader.load(Tool.class).stream() .map(ServiceLoader.Provider::get) .map(Tool::name)) diff --git a/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java b/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java index be47e9f4e..6d7e5666c 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/TypeNameClassifierTest.java @@ -17,7 +17,6 @@ import static com.google.common.truth.Truth.assertThat; import com.google.common.base.Splitter; -import com.google.common.truth.Truth8; import com.google.googlejavaformat.java.TypeNameClassifier.JavaCaseFormat; import java.util.Optional; import org.junit.Test; @@ -52,26 +51,25 @@ private static Optional getPrefix(String qualifiedName) { @Test public void typePrefixLength() { - Truth8.assertThat(getPrefix("fieldName")).isEmpty(); - Truth8.assertThat(getPrefix("CONST")).isEmpty(); - Truth8.assertThat(getPrefix("ClassName")).hasValue(0); - Truth8.assertThat(getPrefix("com.ClassName")).hasValue(1); - Truth8.assertThat(getPrefix("ClassName.foo")).hasValue(1); - Truth8.assertThat(getPrefix("com.ClassName.foo")).hasValue(2); - Truth8.assertThat(getPrefix("ClassName.foo.bar")).hasValue(1); - Truth8.assertThat(getPrefix("com.ClassName.foo.bar")).hasValue(2); - Truth8.assertThat(getPrefix("ClassName.CONST")).hasValue(1); - Truth8.assertThat(getPrefix("ClassName.varName")).hasValue(1); - Truth8.assertThat(getPrefix("ClassName.Inner.varName")).hasValue(2); - Truth8.assertThat(getPrefix("com.R.foo")).hasValue(2); + assertThat(getPrefix("fieldName")).isEmpty(); + assertThat(getPrefix("CONST")).isEmpty(); + assertThat(getPrefix("ClassName")).hasValue(0); + assertThat(getPrefix("com.ClassName")).hasValue(1); + assertThat(getPrefix("ClassName.foo")).hasValue(1); + assertThat(getPrefix("com.ClassName.foo")).hasValue(2); + assertThat(getPrefix("ClassName.foo.bar")).hasValue(1); + assertThat(getPrefix("com.ClassName.foo.bar")).hasValue(2); + assertThat(getPrefix("ClassName.CONST")).hasValue(1); + assertThat(getPrefix("ClassName.varName")).hasValue(1); + assertThat(getPrefix("ClassName.Inner.varName")).hasValue(2); + assertThat(getPrefix("com.R.foo")).hasValue(2); } @Test public void ambiguousClass() { - Truth8.assertThat(getPrefix("com.google.security.acl.proto2api.ACL.Entry.newBuilder")) - .hasValue(7); + assertThat(getPrefix("com.google.security.acl.proto2api.ACL.Entry.newBuilder")).hasValue(7); // A human would probably identify this as "class-shaped", but just looking // at the case we have to assume it could be something like `field1.field2.CONST`. - Truth8.assertThat(getPrefix("com.google.security.acl.proto2api.ACL.newBuilder")).isEmpty(); + assertThat(getPrefix("com.google.security.acl.proto2api.ACL.newBuilder")).isEmpty(); } } From ca02b8dbbf80412321f56b63a982319b95ad92c1 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Fri, 9 Feb 2024 21:38:12 +0100 Subject: [PATCH 244/379] Remove un-used GitHub Action Parameter The https://github.com/oracle-actions/setup-java/tree/v1/?tab=readme-ov-file#input-overview does not have a "cache" parameter (like https://github.com/actions/setup-java/tree/v4/?tab=readme-ov-file#usage does). --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51ecf6e80..6a2f986b4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,6 @@ jobs: with: website: jdk.java.net release: ${{ matrix.java }} - cache: 'maven' - name: 'Set up JDK ${{ matrix.java }}' if: ${{ matrix.java != 'EA' }} uses: actions/setup-java@v4 From 297dda474899fa380acd579ba48ff8f269bc9a48 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Fri, 9 Feb 2024 17:00:53 -0800 Subject: [PATCH 245/379] docs: Add link to a VSC Extension to README (fixes #488) There are a bunch of these; I've had a a bit of a closer look at them the other day, and this one appears to be the most up-to-date, actively maintained, and contrary to the the other more popular by stars older ones seems easy to use because it doesn't require anything to be externally pre-installed but just download from this project's GitHub releases; that's why I'm proposing adding this one. This fixes #488. @cushon LGTY? Fixes #1043 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1043 from vorburger:patch-3 e48524b986133d05e9331bdfc9be75349a6f39df PiperOrigin-RevId: 605769445 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4fe0e2126..38fdac5e8 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ## Using the formatter -### from the command-line +### From the command-line [Download the formatter](https://github.com/google/google-java-format/releases) and run it with: @@ -78,6 +78,8 @@ Implementation`. ### Third-party integrations +* Visual Studio Code + * [google-java-format-for-vs-code](https://marketplace.visualstudio.com/items?itemName=JoseVSeb.google-java-format-for-vs-code) * Gradle plugins * [spotless](https://github.com/diffplug/spotless/tree/main/plugin-gradle#google-java-format) * [sherter/google-java-format-gradle-plugin](https://github.com/sherter/google-java-format-gradle-plugin) From 84582bf73fef63b7ffe7fa8d7bb8e7cdab3c73eb Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Sat, 10 Feb 2024 11:43:50 +0000 Subject: [PATCH 246/379] Mechanically reformat GitHub Actions YAML https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-github-actions proposes this format as the "canonical" one. Adopting this makes it easier to contribute to this project by using that VSC Extension as an editor. This change is purely mechanical and contains no other "semantic" differences. --- .github/workflows/ci.yml | 36 +++++++++++++++++------------------ .github/workflows/release.yml | 10 ++++------ 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a2f986b4..f5457cb9d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,10 +17,10 @@ name: CI on: push: branches: - - master + - master pull_request: branches: - - master + - master jobs: test: @@ -28,9 +28,9 @@ jobs: strategy: fail-fast: false matrix: - os: [ ubuntu-latest ] - java: [ 21, 17, 11 ] - experimental: [ false ] + os: [ubuntu-latest] + java: [21, 17, 11] + experimental: [false] include: # Only test on macos and windows with a single recent JDK to avoid a # combinatorial explosion of test configurations. @@ -50,46 +50,46 @@ jobs: uses: styfle/cancel-workflow-action@0.9.1 with: access_token: ${{ github.token }} - - name: 'Check out repository' + - name: "Check out repository" uses: actions/checkout@v4 - - name: 'Set up JDK ${{ matrix.java }} from jdk.java.net' + - name: "Set up JDK ${{ matrix.java }} from jdk.java.net" if: ${{ matrix.java == 'EA' }} uses: oracle-actions/setup-java@v1 with: website: jdk.java.net release: ${{ matrix.java }} - - name: 'Set up JDK ${{ matrix.java }}' + - name: "Set up JDK ${{ matrix.java }}" if: ${{ matrix.java != 'EA' }} uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} - distribution: 'zulu' - cache: 'maven' - - name: 'Install' + distribution: "zulu" + cache: "maven" + - name: "Install" shell: bash run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V - - name: 'Test' + - name: "Test" shell: bash run: mvn test -B publish_snapshot: - name: 'Publish snapshot' + name: "Publish snapshot" needs: test if: github.event_name == 'push' && github.repository == 'google/google-java-format' && github.ref == 'refs/heads/master' runs-on: ubuntu-latest steps: - - name: 'Check out repository' + - name: "Check out repository" uses: actions/checkout@v4 - - name: 'Set up JDK 17' + - name: "Set up JDK 17" uses: actions/setup-java@v4 with: java-version: 17 - distribution: 'zulu' - cache: 'maven' + distribution: "zulu" + cache: "maven" server-id: sonatype-nexus-snapshots server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD - - name: 'Publish' + - name: "Publish" env: CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cf50d61c6..717e6fd6a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,8 +20,8 @@ jobs: uses: actions/setup-java@v4 with: java-version: 21 - distribution: 'zulu' - cache: 'maven' + distribution: "zulu" + cache: "maven" server-id: sonatype-nexus-staging server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD @@ -46,12 +46,10 @@ jobs: CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} CI_DEPLOY_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }} GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - run: - mvn --no-transfer-progress -pl '!eclipse_plugin' -P sonatype-oss-release clean deploy -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" + run: mvn --no-transfer-progress -pl '!eclipse_plugin' -P sonatype-oss-release clean deploy -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" - name: Build Eclipse plugin - run: - mvn --no-transfer-progress -pl 'eclipse_plugin' verify gpg:sign -DskipTests=true -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" + run: mvn --no-transfer-progress -pl 'eclipse_plugin' verify gpg:sign -DskipTests=true -Dgpg.passphrase="${{ secrets.GPG_PASSPHRASE }}" - name: Push tag run: | From 9e11f30c389d3a9bd8139792466d523375c4842c Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Sat, 10 Feb 2024 11:46:54 +0000 Subject: [PATCH 247/379] Add missing ASL (license) to GitHub Actions --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5457cb9d..9da84de0b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -# Copyright 2020 The Error Prone Authors. +# Copyright 2020 The Google Java Format Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 717e6fd6a..a0bf2c6c8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,17 @@ +# Copyright 2020 The Google Java Format Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + name: Release google-java-format on: From 77cb16857ca88d2a16295b8c81ae4b1cbb3aeca0 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Sun, 11 Feb 2024 11:13:33 -0800 Subject: [PATCH 248/379] Bump native-maven-plugin from 0.9.13 to 0.10.0 (latest) @cushon perhaps merge this separately already? Fixes #1051 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1051 from vorburger:patch-5 7520ec5f784c47a39726ca2ef1eb81c89c7cdfc4 PiperOrigin-RevId: 606060781 --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index d1363fed1..60add52d1 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -282,7 +282,7 @@ org.graalvm.buildtools native-maven-plugin - 0.9.13 + 0.10.0 true From 3d9c8fa1cd6eff1f3bd94c6e367501a622088d59 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Sat, 10 Feb 2024 11:39:29 +0000 Subject: [PATCH 249/379] Build native binary in CI (fixes google#894) --- .github/workflows/ci.yml | 23 +++++++++++++++++++---- .github/workflows/release.yml | 4 ++-- util/test-native.sh | 30 ++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100755 util/test-native.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9da84de0b..e03234959 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,10 +29,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - java: [21, 17, 11] + java: [GraalVM, 21, 17, 11] experimental: [false] include: - # Only test on macos and windows with a single recent JDK to avoid a + # Only test on MacOS and Windows with a single recent JDK to avoid a # combinatorial explosion of test configurations. - os: macos-latest java: 21 @@ -43,6 +43,9 @@ jobs: - os: ubuntu-latest java: EA experimental: true + - os: ubuntu-latest + java: GraalVM + experimental: false runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} steps: @@ -58,19 +61,31 @@ jobs: with: website: jdk.java.net release: ${{ matrix.java }} - - name: "Set up JDK ${{ matrix.java }}" - if: ${{ matrix.java != 'EA' }} + - name: "Set up JDK ${{ matrix.java }} from Zulu" + if: ${{ matrix.java != 'EA' && matrix.java != 'GraalVM' }} uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} distribution: "zulu" cache: "maven" + - name: "Set up JDK ${{ matrix.java }}" + if: ${{ matrix.java == 'GraalVM' }} + uses: graalvm/setup-graalvm@v1 + with: + java-version: "21" + distribution: "graalvm-community" + github-token: ${{ secrets.GITHUB_TOKEN }} + native-image-job-reports: "true" + cache: "maven" - name: "Install" shell: bash run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V - name: "Test" shell: bash run: mvn test -B + - name: "Native" + if: ${{ matrix.java == 'GraalVM' }} + run: mvn -Pnative -DskipTests package -pl core -am && util/test-native.sh publish_snapshot: name: "Publish snapshot" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a0bf2c6c8..cf57f3e94 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -69,7 +69,7 @@ jobs: run: | git push origin "v${{ github.event.inputs.version }}" - - name: Add Jars to Release Entry + - name: Add Artifacts to Release Entry uses: softprops/action-gh-release@v0.1.14 with: draft: true @@ -77,5 +77,5 @@ jobs: tag_name: "v${{ github.event.inputs.version }}" target_commitish: ${{ env.TARGET_COMMITISH }} files: | - core/target/google-java-format-*.jar + core/target/google-java-format* eclipse_plugin/target/google-java-format-eclipse-plugin-*.jar diff --git a/util/test-native.sh b/util/test-native.sh new file mode 100755 index 000000000..a8643baf2 --- /dev/null +++ b/util/test-native.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2024 The Google Java Format Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euox pipefail + +time java -jar core/target/google-java-format-*-all-deps.jar || true + +status=-1 +chmod +x core/target/google-java-format +if time core/target/google-java-format; then + status=0 +else + status=$? +fi +if [[ $status -ne 2 ]]; then + echo "google-java-format_linux (native) without arguments should have printed usage help and exited with 2, but did not :(" + exit 1 +fi From ea57ad1e2a291ca1582aa76925b089077a610db5 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Sun, 11 Feb 2024 20:53:16 +0000 Subject: [PATCH 250/379] Refactor CI to run GraalVM native build in separate job --- .github/workflows/ci.yml | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e03234959..0c8cc2b58 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,13 +23,13 @@ on: - master jobs: - test: + test-OpenJDK: name: "JDK ${{ matrix.java }} on ${{ matrix.os }}" strategy: fail-fast: false matrix: os: [ubuntu-latest] - java: [GraalVM, 21, 17, 11] + java: [21, 17, 11] experimental: [false] include: # Only test on MacOS and Windows with a single recent JDK to avoid a @@ -43,9 +43,6 @@ jobs: - os: ubuntu-latest java: EA experimental: true - - os: ubuntu-latest - java: GraalVM - experimental: false runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.experimental }} steps: @@ -83,6 +80,31 @@ jobs: - name: "Test" shell: bash run: mvn test -B + + test-OpenJDK: + name: "GraalVM on ${{ matrix.os }}" + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + continue-on-error: ${{ matrix.experimental }} + steps: + - name: Cancel previous + uses: styfle/cancel-workflow-action@0.9.1 + with: + access_token: ${{ github.token }} + - name: "Check out repository" + uses: actions/checkout@v4 + - name: "Set up GraalVM ${{ matrix.java }}" + if: ${{ matrix.java == 'GraalVM' }} + uses: graalvm/setup-graalvm@v1 + with: + java-version: "21" + distribution: "graalvm-community" + github-token: ${{ secrets.GITHUB_TOKEN }} + native-image-job-reports: "true" + cache: "maven" - name: "Native" if: ${{ matrix.java == 'GraalVM' }} run: mvn -Pnative -DskipTests package -pl core -am && util/test-native.sh From 6cf0e35c956461204c8dbc90895ea4d53800010a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sun, 11 Feb 2024 14:51:05 -0800 Subject: [PATCH 251/379] Update ci.yml Fix some typos--update references from `test` to `test-OpenJDK`, remove a stale reference to `matrix.experimental` from GraalVM tests --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0c8cc2b58..322f914e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,14 +81,14 @@ jobs: shell: bash run: mvn test -B - test-OpenJDK: + test-GraalVM: name: "GraalVM on ${{ matrix.os }}" strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} - continue-on-error: ${{ matrix.experimental }} + continue-on-error: true steps: - name: Cancel previous uses: styfle/cancel-workflow-action@0.9.1 @@ -111,7 +111,7 @@ jobs: publish_snapshot: name: "Publish snapshot" - needs: test + needs: test-OpenJDK if: github.event_name == 'push' && github.repository == 'google/google-java-format' && github.ref == 'refs/heads/master' runs-on: ubuntu-latest steps: From 1ae69f9424e9c77611c893c9917993a4d31f6833 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sun, 11 Feb 2024 14:54:36 -0800 Subject: [PATCH 252/379] Remove obsolete test for matrix.java == 'GraalVM' --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 322f914e0..ff402eff4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,6 @@ jobs: - name: "Check out repository" uses: actions/checkout@v4 - name: "Set up GraalVM ${{ matrix.java }}" - if: ${{ matrix.java == 'GraalVM' }} uses: graalvm/setup-graalvm@v1 with: java-version: "21" @@ -106,7 +105,6 @@ jobs: native-image-job-reports: "true" cache: "maven" - name: "Native" - if: ${{ matrix.java == 'GraalVM' }} run: mvn -Pnative -DskipTests package -pl core -am && util/test-native.sh publish_snapshot: From ad089da9736bc849454e793226cdc8f1f9fa6d12 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 12 Feb 2024 16:02:26 -0800 Subject: [PATCH 253/379] Handle 'any' patterns Fixes https://github.com/google/google-java-format/issues/1037 PiperOrigin-RevId: 606394473 --- .../java/java21/Java21InputAstVisitor.java | 18 +++++++++++ .../java/FormatterIntegrationTest.java | 3 +- .../java/testdata/I1037.input | 11 +++++++ .../java/testdata/I1037.output | 11 +++++++ util/test-native.sh | 30 ------------------- 5 files changed, 42 insertions(+), 31 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I1037.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I1037.output delete mode 100755 util/test-native.sh diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java index 8ab04e665..2192a32a9 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -24,6 +24,8 @@ import com.sun.source.tree.PatternCaseLabelTree; import com.sun.source.tree.PatternTree; import com.sun.source.tree.StringTemplateTree; +import com.sun.source.tree.Tree; +import com.sun.tools.javac.tree.JCTree; import javax.lang.model.element.Name; /** @@ -107,4 +109,20 @@ protected void variableName(Name name) { visit(name); } } + + @Override + public Void scan(Tree tree, Void unused) { + // Pre-visit AST for preview features, since com.sun.source.tree.AnyPattern can't be + // accessed directly without --enable-preview. + if (tree instanceof JCTree.JCAnyPattern) { + visitJcAnyPattern((JCTree.JCAnyPattern) tree); + return null; + } else { + return super.scan(tree, unused); + } + } + + private void visitJcAnyPattern(JCTree.JCAnyPattern unused) { + token("_"); + } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 26493b022..15a6e75f9 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -62,7 +62,8 @@ public class FormatterIntegrationTest { "Unnamed", "I981", "StringTemplate", - "I1020") + "I1020", + "I1037") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1037.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1037.input new file mode 100644 index 000000000..ed39459dd --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1037.input @@ -0,0 +1,11 @@ +public sealed interface A { + record AA(Long a) implements A {} + + static Long mySwitch(A a) { + switch (a) { + case AA(_) -> { + return 1L; + } + } + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1037.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1037.output new file mode 100644 index 000000000..ed39459dd --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1037.output @@ -0,0 +1,11 @@ +public sealed interface A { + record AA(Long a) implements A {} + + static Long mySwitch(A a) { + switch (a) { + case AA(_) -> { + return 1L; + } + } + } +} diff --git a/util/test-native.sh b/util/test-native.sh deleted file mode 100755 index a8643baf2..000000000 --- a/util/test-native.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2024 The Google Java Format Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -euox pipefail - -time java -jar core/target/google-java-format-*-all-deps.jar || true - -status=-1 -chmod +x core/target/google-java-format -if time core/target/google-java-format; then - status=0 -else - status=$? -fi -if [[ $status -ne 2 ]]; then - echo "google-java-format_linux (native) without arguments should have printed usage help and exited with 2, but did not :(" - exit 1 -fi From c5c3deb61f7e6a848bdf4943dcc59fc1d505b16d Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Tue, 13 Feb 2024 09:29:52 -0800 Subject: [PATCH 254/379] Add `util/test-native.sh` from https://github.com/google/google-java-format/pull/1048 PiperOrigin-RevId: 606648629 --- util/test-native.sh | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 util/test-native.sh diff --git a/util/test-native.sh b/util/test-native.sh new file mode 100644 index 000000000..a8643baf2 --- /dev/null +++ b/util/test-native.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# Copyright 2024 The Google Java Format Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euox pipefail + +time java -jar core/target/google-java-format-*-all-deps.jar || true + +status=-1 +chmod +x core/target/google-java-format +if time core/target/google-java-format; then + status=0 +else + status=$? +fi +if [[ $status -ne 2 ]]; then + echo "google-java-format_linux (native) without arguments should have printed usage help and exited with 2, but did not :(" + exit 1 +fi From 6b4828af0fc0b82c1132f1119fc722208cab53d2 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Tue, 13 Feb 2024 12:12:14 -0800 Subject: [PATCH 255/379] Fix chmod +x util/test-native.sh which Copybara broke @cushon Fixes #1059 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1059 from vorburger:chmod-test-native 27966592f76074dcb377517bdeea5d648097b358 PiperOrigin-RevId: 606705116 --- util/test-native.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 util/test-native.sh diff --git a/util/test-native.sh b/util/test-native.sh old mode 100644 new mode 100755 From 59b09facf3f606b25290ba5070de8a4f81d46ea8 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Tue, 13 Feb 2024 12:14:46 -0800 Subject: [PATCH 256/379] Bump Maven JavaDoc plugin from 3.4.0 to 3.6.3 to fix build failure [This build](https://github.com/google/google-java-format/actions/runs/7891365432/job/21535541300?pr=1060) for #1060 failed on (only) Windows under GraalVM for Native and I suspect that this change may fix this problem: ``` Error: Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:3.4.0:jar (attach-javadocs) on project google-java-format: MavenReportException: Error while generating Javadoc: Error: Exit code: 1 - Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\CloseOp.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\CommentsHelper.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\Doc.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\DocBuilder.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\FormatterDiagnostic.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\FormattingError.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\Indent.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\Input.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\InputOutput.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\CommandLineOptions.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\CommandLineOptionsParser.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\DimensionHelpers.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\filer\FormattingFiler.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\filer\FormattingJavaFileObject.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\FormatFileCallable.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\Formatter.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\FormatterException.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\GoogleJavaFormatTool.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\GoogleJavaFormatToolProvider.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\ImportOrderer.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\java17\Java17InputAstVisitor.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\java21\Java21InputAstVisitor.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\JavaCommentsHelper.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\JavacTokens.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\javadoc\CharStream.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\javadoc\JavadocFormatter.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\javadoc\JavadocLexer.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\javadoc\JavadocWriter.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\javadoc\NestingCounter.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\javadoc\Token.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\JavaFormatterOptions.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\JavaInput.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\JavaInputAstVisitor.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\JavaOutput.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\Main.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\ModifierOrderer.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\RemoveUnusedImports.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\Replacement.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\SnippetFormatter.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\StringWrapper.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\Trees.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\TypeNameClassifier.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\UsageException.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\Newlines.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\Op.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\OpenOp.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\OpsBuilder.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\Output.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\target\generated-sources\java\com\google\googlejavaformat\java\GoogleJavaFormatVersion.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\target\generated-sources\annotations\com\google\googlejavaformat\java\AutoOneOf_JavaInputAstVisitor_AnnotationOrModifier.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\target\generated-sources\annotations\com\google\googlejavaformat\java\AutoValue_FormatFileCallable_Result.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\target\generated-sources\annotations\com\google\googlejavaformat\java\AutoValue_JavaFormatterOptions.java... Error: Loading source file D:\a\google-java-format\google-java-format\core\target\generated-sources\annotations\com\google\googlejavaformat\java\AutoValue_JavaInputAstVisitor_DeclarationModifiersAndTypeAnnotations.java... Error: Loading source files for package com.google.googlejavaformat... Error: Loading source files for package com.google.googlejavaformat.java... Error: Loading source files for package com.google.googlejavaformat.java.filer... Error: Loading source files for package com.google.googlejavaformat.java.java17... Error: Loading source files for package com.google.googlejavaformat.java.java21... Error: Loading source files for package com.google.googlejavaformat.java.javadoc... Error: Constructing Javadoc information... Error: D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\DimensionHelpers.java:18: error: package com.sun.source.tree is not visible Error: import com.sun.source.tree.AnnotatedTypeTree; Error: ^ Error: (package com.sun.source.tree is declared in module jdk.compiler, but module com.google.googlejavaformat does not read it) Error: D:\a\google-java-format\google-java-format\core\src\main\java\com\google\googlejavaformat\java\DimensionHelpers.java:19: error: package com.sun.source.tree is not visible Error: import com.sun.source.tree.AnnotationTree; (...) ``` @cushon @cpovirk merge? Fixes #1061 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1061 from vorburger:maven-javadoc-plugin c3c4b6fcc2f7a448aa0329754dcc0b685566b153 PiperOrigin-RevId: 606705880 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index c6dc8bafd..2b426cee1 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ 2.16 1.9 1.0.1 - 3.4.0 + 3.6.3 3.2.1
@@ -172,7 +172,7 @@ maven-javadoc-plugin - 3.4.0 + ${maven-javadoc-plugin.version} maven-gpg-plugin @@ -260,7 +260,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.4.0 + ${maven-javadoc-plugin.version} none From b9b41faf47e13692c02a517ea9ebe7d173fe7374 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Tue, 13 Feb 2024 18:51:59 +0000 Subject: [PATCH 257/379] Add Windows native build --- .github/workflows/ci.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff402eff4..ab0ebf024 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,7 +86,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} continue-on-error: true steps: @@ -104,8 +104,13 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} native-image-job-reports: "true" cache: "maven" - - name: "Native" - run: mvn -Pnative -DskipTests package -pl core -am && util/test-native.sh + - name: "Native Build" + run: mvn -Pnative -DskipTests package -pl core -am + - name: "Native Test" + # Bash script for testing won't work on Windows + # TODO: Anyone reading this wants to write a *.bat or *.ps1 equivalent? + if: ${{ matrix.os != 'windows-latest' }} + run: util/test-native.sh publish_snapshot: name: "Publish snapshot" From 9851a393fede8821489317d54e5bf02e6dc0bf72 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 12 Feb 2024 16:09:19 -0800 Subject: [PATCH 258/379] Generate native-image binaries for google-java-format And include them in release artifacts. I tested this on my fork of the repo, and have a demo here: https://github.com/cushon/google-java-format/releases When downloading the artifacts from the releases page they don't have the executable bit set, and my Mac blocks them because they aren't signed. That can be worked around with the following, but isn't ideal: ``` chmod a+rx google-java-format-darwin sudo xattr -r -d com.apple.quarantine google-java-format-darwin ``` Progress towards #868 --- .github/workflows/release.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cf57f3e94..3dafd8cd3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -79,3 +79,31 @@ jobs: files: | core/target/google-java-format* eclipse_plugin/target/google-java-format-eclipse-plugin-*.jar + + build-native-image: + name: "Build GraalVM native-image on ${{ matrix.os }}" + runs-on: ${{ matrix.os }} + needs: build-maven-jars + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + steps: + - name: "Check out repository" + uses: actions/checkout@v4 + - name: "Set up GraalVM" + uses: graalvm/setup-graalvm@v1 + with: + java-version: "21" + distribution: "graalvm-community" + github-token: ${{ secrets.GITHUB_TOKEN }} + native-image-job-reports: "true" + cache: "maven" + - name: "Native" + run: mvn -Pnative -DskipTests package -pl core -am + - name: "Move outputs" + run: cp core/target/google-java-format google-java-format-${{ matrix.os == 'ubuntu-latest' && 'linux' || 'darwin' }} + - name: "Upload native-image" + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + run: gh release upload "v${{ github.event.inputs.version }}" "google-java-format-${{ matrix.os == 'ubuntu-latest' && 'linux' || 'darwin' }}" From 4e9aa25d91968d6b7bd01482e06eaf12b2ff20cd Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 15 Feb 2024 12:39:24 -0800 Subject: [PATCH 259/379] Update .github/workflows/release.yml Co-authored-by: Michael Vorburger --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3dafd8cd3..0848c869d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,7 +86,7 @@ jobs: needs: build-maven-jars strategy: matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] steps: - name: "Check out repository" uses: actions/checkout@v4 From 0bc08ab915eaee7cb6063fe2963df4108e5b84f4 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 15 Feb 2024 12:55:20 -0800 Subject: [PATCH 260/379] Update release.yml --- .github/workflows/release.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0848c869d..e1f94aaa0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -87,6 +87,8 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] + env: + SUFFIX: ${{fromJson('{"ubuntu-latest":"linux-x86_64", "macos-latest":"darwin-arm64", "windows-latest":"windows_x86-64"}')[matrix.os]}} steps: - name: "Check out repository" uses: actions/checkout@v4 @@ -101,9 +103,9 @@ jobs: - name: "Native" run: mvn -Pnative -DskipTests package -pl core -am - name: "Move outputs" - run: cp core/target/google-java-format google-java-format-${{ matrix.os == 'ubuntu-latest' && 'linux' || 'darwin' }} + run: cp core/target/google-java-format google-java-format-${{ env.SUFFIX }} - name: "Upload native-image" env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} - run: gh release upload "v${{ github.event.inputs.version }}" "google-java-format-${{ matrix.os == 'ubuntu-latest' && 'linux' || 'darwin' }}" + run: gh release upload "v${{ github.event.inputs.version }}" "google-java-format-${{ env.SUFFIX }}" From 865cdf873e13be398f6346bb54b7be5fd58c1498 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 16 Feb 2024 08:25:46 -0800 Subject: [PATCH 261/379] Apply suggestions from code review Co-authored-by: Michael Vorburger --- .github/workflows/release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e1f94aaa0..36c0eb59d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -88,7 +88,7 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] env: - SUFFIX: ${{fromJson('{"ubuntu-latest":"linux-x86_64", "macos-latest":"darwin-arm64", "windows-latest":"windows_x86-64"}')[matrix.os]}} + SUFFIX: ${{fromJson('{"ubuntu-latest":"linux-x86-64", "macos-latest":"darwin-arm64", "windows-latest":"windows-x86-64"}')[matrix.os]}} steps: - name: "Check out repository" uses: actions/checkout@v4 @@ -103,9 +103,9 @@ jobs: - name: "Native" run: mvn -Pnative -DskipTests package -pl core -am - name: "Move outputs" - run: cp core/target/google-java-format google-java-format-${{ env.SUFFIX }} + run: cp core/target/google-java-format google-java-format_${{ env.SUFFIX }} - name: "Upload native-image" env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} - run: gh release upload "v${{ github.event.inputs.version }}" "google-java-format-${{ env.SUFFIX }}" + run: gh release upload "v${{ github.event.inputs.version }}" "google-java-format_${{ env.SUFFIX }}" From 250fa9be7ae921b80c64d3bfe046faff8f3d0009 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 16 Feb 2024 14:37:19 -0800 Subject: [PATCH 262/379] Update release.yml Only update `.jar` files from main build This un-does a change made in anticipation of uploading native image artifacts, but they are uploaded by separate steps, and we want to exclude other outputs the maven build generates. --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 36c0eb59d..904a8c3be 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -77,7 +77,7 @@ jobs: tag_name: "v${{ github.event.inputs.version }}" target_commitish: ${{ env.TARGET_COMMITISH }} files: | - core/target/google-java-format* + core/target/google-java-format-*.jar eclipse_plugin/target/google-java-format-eclipse-plugin-*.jar build-native-image: From 910586c6390861c448ab7b69fe0fe88a803012dd Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 16 Feb 2024 14:56:00 -0800 Subject: [PATCH 263/379] Handle `.exe` extensions for windows native-image --- .github/workflows/release.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 904a8c3be..2f309026b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -89,6 +89,7 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] env: SUFFIX: ${{fromJson('{"ubuntu-latest":"linux-x86-64", "macos-latest":"darwin-arm64", "windows-latest":"windows-x86-64"}')[matrix.os]}} + EXTENSION: ${{ matrix.os == 'windows-latest' && '.exe' || '' }} steps: - name: "Check out repository" uses: actions/checkout@v4 @@ -103,9 +104,9 @@ jobs: - name: "Native" run: mvn -Pnative -DskipTests package -pl core -am - name: "Move outputs" - run: cp core/target/google-java-format google-java-format_${{ env.SUFFIX }} + run: cp core/target/google-java-format${{ env.EXTENSION }} google-java-format_${{ env.SUFFIX }}${{ env.EXTENSION }} - name: "Upload native-image" env: GH_TOKEN: ${{ github.token }} GH_REPO: ${{ github.repository }} - run: gh release upload "v${{ github.event.inputs.version }}" "google-java-format_${{ env.SUFFIX }}" + run: gh release upload "v${{ github.event.inputs.version }}" "google-java-format_${{ env.SUFFIX }}${{ env.EXTENSION }}" From 571c2b6ea232e295158154c9fbd6ef18f9e97942 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 16 Feb 2024 16:38:04 -0800 Subject: [PATCH 264/379] Update maven native-image configuration for google-java-format PiperOrigin-RevId: 607835047 --- core/pom.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 60add52d1..064f9dee8 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -288,7 +288,7 @@ build-native - build + compile-no-fork package @@ -306,9 +306,19 @@ ${project.build.directory}/${project.artifactId}-${project.version}-all-deps.jar + -H:+UnlockExperimentalVMOptions -H:IncludeResourceBundles=com.sun.tools.javac.resources.compiler + -H:IncludeResourceBundles=com.sun.tools.javac.resources.javac --no-fallback --initialize-at-build-time=com.sun.tools.javac.file.Locations + -H:+ReportExceptionStackTraces + -H:-UseContainerSupport + -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED + -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED From 92c609a43bc894e4cd69e9c037491163303d97ed Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 16 Feb 2024 17:42:59 -0800 Subject: [PATCH 265/379] Set `-march=compatibility` for native-image builds This avoids CPU features that may not be available on all machines. Currently I'm seeing errors trying to run binaries built on the Github Actions machines locally on a M1. PiperOrigin-RevId: 607847525 --- core/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/core/pom.xml b/core/pom.xml index 064f9dee8..7b4a1d1f2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -319,6 +319,7 @@ -J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED + -march=compatibility From ce3cb59a8d649359a8e6e7fcc5f2f21bb79b3df1 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 22 Feb 2024 15:52:03 -0800 Subject: [PATCH 266/379] Re-indent text blocks PiperOrigin-RevId: 609526784 --- .../java/JavaInputAstVisitor.java | 3 + .../googlejavaformat/java/StringWrapper.java | 199 ++++++++++++++---- .../java/StringWrapperTest.java | 89 +++++++- .../googlejavaformat/java/testdata/RSLs.input | 39 +++- .../java/testdata/RSLs.output | 54 ++++- 5 files changed, 327 insertions(+), 57 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 1123ac01c..c23acbdb8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -1667,6 +1667,9 @@ public Void visitMemberSelect(MemberSelectTree node, Void unused) { public Void visitLiteral(LiteralTree node, Void unused) { sync(node); String sourceForNode = getSourceForNode(node, getCurrentPath()); + if (sourceForNode.startsWith("\"\"\"")) { + builder.forcedBreak(); + } if (isUnaryMinusLiteral(sourceForNode)) { token("-"); sourceForNode = sourceForNode.substring(1).trim(); diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index f241ae47f..81714db64 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -14,6 +14,7 @@ package com.google.googlejavaformat.java; +import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.Iterables.getLast; import static java.lang.Math.min; import static java.nio.charset.StandardCharsets.UTF_8; @@ -44,6 +45,7 @@ import com.sun.tools.javac.util.Position; import java.io.IOException; import java.io.UncheckedIOException; +import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayDeque; import java.util.ArrayList; @@ -59,6 +61,7 @@ import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import javax.tools.StandardLocation; +import org.checkerframework.checker.nullness.qual.Nullable; /** Wraps string literals that exceed the column limit. */ public final class StringWrapper { @@ -72,7 +75,7 @@ public static String wrap(String input, Formatter formatter) throws FormatterExc */ static String wrap(final int columnLimit, String input, Formatter formatter) throws FormatterException { - if (!longLines(columnLimit, input)) { + if (!needWrapping(columnLimit, input)) { // fast path return input; } @@ -111,13 +114,48 @@ static String wrap(final int columnLimit, String input, Formatter formatter) private static TreeRangeMap getReflowReplacements( int columnLimit, final String input) throws FormatterException { - JCTree.JCCompilationUnit unit = parse(input, /* allowStringFolding= */ false); - String separator = Newlines.guessLineSeparator(input); + return new Reflower(columnLimit, input).getReflowReplacements(); + } + + private static class Reflower { + + private final String input; + private final int columnLimit; + private final String separator; + private final JCTree.JCCompilationUnit unit; + private final Position.LineMap lineMap; + + Reflower(int columnLimit, String input) throws FormatterException { + this.columnLimit = columnLimit; + this.input = input; + this.separator = Newlines.guessLineSeparator(input); + this.unit = parse(input, /* allowStringFolding= */ false); + this.lineMap = unit.getLineMap(); + } + + TreeRangeMap getReflowReplacements() { + // Paths to string literals that extend past the column limit. + List longStringLiterals = new ArrayList<>(); + // Paths to text blocks to be re-indented. + List textBlocks = new ArrayList<>(); + new LongStringsAndTextBlockScanner(longStringLiterals, textBlocks) + .scan(new TreePath(unit), null); + TreeRangeMap replacements = TreeRangeMap.create(); + indentTextBlocks(replacements, textBlocks); + wrapLongStrings(replacements, longStringLiterals); + return replacements; + } + + private class LongStringsAndTextBlockScanner extends TreePathScanner { + + private final List longStringLiterals; + private final List textBlocks; + + LongStringsAndTextBlockScanner(List longStringLiterals, List textBlocks) { + this.longStringLiterals = longStringLiterals; + this.textBlocks = textBlocks; + } - // Paths to string literals that extend past the column limit. - List toFix = new ArrayList<>(); - final Position.LineMap lineMap = unit.getLineMap(); - new TreePathScanner() { @Override public Void visitLiteral(LiteralTree literalTree, Void aVoid) { if (literalTree.getKind() != Kind.STRING_LITERAL) { @@ -125,6 +163,7 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) { } int pos = getStartPosition(literalTree); if (input.substring(pos, min(input.length(), pos + 3)).equals("\"\"\"")) { + textBlocks.add(literalTree); return null; } Tree parent = getCurrentPath().getParentPath().getLeaf(); @@ -140,44 +179,114 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) { if (lineMap.getColumnNumber(lineEnd) - 1 <= columnLimit) { return null; } - toFix.add(getCurrentPath()); + longStringLiterals.add(getCurrentPath()); return null; } - }.scan(new TreePath(unit), null); - - TreeRangeMap replacements = TreeRangeMap.create(); - for (TreePath path : toFix) { - // Find the outermost contiguous enclosing concatenation expression - TreePath enclosing = path; - while (enclosing.getParentPath().getLeaf().getKind() == Tree.Kind.PLUS) { - enclosing = enclosing.getParentPath(); + } + + private void indentTextBlocks( + TreeRangeMap replacements, List textBlocks) { + for (Tree tree : textBlocks) { + int startPosition = getStartPosition(tree); + int endPosition = getEndPosition(unit, tree); + String text = input.substring(startPosition, endPosition); + + // Find the source code of the text block with incidental whitespace removed. + // The first line of the text block is always """, and it does not affect incidental + // whitespace. + ImmutableList initialLines = text.lines().collect(toImmutableList()); + String stripped = stripIndent(initialLines.stream().skip(1).collect(joining(separator))); + ImmutableList lines = stripped.lines().collect(toImmutableList()); + int deindent = + initialLines.get(1).stripTrailing().length() - lines.get(0).stripTrailing().length(); + + int startColumn = lineMap.getColumnNumber(startPosition); + String prefix = + (deindent == 0 || lines.stream().anyMatch(x -> x.length() + startColumn > columnLimit)) + ? "" + : " ".repeat(startColumn - 1); + + StringBuilder output = new StringBuilder("\"\"\""); + for (int i = 0; i < lines.size(); i++) { + String line = lines.get(i); + String trimmed = line.stripLeading().stripTrailing(); + output.append(separator); + if (!trimmed.isEmpty()) { + // Don't add incidental leading whitespace to empty lines + output.append(prefix); + } + if (i == lines.size() - 1 && trimmed.equals("\"\"\"")) { + // If the trailing line is just """, indenting is more than the prefix of incidental + // whitespace has no effect, and results in a javac text-blocks warning that 'trailing + // white space will be removed'. + output.append("\"\"\""); + } else { + output.append(line); + } + } + replacements.put(Range.closedOpen(startPosition, endPosition), output.toString()); } - // Is the literal being wrapped the first in a chain of concatenation expressions? - // i.e. `ONE + TWO + THREE` - // We need this information to handle continuation indents. - AtomicBoolean first = new AtomicBoolean(false); - // Finds the set of string literals in the concat expression that includes the one that needs - // to be wrapped. - List flat = flatten(input, unit, path, enclosing, first); - // Zero-indexed start column - int startColumn = lineMap.getColumnNumber(getStartPosition(flat.get(0))) - 1; - - // Handling leaving trailing non-string tokens at the end of the literal, - // e.g. the trailing `);` in `foo("...");`. - int end = getEndPosition(unit, getLast(flat)); - int lineEnd = end; - while (Newlines.hasNewlineAt(input, lineEnd) == -1) { - lineEnd++; + } + + private void wrapLongStrings( + TreeRangeMap replacements, List longStringLiterals) { + for (TreePath path : longStringLiterals) { + // Find the outermost contiguous enclosing concatenation expression + TreePath enclosing = path; + while (enclosing.getParentPath().getLeaf().getKind() == Kind.PLUS) { + enclosing = enclosing.getParentPath(); + } + // Is the literal being wrapped the first in a chain of concatenation expressions? + // i.e. `ONE + TWO + THREE` + // We need this information to handle continuation indents. + AtomicBoolean first = new AtomicBoolean(false); + // Finds the set of string literals in the concat expression that includes the one that + // needs + // to be wrapped. + List flat = flatten(input, unit, path, enclosing, first); + // Zero-indexed start column + int startColumn = lineMap.getColumnNumber(getStartPosition(flat.get(0))) - 1; + + // Handling leaving trailing non-string tokens at the end of the literal, + // e.g. the trailing `);` in `foo("...");`. + int end = getEndPosition(unit, getLast(flat)); + int lineEnd = end; + while (Newlines.hasNewlineAt(input, lineEnd) == -1) { + lineEnd++; + } + int trailing = lineEnd - end; + + // Get the original source text of the string literals, excluding `"` and `+`. + ImmutableList components = stringComponents(input, unit, flat); + replacements.put( + Range.closedOpen(getStartPosition(flat.get(0)), getEndPosition(unit, getLast(flat))), + reflow(separator, columnLimit, startColumn, trailing, components, first.get())); } - int trailing = lineEnd - end; + } + } + + private static final Method STRIP_INDENT = getStripIndent(); + + private static @Nullable Method getStripIndent() { + if (Runtime.version().feature() < 15) { + return null; + } + try { + return String.class.getMethod("stripIndent"); + } catch (NoSuchMethodException e) { + throw new LinkageError(e.getMessage(), e); + } + } - // Get the original source text of the string literals, excluding `"` and `+`. - ImmutableList components = stringComponents(input, unit, flat); - replacements.put( - Range.closedOpen(getStartPosition(flat.get(0)), getEndPosition(unit, getLast(flat))), - reflow(separator, columnLimit, startColumn, trailing, components, first.get())); + private static String stripIndent(String input) { + if (STRIP_INDENT == null) { + return input; + } + try { + return (String) STRIP_INDENT.invoke(input); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); } - return replacements; } /** @@ -364,13 +473,16 @@ private static int getStartPosition(Tree tree) { return ((JCTree) tree).getStartPosition(); } - /** Returns true if any lines in the given Java source exceed the column limit. */ - private static boolean longLines(int columnLimit, String input) { + /** + * Returns true if any lines in the given Java source exceed the column limit, or contain a {@code + * """} that could indicate a text block. + */ + private static boolean needWrapping(int columnLimit, String input) { // TODO(cushon): consider adding Newlines.lineIterable? Iterator it = Newlines.lineIterator(input); while (it.hasNext()) { String line = it.next(); - if (line.length() > columnLimit) { + if (line.length() > columnLimit || line.contains("\"\"\"")) { return true; } } @@ -385,7 +497,6 @@ private static JCTree.JCCompilationUnit parse(String source, boolean allowString context.put(DiagnosticListener.class, diagnostics); Options.instance(context).put("--enable-preview", "true"); Options.instance(context).put("allowStringFolding", Boolean.toString(allowStringFolding)); - JCTree.JCCompilationUnit unit; JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8); try { fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of()); @@ -404,7 +515,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) { JavacParser parser = parserFactory.newParser( source, /* keepDocComments= */ true, /* keepEndPos= */ true, /* keepLineMap= */ true); - unit = parser.parseCompilationUnit(); + JCTree.JCCompilationUnit unit = parser.parseCompilationUnit(); unit.sourcefile = sjfo; Iterable> errorDiagnostics = Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic); diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java index f7be369f1..5ef7cb51a 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -60,19 +60,90 @@ public void textBlock() throws Exception { lines( "package com.mypackage;", "public class ReproBug {", - " private String myString;", - " private ReproBug() {", - " String str =", - " \"\"\"", - " " - + " {\"sourceEndpoint\":\"ri.something.1-1.object-internal.1\",\"targetEndpoint\":\"ri.some" - + "thing.1-1.object-internal.2\",\"typeId\":\"typeId\"}\"\"\";", - " myString = str;", - " }", + " private String myString;", + " private ReproBug() {", + " String str =", + " \"\"\"", + "{\"sourceEndpoint\":\"ri.something.1-1.object-internal.1\",\"targetEndpoint" + + "\":\"ri.something.1-1.object-internal.2\",\"typeId\":\"typeId\"}\"\"\";", + " myString = str;", + " }", "}"); assertThat(StringWrapper.wrap(100, input, new Formatter())).isEqualTo(input); } + // Test that whitespace handling on text block lines only removes spaces, not other control + // characters. + @Test + public void textBlockControlCharacter() throws Exception { + assumeTrue(Runtime.version().feature() >= 15); + // We want an actual control character in the Java source being formatted, not a unicode escape, + // i.e. the escape below doesn't need to be double-escaped. + String input = + lines( + "package p;", + "public class T {", + " String s =", + " \"\"\"", + " \u0007lorem", + " \u0007", + " ipsum", + " \"\"\";", + "}"); + String actual = StringWrapper.wrap(100, input, new Formatter()); + assertThat(actual).isEqualTo(input); + } + + @Test + public void textBlockTrailingWhitespace() throws Exception { + assumeTrue(Runtime.version().feature() >= 15); + String input = + lines( + "public class T {", + " String s =", + " \"\"\"", + " lorem ", + " ipsum", + " \"\"\";", + "}"); + String expected = + lines( + "public class T {", + " String s =", + " \"\"\"", + " lorem", + " ipsum", + " \"\"\";", + "}"); + String actual = StringWrapper.wrap(100, input, new Formatter()); + assertThat(actual).isEqualTo(expected); + } + + @Test + public void textBlockSpaceTabMix() throws Exception { + assumeTrue(Runtime.version().feature() >= 15); + String input = + lines( + "public class T {", + " String s =", + " \"\"\"", + " lorem", + " \tipsum", + " \"\"\";", + "}"); + String expected = + lines( + "public class T {", + " String s =", + " \"\"\"", + " lorem", + " ipsum", + " \"\"\";", + "}"); + String actual = StringWrapper.wrap(100, input, new Formatter()); + assertThat(actual).isEqualTo(expected); + } + private static String lines(String... line) { return Joiner.on('\n').join(line) + '\n'; } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input index 9c18f0def..f401285bc 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input @@ -1,6 +1,43 @@ class RSLs { - String s = """ + String a = """ lorem ipsum """; + String b = """ + lorem + ipsum + """; + String c = """ + lorem + ipsum + """; + String d = """ + ipsum + """; + String e = """ + """; + String f = """ + ipsum"""; + String g = """ + lorem\ + ipsum + """; + String h = """ + lorem\ + ipsum\ + """; + String i = """ + lorem + + ipsum + """; + String j = """ + lorem + one long incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt + ipsum + """; + String k = """ +lorem +ipsum +"""; } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output index 9c18f0def..c6051d1fd 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output @@ -1,6 +1,54 @@ class RSLs { - String s = """ - lorem + String a = + """ + lorem + ipsum + """; + String b = + """ + lorem ipsum - """; + """; + String c = + """ + lorem + ipsum + """; + String d = + """ + ipsum + """; + String e = + """ + """; + String f = + """ + ipsum"""; + String g = + """ + lorem\ + ipsum + """; + String h = + """ + lorem\ + ipsum\ + """; + String i = + """ + lorem + + ipsum + """; + String j = + """ +lorem +one long incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt +ipsum +"""; + String k = + """ +lorem +ipsum +"""; } From e946e82801eb5bbd52bea00355ba20450bc0725c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 23 Feb 2024 08:14:44 -0800 Subject: [PATCH 267/379] Work around a crash on comments inside string template arguments PiperOrigin-RevId: 609732753 --- .../googlejavaformat/java/JavacTokens.java | 62 +++++++++++++++++-- .../java/FormatterIntegrationTest.java | 3 +- .../java/testdata/TextBlockTemplates.input | 11 ++++ .../java/testdata/TextBlockTemplates.output | 14 +++++ 4 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java index da77cf82c..690c924f1 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java @@ -15,6 +15,7 @@ package com.google.googlejavaformat.java; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkElementIndex; import static java.util.Arrays.stream; import com.google.common.collect.ImmutableList; @@ -28,6 +29,7 @@ import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.parser.UnicodeReader; import com.sun.tools.javac.util.Context; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -35,9 +37,10 @@ import java.util.List; import java.util.Objects; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; /** A wrapper around javac's lexer. */ -class JavacTokens { +final class JavacTokens { /** The lexer eats terminal comments, so feed it one we don't care about. */ // TODO(b/33103797): fix javac and remove the work-around @@ -51,6 +54,8 @@ static class RawTok { private final int endPos; RawTok(String stringVal, TokenKind kind, int pos, int endPos) { + checkElementIndex(pos, endPos, "pos"); + checkArgument(pos < endPos, "expected pos (%s) < endPos (%s)", pos, endPos); this.stringVal = stringVal; this.kind = kind; this.pos = pos; @@ -136,13 +141,30 @@ public static ImmutableList getTokens( int last = 0; for (Token t : javacTokens) { if (t.comments != null) { + // javac accumulates comments in reverse order for (Comment c : Lists.reverse(t.comments)) { - if (last < c.getSourcePos(0)) { - tokens.add(new RawTok(null, null, last, c.getSourcePos(0))); + int pos = c.getSourcePos(0); + int length; + if (pos == -1) { + // We've found a comment whose position hasn't been recorded. Deduce its position as the + // first `/` character after the end of the previous token. + // + // javac creates a new JavaTokenizer to process string template arguments, so + // CommentSavingTokenizer doesn't get a chance to preprocess those comments and save + // their text and positions. + // + // TODO: consider always using this approach once the minimum supported JDK is 16 and + // we can assume BasicComment#getRawCharacters is always available. + pos = source.indexOf('/', last); + length = CommentSavingTokenizer.commentLength(c); + } else { + length = c.getText().length(); } - tokens.add( - new RawTok(null, null, c.getSourcePos(0), c.getSourcePos(0) + c.getText().length())); - last = c.getSourcePos(0) + c.getText().length(); + if (last < pos) { + tokens.add(new RawTok(null, null, last, pos)); + } + tokens.add(new RawTok(null, null, pos, pos + length)); + last = pos + length; } } if (stopTokens.contains(t.kind)) { @@ -181,6 +203,32 @@ public static ImmutableList getTokens( /** A {@link JavaTokenizer} that saves comments. */ static class CommentSavingTokenizer extends JavaTokenizer { + + private static final Method GET_RAW_CHARACTERS_METHOD = getRawCharactersMethod(); + + private static @Nullable Method getRawCharactersMethod() { + try { + // This is a method in PositionTrackingReader, but that class is not public. + return BasicComment.class.getMethod("getRawCharacters"); + } catch (NoSuchMethodException e) { + return null; + } + } + + static int commentLength(Comment comment) { + if (comment instanceof BasicComment && GET_RAW_CHARACTERS_METHOD != null) { + // If we've seen a BasicComment instead of a CommentWithTextAndPosition, getText() will + // be null, so we deduce the length using getRawCharacters. See also the comment at the + // usage of this method in getTokens. + try { + return ((char[]) GET_RAW_CHARACTERS_METHOD.invoke(((BasicComment) comment))).length; + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } + return comment.getText().length(); + } + CommentSavingTokenizer(ScannerFactory fac, char[] buffer, int length) { super(fac, buffer, length); } @@ -288,4 +336,6 @@ protected AccessibleReader(ScannerFactory fac, char[] buffer, int length) { super(fac, buffer, length); } } + + private JavacTokens() {} } diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 15a6e75f9..d31218e28 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -63,7 +63,8 @@ public class FormatterIntegrationTest { "I981", "StringTemplate", "I1020", - "I1037") + "I1037", + "TextBlockTemplates") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.input new file mode 100644 index 000000000..2d00d3300 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.input @@ -0,0 +1,11 @@ +abstract class RSLs { + abstract String f(); + + String a = STR.""" + lorem + foo\{ /** a method */ f( // line comment + /* TODO */ + )}bar + ipsum + """; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.output new file mode 100644 index 000000000..36736724f --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.output @@ -0,0 +1,14 @@ +abstract class RSLs { + abstract String f(); + + String a = + STR.""" + lorem + foo\{ + /** a method */ + f( // line comment + /* TODO */ + )}bar + ipsum + """; +} From d8216e8c1d15d225223a308c04612d4a5eb60c09 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 23 Feb 2024 10:02:43 -0800 Subject: [PATCH 268/379] Migrate google-java-format to JSpecify PiperOrigin-RevId: 609760882 --- core/pom.xml | 4 ++-- .../google/googlejavaformat/java/FormatFileCallable.java | 2 +- .../google/googlejavaformat/java/JavaInputAstVisitor.java | 4 ++-- .../com/google/googlejavaformat/java/JavacTokens.java | 2 +- .../com/google/googlejavaformat/java/StringWrapper.java | 2 +- .../googlejavaformat/java/filer/FormattingFiler.java | 2 +- .../java/filer/FormattingJavaFileObject.java | 2 +- .../googlejavaformat/java/testdata/TypeAnnotations.input | 2 +- .../googlejavaformat/java/testdata/TypeAnnotations.output | 2 +- .../intellij/GoogleJavaFormatConfigurable.java | 2 +- .../intellij/GoogleJavaFormatSettings.java | 2 +- pom.xml | 8 ++++---- 12 files changed, 17 insertions(+), 17 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 7b4a1d1f2..c3753a150 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -42,8 +42,8 @@ - org.checkerframework - checker-qual + org.jspecify + jspecify true diff --git a/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java b/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java index 3d68a23f3..7cec1fca8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java +++ b/core/src/main/java/com/google/googlejavaformat/java/FormatFileCallable.java @@ -20,7 +20,7 @@ import com.google.common.collect.TreeRangeSet; import java.nio.file.Path; import java.util.concurrent.Callable; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; /** * Encapsulates information about a file to be formatted, including which parts of the file to diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index c23acbdb8..6dc82f40c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -158,7 +158,7 @@ import java.util.regex.Pattern; import java.util.stream.Stream; import javax.lang.model.element.Name; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; /** * An AST visitor that builds a stream of {@link Op}s to format from the given {@link @@ -287,7 +287,7 @@ private static ImmutableSetMultimap typeAnnotations() { ImmutableList.of( "org.jspecify.annotations.NonNull", "org.jspecify.annotations.Nullable", - "org.jspecify.nullness.Nullable", + "org.jspecify.annotations.Nullable", "org.checkerframework.checker.nullness.qual.NonNull", "org.checkerframework.checker.nullness.qual.Nullable")) { String simpleName = annotation.substring(annotation.lastIndexOf('.') + 1); diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java index 690c924f1..986db3912 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java @@ -37,7 +37,7 @@ import java.util.List; import java.util.Objects; import java.util.Set; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; /** A wrapper around javac's lexer. */ final class JavacTokens { diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 81714db64..6814054a2 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -61,7 +61,7 @@ import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import javax.tools.StandardLocation; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; /** Wraps string literals that exceed the column limit. */ public final class StringWrapper { diff --git a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java index d38d84eca..ebdc8dfec 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java +++ b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java @@ -24,7 +24,7 @@ import javax.tools.FileObject; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; /** * A decorating {@link Filer} implementation which formats Java source files with a {@link diff --git a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java index c8ae80769..b65258b1a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java +++ b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingJavaFileObject.java @@ -26,7 +26,7 @@ import javax.tools.Diagnostic; import javax.tools.ForwardingJavaFileObject; import javax.tools.JavaFileObject; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; /** A {@link JavaFileObject} decorator which {@linkplain Formatter formats} source code. */ final class FormattingJavaFileObject extends ForwardingJavaFileObject { diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input index ddaa8f1ad..d6483bbf2 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.input @@ -1,4 +1,4 @@ -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; class TypeAnnotations { diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output index 8dd5d4efc..6d0c3017d 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TypeAnnotations.output @@ -1,4 +1,4 @@ -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; class TypeAnnotations { diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java index 2f34b7471..cbb0ee10b 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java @@ -31,9 +31,9 @@ import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; -import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; class GoogleJavaFormatConfigurable extends BaseConfigurable implements SearchableConfigurable { diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java index ee187c00d..572d9ba6d 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java @@ -21,8 +21,8 @@ import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.project.Project; -import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; @State( name = "GoogleJavaFormatSettings", diff --git a/pom.xml b/pom.xml index 2b426cee1..152fdfde2 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ 1.8 32.1.3-jre 1.4.0 - 3.21.2 + 0.3.0 2.16 1.9 1.0.1 @@ -107,9 +107,9 @@ - org.checkerframework - checker-qual - ${checker.version} + org.jspecify + jspecify + ${jspecify.version} com.google.errorprone From 29b7f93237fbda5f4bbada2cf16e97c9917ca59d Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Mon, 26 Feb 2024 17:29:07 +0100 Subject: [PATCH 269/379] Remove an un-used portion of CI YAML --- .github/workflows/ci.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab0ebf024..9dca726b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,15 +65,6 @@ jobs: java-version: ${{ matrix.java }} distribution: "zulu" cache: "maven" - - name: "Set up JDK ${{ matrix.java }}" - if: ${{ matrix.java == 'GraalVM' }} - uses: graalvm/setup-graalvm@v1 - with: - java-version: "21" - distribution: "graalvm-community" - github-token: ${{ secrets.GITHUB_TOKEN }} - native-image-job-reports: "true" - cache: "maven" - name: "Install" shell: bash run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V From 32d14f0e5b0413e9f64dc2f9116d921ed7adec99 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Mon, 26 Feb 2024 16:46:20 +0000 Subject: [PATCH 270/379] Build native on Ubuntu 20.04 instead of latest 22.04 (re. #1072). This MAY (?) help re. libc.so.6 (GLIBC_2.34) for https://github.com/google/google-java-format/issues/1072. --- .github/workflows/ci.yml | 5 ++++- .github/workflows/release.yml | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9dca726b1..c623efe38 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,7 +77,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + # Use "oldest" available ubuntu-* instead of -latest, + # see https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories; + # due to https://github.com/google/google-java-format/issues/1072. + os: [ubuntu-20.04, macos-latest, windows-latest] runs-on: ${{ matrix.os }} continue-on-error: true steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2f309026b..e8f50b503 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,7 +86,10 @@ jobs: needs: build-maven-jars strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + # Use "oldest" available ubuntu-* instead of -latest, + # see https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories; + # due to https://github.com/google/google-java-format/issues/1072. + os: [ubuntu-20.04, macos-latest, windows-latest] env: SUFFIX: ${{fromJson('{"ubuntu-latest":"linux-x86-64", "macos-latest":"darwin-arm64", "windows-latest":"windows-x86-64"}')[matrix.os]}} EXTENSION: ${{ matrix.os == 'windows-latest' && '.exe' || '' }} From cea3782400689132f3f84178a8848b9d7cb4a9e5 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Mon, 26 Feb 2024 18:04:13 +0100 Subject: [PATCH 271/379] Update release.yml --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e8f50b503..a390df249 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -91,7 +91,8 @@ jobs: # due to https://github.com/google/google-java-format/issues/1072. os: [ubuntu-20.04, macos-latest, windows-latest] env: - SUFFIX: ${{fromJson('{"ubuntu-latest":"linux-x86-64", "macos-latest":"darwin-arm64", "windows-latest":"windows-x86-64"}')[matrix.os]}} + # NB: Must keep the keys in this inline JSON below in line with the os: above! + SUFFIX: ${{fromJson('{"ubuntu-20.04":"linux-x86-64", "macos-latest":"darwin-arm64", "windows-latest":"windows-x86-64"}')[matrix.os]}} EXTENSION: ${{ matrix.os == 'windows-latest' && '.exe' || '' }} steps: - name: "Check out repository" From 74c510a03f218bdae157ebf06f030afd98eafc39 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Tue, 27 Feb 2024 10:40:25 -0800 Subject: [PATCH 272/379] Update the IntelliJ plugin to gfj 1.20.0. PiperOrigin-RevId: 610801461 --- idea_plugin/build.gradle.kts | 6 +++--- .../intellij/GoogleJavaFormatConfigurable.java | 2 +- .../googlejavaformat/intellij/GoogleJavaFormatSettings.java | 2 +- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 2247893c1..0c3ae944e 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -14,7 +14,7 @@ * limitations under the License. */ -plugins { id("org.jetbrains.intellij") version "1.16.1" } +plugins { id("org.jetbrains.intellij") version "1.17.2" } apply(plugin = "org.jetbrains.intellij") @@ -22,7 +22,7 @@ apply(plugin = "java") repositories { mavenCentral() } -val googleJavaFormatVersion = "1.19.2" +val googleJavaFormatVersion = "1.20.0" java { sourceCompatibility = JavaVersion.VERSION_11 @@ -62,5 +62,5 @@ tasks { dependencies { implementation("com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}") testImplementation("junit:junit:4.13.2") - testImplementation("com.google.truth:truth:1.2.0") + testImplementation("com.google.truth:truth:1.4.1") } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java index cbb0ee10b..759decc0f 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java @@ -33,7 +33,7 @@ import javax.swing.JPanel; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; -import org.jspecify.annotations.Nullable; +import org.jetbrains.annotations.Nullable; class GoogleJavaFormatConfigurable extends BaseConfigurable implements SearchableConfigurable { diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java index 572d9ba6d..4546f68a3 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatSettings.java @@ -22,7 +22,7 @@ import com.intellij.openapi.components.Storage; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; -import org.jspecify.annotations.Nullable; +import org.jetbrains.annotations.Nullable; @State( name = "GoogleJavaFormatSettings", diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index a5600b00d..c426a1ff1 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
1.20.0.0
+
Updated to use google-java-format 1.20.0.
1.19.2.0
Updated to use google-java-format 1.19.2.
1.17.0.0
From f20d393babf0fb489a90a1d7913d7a43e5f8cff1 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 29 Feb 2024 13:06:44 -0800 Subject: [PATCH 273/379] Bump the version number for native image builds Fixes https://github.com/google/google-java-format/issues/1068 --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a390df249..d2ce2beae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -105,6 +105,8 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} native-image-job-reports: "true" cache: "maven" + - name: Bump Version Number + run: mvn --no-transfer-progress versions:set versions:commit -DnewVersion="${{ github.event.inputs.version }}" - name: "Native" run: mvn -Pnative -DskipTests package -pl core -am - name: "Move outputs" From 823d7c99bc61e05e26ec68ede3c42231b6e2e62b Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Wed, 6 Mar 2024 00:24:37 -0800 Subject: [PATCH 274/379] Print all known values when an invalid range is given. For easier root cause analysis when an invalid request is passed. PiperOrigin-RevId: 613110312 --- .../googlejavaformat/java/JavaInput.java | 6 ++-- .../googlejavaformat/java/FormatterTest.java | 28 +++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 7b5eb841f..b5290ab10 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -573,9 +573,11 @@ Range characterRangeToTokenRange(Range characterRange) if (characterRange.upperEndpoint() > text.length()) { throw new FormatterException( String.format( - "error: invalid length %d, offset + length (%d) is outside the file", + "error: invalid offset (%d) or length (%d); offset + length (%d) > file length (%d)", + characterRange.lowerEndpoint(), characterRange.upperEndpoint() - characterRange.lowerEndpoint(), - characterRange.upperEndpoint())); + characterRange.upperEndpoint(), + text.length())); } // empty range stands for "format the line under the cursor" Range nonEmptyRange = diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java index 9bbca496a..b0d7b4030 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java @@ -64,7 +64,7 @@ public void testFormatAosp() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("A.java"); - Files.write(path, input.getBytes(UTF_8)); + Files.writeString(path, input); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -116,7 +116,7 @@ public void testFormatLengthUpToEOF() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(UTF_8)); + Files.writeString(path, input); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -133,7 +133,7 @@ public void testFormatLengthOutOfRange() throws Exception { Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); - Files.write(path, input.getBytes(UTF_8)); + Files.writeString(path, input); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); @@ -142,7 +142,25 @@ public void testFormatLengthOutOfRange() throws Exception { String[] args = {"--offset", "0", "--length", "9999", path.toString()}; assertThat(main.format(args)).isEqualTo(1); assertThat(err.toString()) - .contains("error: invalid length 9999, offset + length (9999) is outside the file"); + .contains("error: invalid offset (0) or length (9999); offset + length (9999)"); + } + + @Test + public void testFormatOffsetOutOfRange() throws Exception { + String input = "class Foo{}\n"; + + Path tmpdir = testFolder.newFolder().toPath(); + Path path = tmpdir.resolve("Foo.java"); + Files.writeString(path, input); + + StringWriter out = new StringWriter(); + StringWriter err = new StringWriter(); + + Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); + String[] args = {"--offset", "9998", "--length", "1", path.toString()}; + assertThat(main.format(args)).isEqualTo(1); + assertThat(err.toString()) + .contains("error: invalid offset (9998) or length (1); offset + length (9999)"); } @Test @@ -303,7 +321,7 @@ private void importOrdering(String sortArg, String outputResourceName) String inputResourceName = "com/google/googlejavaformat/java/testimports/A.input"; String input = getResource(inputResourceName); String expectedOutput = getResource(outputResourceName); - Files.write(path, input.getBytes(UTF_8)); + Files.writeString(path, input); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); From 8ee063ef78e16321fa4f815b14d246df783f3828 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 18 Mar 2024 09:08:28 -0700 Subject: [PATCH 275/379] Update tycho version from 3.0.0 to 3.0.5 I think this fixes crashes from the presubmit for unknown commit: ``` Error: Exception in thread "main" java.lang.NoSuchMethodError: 'java.lang.String org.eclipse.equinox.p2.core.IProvisioningAgent.getProperty(java.lang.String)' at org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository.getAgentPropertyWithFallback(SimpleArtifactRepository.java:813) at org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepository.getMaximumThreads(SimpleArtifactRepository.java:1012) ``` I tested a PR with these changes and it was clean [1], so either this helps or it was a transient issue, but either way this shouldn't hurt. [1] https://github.com/google/google-java-format/actions/runs/8329274139 PiperOrigin-RevId: 616846344 --- eclipse_plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index 9e6acdac0..b2c6e368a 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -32,7 +32,7 @@ UTF-8 - 3.0.0 + 3.0.5 From 71a755b4daf0846c867834b5a0d86297ac7d0667 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Mon, 18 Mar 2024 12:14:38 -0700 Subject: [PATCH 276/379] Update the IntelliJ plugin to gfj 1.21.0. PiperOrigin-RevId: 616908365 --- idea_plugin/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 0c3ae944e..05010fe3c 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -22,7 +22,7 @@ apply(plugin = "java") repositories { mavenCentral() } -val googleJavaFormatVersion = "1.20.0" +val googleJavaFormatVersion = "1.21.0" java { sourceCompatibility = JavaVersion.VERSION_11 @@ -62,5 +62,5 @@ tasks { dependencies { implementation("com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}") testImplementation("junit:junit:4.13.2") - testImplementation("com.google.truth:truth:1.4.1") + testImplementation("com.google.truth:truth:1.4.2") } From 3ee6e2a34029bc5e68a5f733749e2732c2bf7940 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Thu, 28 Mar 2024 17:07:54 -0700 Subject: [PATCH 277/379] Java-format: format multiples files in parallel to improve speed PiperOrigin-RevId: 620100015 --- scripts/google-java-format-diff.py | 82 ++++++++++++++++++------------ 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/scripts/google-java-format-diff.py b/scripts/google-java-format-diff.py index 2c75edac7..7f52ed1ec 100755 --- a/scripts/google-java-format-diff.py +++ b/scripts/google-java-format-diff.py @@ -33,8 +33,34 @@ import subprocess import io import sys +from concurrent.futures import ThreadPoolExecutor,wait,FIRST_EXCEPTION from shutil import which +def _apply_format(filename, lines, base_command, args): + """Apply format on filename.""" + if args.i and args.verbose: + print('Formatting', filename) + + command = base_command[:] + command.extend(lines) + command.append(filename) + p = subprocess.Popen(command, stdout=subprocess.PIPE, + stderr=None, stdin=subprocess.PIPE) + stdout, _ = p.communicate() + if p.returncode != 0: + sys.exit(p.returncode) + + if not args.i: + with open(filename) as f: + code = f.readlines() + formatted_code = io.StringIO(stdout.decode('utf-8')).readlines() + diff = difflib.unified_diff(code, formatted_code, + filename, filename, + '(before formatting)', '(after formatting)') + diff_string = ''.join(diff) + if len(diff_string) > 0: + sys.stdout.write(diff_string) + def main(): parser = argparse.ArgumentParser(description= 'Reformat changed lines in diff. Without -i ' @@ -108,39 +134,29 @@ def main(): binary = which('google-java-format') or '/usr/bin/google-java-format' base_command = [binary] - # Reformat files containing changes in place. - for filename, lines in lines_by_file.items(): - if args.i and args.verbose: - print('Formatting', filename) - command = base_command[:] - if args.i: - command.append('-i') - if args.aosp: - command.append('--aosp') - if args.skip_sorting_imports: - command.append('--skip-sorting-imports') - if args.skip_removing_unused_imports: - command.append('--skip-removing-unused-imports') - if args.skip_javadoc_formatting: - command.append('--skip-javadoc-formatting') - command.extend(lines) - command.append(filename) - p = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=None, stdin=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode != 0: - sys.exit(p.returncode); - - if not args.i: - with open(filename) as f: - code = f.readlines() - formatted_code = io.StringIO(stdout.decode('utf-8')).readlines() - diff = difflib.unified_diff(code, formatted_code, - filename, filename, - '(before formatting)', '(after formatting)') - diff_string = ''.join(diff) - if len(diff_string) > 0: - sys.stdout.write(diff_string) + if args.i: + base_command.append('-i') + if args.aosp: + base_command.append('--aosp') + if args.skip_sorting_imports: + base_command.append('--skip-sorting-imports') + if args.skip_removing_unused_imports: + base_command.append('--skip-removing-unused-imports') + if args.skip_javadoc_formatting: + base_command.append('--skip-javadoc-formatting') + + with ThreadPoolExecutor() as executor: + format_futures = [] + for filename, lines in lines_by_file.items(): + format_futures.append( + executor.submit(_apply_format, filename, lines, base_command, args) + ) + + done, _ = wait(format_futures, return_when=FIRST_EXCEPTION) + for future in done: + if exception := future.exception(): + executor.shutdown(wait=True, cancel_futures=True) + sys.exit(exception.args[0]) if __name__ == '__main__': main() From 31678188c402f8ff4a0cd173f1c53f7d82fa1033 Mon Sep 17 00:00:00 2001 From: nickreid Date: Fri, 29 Mar 2024 19:08:52 -0700 Subject: [PATCH 278/379] Stop using floats to represent line widths, which must be integers. Float was used so that forced breaks could be modeled with POSITIVE_INFINISTY, but an arbitrary large int works just as well. PiperOrigin-RevId: 620395732 --- .../java/com/google/googlejavaformat/Doc.java | 63 +++++++++++-------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Doc.java b/core/src/main/java/com/google/googlejavaformat/Doc.java index cab688558..01a75846e 100644 --- a/core/src/main/java/com/google/googlejavaformat/Doc.java +++ b/core/src/main/java/com/google/googlejavaformat/Doc.java @@ -63,6 +63,16 @@ public enum FillMode { FORCED } + /** + * The maximum supported line width. + * + *

This can be used as a sentinel/threshold for {@code Doc}s that break unconditionally. + * + *

The value was selected to be obviously too large for any practical line, but small enough to + * prevent accidental overflow. + */ + public static final int MAX_LINE_WIDTH = 1000; + /** State for writing. */ public static final class State { final int lastIndent; @@ -103,8 +113,7 @@ public String toString() { private static final Range EMPTY_RANGE = Range.closedOpen(-1, -1); private static final DiscreteDomain INTEGERS = DiscreteDomain.integers(); - // Memoized width; Float.POSITIVE_INFINITY if contains forced breaks. - private final Supplier width = Suppliers.memoize(this::computeWidth); + private final Supplier width = Suppliers.memoize(this::computeWidth); // Memoized flat; not defined (and never computed) if contains forced breaks. private final Supplier flat = Suppliers.memoize(this::computeFlat); @@ -113,16 +122,16 @@ public String toString() { private final Supplier> range = Suppliers.memoize(this::computeRange); /** - * Return the width of a {@code Doc}, or {@code Float.POSITIVE_INFINITY} if it must be broken. + * Return the width of a {@code Doc}. * * @return the width */ - final float getWidth() { + final int getWidth() { return width.get(); } /** - * Return a {@code Doc}'s flat-string value; not defined (and never called) if the (@code Doc} + * Return a {@code Doc}'s flat-string value; not defined (and never called) if the {@code Doc} * contains forced breaks. * * @return the flat-string value @@ -143,9 +152,9 @@ final Range range() { /** * Compute the {@code Doc}'s width. * - * @return the width, or {@code Float.POSITIVE_INFINITY} if it must be broken + * @return the width */ - abstract float computeWidth(); + abstract int computeWidth(); /** * Compute the {@code Doc}'s flat value. Not defined (and never called) if contains forced breaks. @@ -202,12 +211,8 @@ void add(Doc doc) { } @Override - float computeWidth() { - float thisWidth = 0.0F; - for (Doc doc : docs) { - thisWidth += doc.getWidth(); - } - return thisWidth; + int computeWidth() { + return getWidth(docs); } @Override @@ -246,10 +251,10 @@ Range computeRange() { @Override public State computeBreaks(CommentsHelper commentsHelper, int maxWidth, State state) { - float thisWidth = getWidth(); + int thisWidth = getWidth(); if (state.column + thisWidth <= maxWidth) { oneLine = true; - return state.withColumn(state.column + (int) thisWidth); + return state.withColumn(state.column + thisWidth); } State broken = computeBroken( @@ -295,8 +300,8 @@ private static State computeBreakAndSplit( State state, Optional optBreakDoc, List split) { - float breakWidth = optBreakDoc.isPresent() ? optBreakDoc.get().getWidth() : 0.0F; - float splitWidth = getWidth(split); + int breakWidth = optBreakDoc.isPresent() ? optBreakDoc.get().getWidth() : 0; + int splitWidth = getWidth(split); boolean shouldBreak = (optBreakDoc.isPresent() && optBreakDoc.get().fillMode == FillMode.UNIFIED) || state.mustBreak @@ -348,12 +353,16 @@ private void writeFilled(Output output) { * Get the width of a sequence of {@link Doc}s. * * @param docs the {@link Doc}s - * @return the width, or {@code Float.POSITIVE_INFINITY} if any {@link Doc} must be broken + * @return the width */ - static float getWidth(List docs) { - float width = 0.0F; + static int getWidth(List docs) { + int width = 0; for (Doc doc : docs) { width += doc.getWidth(); + + if (width >= MAX_LINE_WIDTH) { + return MAX_LINE_WIDTH; // Paranoid overflow protection + } } return width; } @@ -455,7 +464,7 @@ public void add(DocBuilder builder) { } @Override - float computeWidth() { + int computeWidth() { return token.getTok().length(); } @@ -512,8 +521,8 @@ public void add(DocBuilder builder) { } @Override - float computeWidth() { - return 1.0F; + int computeWidth() { + return 1; } @Override @@ -615,8 +624,8 @@ public void add(DocBuilder builder) { } @Override - float computeWidth() { - return isForced() ? Float.POSITIVE_INFINITY : (float) flat.length(); + int computeWidth() { + return isForced() ? MAX_LINE_WIDTH : flat.length(); } @Override @@ -705,7 +714,7 @@ public void add(DocBuilder builder) { } @Override - float computeWidth() { + int computeWidth() { int idx = Newlines.firstBreak(tok.getOriginalText()); // only count the first line of multi-line block comments if (tok.isComment()) { @@ -718,7 +727,7 @@ float computeWidth() { return reformatParameterComment(tok).map(String::length).orElse(tok.length()); } } - return idx != -1 ? Float.POSITIVE_INFINITY : (float) tok.length(); + return idx != -1 ? MAX_LINE_WIDTH : tok.length(); } @Override From 9bdae025b7b023d45636e707c9225d0cdd66eb0b Mon Sep 17 00:00:00 2001 From: nickreid Date: Mon, 1 Apr 2024 06:23:56 -0700 Subject: [PATCH 279/379] Support multiline tokens in GJF-core Cursory perf measurements show no detectable cost from scanning every token. If one should be discovered later, we can add guards to only scan potentially multiline tokens. PiperOrigin-RevId: 620833035 --- .../src/main/java/com/google/googlejavaformat/Doc.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Doc.java b/core/src/main/java/com/google/googlejavaformat/Doc.java index 01a75846e..6414a3fb1 100644 --- a/core/src/main/java/com/google/googlejavaformat/Doc.java +++ b/core/src/main/java/com/google/googlejavaformat/Doc.java @@ -397,6 +397,10 @@ boolean isReal() { private final Indent plusIndentCommentsBefore; private final Optional breakAndIndentTrailingComment; + private Input.Tok tok() { + return token.getTok(); + } + private Token( Input.Token token, RealOrImaginary realOrImaginary, @@ -465,7 +469,8 @@ public void add(DocBuilder builder) { @Override int computeWidth() { - return token.getTok().length(); + int idx = Newlines.firstBreak(tok().getOriginalText()); + return (idx >= 0) ? MAX_LINE_WIDTH : tok().length(); } @Override @@ -480,8 +485,7 @@ Range computeRange() { @Override public State computeBreaks(CommentsHelper commentsHelper, int maxWidth, State state) { - String text = token.getTok().getOriginalText(); - return state.withColumn(state.column + text.length()); + return state.withColumn(state.column + computeWidth()); } @Override From 33bf757b184cecd5be0c5377cdd3afbc7908f96f Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 1 Apr 2024 13:17:34 -0700 Subject: [PATCH 280/379] Update text block formatting after nickreid's improvements in unknown commit Previously the formatting was adding a forced break at the beginning of text blocks, which caused issues like #1081. With the changes in the baseline CL it correctly handles the 'width' of text blocks containing newlines as infinity, instead of counting the number of characters and treating the newline as having width 1. Fixes https://github.com/google/google-java-format/issues/1081 PiperOrigin-RevId: 620933964 --- .../googlejavaformat/java/JavaInputAstVisitor.java | 3 --- .../googlejavaformat/java/testdata/RSLs.input | 11 +++++++++++ .../googlejavaformat/java/testdata/RSLs.output | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 6dc82f40c..1e0675ffd 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -1667,9 +1667,6 @@ public Void visitMemberSelect(MemberSelectTree node, Void unused) { public Void visitLiteral(LiteralTree node, Void unused) { sync(node); String sourceForNode = getSourceForNode(node, getCurrentPath()); - if (sourceForNode.startsWith("\"\"\"")) { - builder.forcedBreak(); - } if (isUnaryMinusLiteral(sourceForNode)) { token("-"); sourceForNode = sourceForNode.substring(1).trim(); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input index f401285bc..22aa8f2b2 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input @@ -40,4 +40,15 @@ class RSLs { lorem ipsum """; + { + f(""" + lorem + ipsum + """, 42); + + """ + hello %s + """ + .formatted("world"); + } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output index c6051d1fd..5ca1fb8cc 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output @@ -51,4 +51,18 @@ ipsum lorem ipsum """; + + { + f( + """ + lorem + ipsum + """, + 42); + + """ + hello %s + """ + .formatted("world"); + } } From c4b467d50bd6bb52935075b438f602ff902db167 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Sat, 6 Apr 2024 03:02:26 -0700 Subject: [PATCH 281/379] Support overlapping --lines ranges in google-java-format. The strict behavior comes from the underlying ImmutableRangeSet.Builder class, which does not allow overlapping ranges to be added. Let's use TreeRangeSet instead. I have also updated the documentation for the --lines flag to make it clear that the line numbers are a closed-closed interval. Tested with: ``` blaze run :google_java_format_binary -- --lines=1:5 --lines=3:8 - < Foo.java ``` Before this CL the command fails with: ``` '--lines=1:5' '--lines=3:8' - Overlapping ranges not permitted but found [0..5) overlapping [2..8) ``` After this CL the command succeeds. PiperOrigin-RevId: 622410610 --- .../googlejavaformat/java/CommandLineOptions.java | 8 +++++--- .../java/CommandLineOptionsParser.java | 4 ++-- .../googlejavaformat/java/UsageException.java | 2 +- .../java/CommandLineOptionsParserTest.java | 15 ++++++--------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java index 5a233284a..d5480a790 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java @@ -16,6 +16,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableRangeSet; +import com.google.common.collect.RangeSet; +import com.google.common.collect.TreeRangeSet; import java.util.Optional; /** @@ -178,7 +180,7 @@ static Builder builder() { static class Builder { private final ImmutableList.Builder files = ImmutableList.builder(); - private final ImmutableRangeSet.Builder lines = ImmutableRangeSet.builder(); + private final RangeSet lines = TreeRangeSet.create(); private final ImmutableList.Builder offsets = ImmutableList.builder(); private final ImmutableList.Builder lengths = ImmutableList.builder(); private boolean inPlace = false; @@ -204,7 +206,7 @@ Builder inPlace(boolean inPlace) { return this; } - ImmutableRangeSet.Builder linesBuilder() { + RangeSet linesBuilder() { return lines; } @@ -282,7 +284,7 @@ CommandLineOptions build() { return new CommandLineOptions( files.build(), inPlace, - lines.build(), + ImmutableRangeSet.copyOf(lines), offsets.build(), lengths.build(), aosp, diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java index f7c3dec95..52a5e05d4 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java @@ -18,8 +18,8 @@ import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableRangeSet; import com.google.common.collect.Range; +import com.google.common.collect.RangeSet; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.Files; @@ -157,7 +157,7 @@ private static String getValue(String flag, Iterator it, String value) { * number. Line numbers are {@code 1}-based, but are converted to the {@code 0}-based numbering * used internally by google-java-format. */ - private static void parseRangeSet(ImmutableRangeSet.Builder result, String ranges) { + private static void parseRangeSet(RangeSet result, String ranges) { for (String range : COMMA_SPLITTER.split(ranges)) { result.add(parseRange(range)); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/UsageException.java b/core/src/main/java/com/google/googlejavaformat/java/UsageException.java index a10f2d076..50d55d4d4 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/UsageException.java +++ b/core/src/main/java/com/google/googlejavaformat/java/UsageException.java @@ -56,7 +56,7 @@ final class UsageException extends Exception { " --set-exit-if-changed", " Return exit code 1 if there are any formatting changes.", " --lines, -lines, --line, -line", - " Line range(s) to format, like 5:10 (1-based; default is all).", + " Line range(s) to format, e.g. the first 5 lines are 1:5 (1-based; default is all).", " --offset, -offset", " Character offset to format (0-based; default is all).", " --length, -length", diff --git a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java index 08fbbbab3..93dfb79c2 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/CommandLineOptionsParserTest.java @@ -16,7 +16,6 @@ import static com.google.common.truth.Truth.assertThat; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; @@ -151,15 +150,13 @@ public void setExitIfChanged() { .isTrue(); } - // TODO(cushon): consider handling this in the parser and reporting a more detailed error @Test - public void illegalLines() { - try { - CommandLineOptionsParser.parse(Arrays.asList("-lines=1:1", "-lines=1:1")); - fail(); - } catch (IllegalArgumentException e) { - assertThat(e).hasMessageThat().contains("overlap"); - } + public void mergedLines() { + assertThat( + CommandLineOptionsParser.parse(Arrays.asList("-lines=1:5", "-lines=2:8")) + .lines() + .asRanges()) + .containsExactly(Range.closedOpen(0, 8)); } @Test From 6e3b852443363917504edd779e21c97f919ddf70 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Mon, 15 Apr 2024 09:56:07 -0700 Subject: [PATCH 282/379] update the IntelliJ plugin to 1.22.0 PiperOrigin-RevId: 624993575 --- idea_plugin/build.gradle.kts | 8 ++++++-- idea_plugin/src/main/resources/META-INF/plugin.xml | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 05010fe3c..0ba5032dc 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -14,7 +14,8 @@ * limitations under the License. */ -plugins { id("org.jetbrains.intellij") version "1.17.2" } +// https://github.com/JetBrains/intellij-platform-gradle-plugin/releases +plugins { id("org.jetbrains.intellij") version "1.17.3" } apply(plugin = "org.jetbrains.intellij") @@ -22,7 +23,8 @@ apply(plugin = "java") repositories { mavenCentral() } -val googleJavaFormatVersion = "1.21.0" +// https://github.com/google/google-java-format/releases +val googleJavaFormatVersion = "1.22.0" java { sourceCompatibility = JavaVersion.VERSION_11 @@ -61,6 +63,8 @@ tasks { dependencies { implementation("com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}") + // https://mvnrepository.com/artifact/junit/junit testImplementation("junit:junit:4.13.2") + // https://mvnrepository.com/artifact/com.google.truth/truth testImplementation("com.google.truth:truth:1.4.2") } diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index c426a1ff1..378c2529c 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,10 @@ ]]> +

1.22.0.0
+
Updated to use google-java-format 1.22.0.
+
1.21.0.0
+
Updated to use google-java-format 1.21.0.
1.20.0.0
Updated to use google-java-format 1.20.0.
1.19.2.0
From fdf4b29a6e1206f451bd96ed7967f4061921881a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 29 Apr 2024 14:11:05 -0700 Subject: [PATCH 283/379] Remove support for the String Templates preview feature Rollback of https://github.com/google/google-java-format/commit/b5feefe4ab4dbdbba393d769eb1815f26896104b, https://github.com/google/google-java-format/commit/38de9c4e05bc871496c232c1ccbfc4be06a580e2, https://github.com/google/google-java-format/commit/e946e82801eb5bbd52bea00355ba20450bc0725c See https://bugs.openjdk.org/browse/JDK-8329949 PiperOrigin-RevId: 629182379 --- .../googlejavaformat/java/JavaInput.java | 13 +- .../googlejavaformat/java/JavacTokens.java | 145 +++--------------- .../java/java21/Java21InputAstVisitor.java | 23 +-- .../java/FormatterIntegrationTest.java | 4 +- .../googlejavaformat/java/FormatterTest.java | 24 --- .../googlejavaformat/java/testdata/I981.input | 12 -- .../java/testdata/I981.output | 14 -- .../java/testdata/StringTemplate.input | 10 -- .../java/testdata/StringTemplate.output | 9 -- .../java/testdata/TextBlockTemplates.input | 11 -- .../java/testdata/TextBlockTemplates.output | 14 -- 11 files changed, 26 insertions(+), 253 deletions(-) delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.input delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.output delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.input delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.output delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.input delete mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index b5290ab10..01c617776 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -387,14 +387,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept final boolean isNumbered; // Is this tok numbered? (tokens and comments) String extraNewline = null; // Extra newline at end? List strings = new ArrayList<>(); - if (tokText.startsWith("'") - || tokText.startsWith("\"") - || JavacTokens.isStringFragment(t.kind())) { - // Perform this check first, STRINGFRAGMENT tokens can start with arbitrary characters. - isToken = true; - isNumbered = true; - strings.add(originalTokText); - } else if (Character.isWhitespace(tokText0)) { + if (Character.isWhitespace(tokText0)) { isToken = false; isNumbered = false; Iterator it = Newlines.lineIterator(originalTokText); @@ -411,6 +404,10 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept strings.add(line); } } + } else if (tokText.startsWith("'") || tokText.startsWith("\"")) { + isToken = true; + isNumbered = true; + strings.add(originalTokText); } else if (tokText.startsWith("//") || tokText.startsWith("/*")) { // For compatibility with an earlier lexer, the newline after a // comment is its own tok. if (tokText.startsWith("//") diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java index 986db3912..6daac33b9 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java @@ -15,8 +15,6 @@ package com.google.googlejavaformat.java; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkElementIndex; -import static java.util.Arrays.stream; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -29,15 +27,7 @@ import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.parser.UnicodeReader; import com.sun.tools.javac.util.Context; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; import java.util.Set; -import org.jspecify.annotations.Nullable; /** A wrapper around javac's lexer. */ final class JavacTokens { @@ -54,8 +44,6 @@ static class RawTok { private final int endPos; RawTok(String stringVal, TokenKind kind, int pos, int endPos) { - checkElementIndex(pos, endPos, "pos"); - checkArgument(pos < endPos, "expected pos (%s) < endPos (%s)", pos, endPos); this.stringVal = stringVal; this.kind = kind; this.pos = pos; @@ -83,18 +71,9 @@ public String stringVal() { } } - private static final TokenKind STRINGFRAGMENT = - stream(TokenKind.values()) - .filter(t -> t.name().contentEquals("STRINGFRAGMENT")) - .findFirst() - .orElse(null); - - static boolean isStringFragment(TokenKind kind) { - return STRINGFRAGMENT != null && Objects.equals(kind, STRINGFRAGMENT); - } - - private static ImmutableList readAllTokens( - String source, Context context, Set nonTerminalStringFragments) { + /** Lex the input and return a list of {@link RawTok}s. */ + public static ImmutableList getTokens( + String source, Context context, Set stopTokens) { if (source == null) { return ImmutableList.of(); } @@ -102,69 +81,20 @@ private static ImmutableList readAllTokens( char[] buffer = (source + EOF_COMMENT).toCharArray(); Scanner scanner = new AccessibleScanner(fac, new CommentSavingTokenizer(fac, buffer, buffer.length)); - List tokens = new ArrayList<>(); - do { - scanner.nextToken(); - tokens.add(scanner.token()); - } while (scanner.token().kind != TokenKind.EOF); - for (int i = 0; i < tokens.size(); i++) { - if (isStringFragment(tokens.get(i).kind)) { - int start = i; - while (isStringFragment(tokens.get(i).kind)) { - i++; - } - for (int j = start; j < i - 1; j++) { - nonTerminalStringFragments.add(tokens.get(j).pos); - } - } - } - // A string template is tokenized as a series of STRINGFRAGMENT tokens containing the string - // literal values, followed by the tokens for the template arguments. For the formatter, we - // want the stream of tokens to appear in order by their start position. - if (Runtime.version().feature() >= 21) { - Collections.sort(tokens, Comparator.comparingInt(t -> t.pos)); - } - return ImmutableList.copyOf(tokens); - } - - /** Lex the input and return a list of {@link RawTok}s. */ - public static ImmutableList getTokens( - String source, Context context, Set stopTokens) { - if (source == null) { - return ImmutableList.of(); - } - Set nonTerminalStringFragments = new HashSet<>(); - ImmutableList javacTokens = readAllTokens(source, context, nonTerminalStringFragments); - ImmutableList.Builder tokens = ImmutableList.builder(); int end = source.length(); int last = 0; - for (Token t : javacTokens) { + do { + scanner.nextToken(); + Token t = scanner.token(); if (t.comments != null) { - // javac accumulates comments in reverse order for (Comment c : Lists.reverse(t.comments)) { - int pos = c.getSourcePos(0); - int length; - if (pos == -1) { - // We've found a comment whose position hasn't been recorded. Deduce its position as the - // first `/` character after the end of the previous token. - // - // javac creates a new JavaTokenizer to process string template arguments, so - // CommentSavingTokenizer doesn't get a chance to preprocess those comments and save - // their text and positions. - // - // TODO: consider always using this approach once the minimum supported JDK is 16 and - // we can assume BasicComment#getRawCharacters is always available. - pos = source.indexOf('/', last); - length = CommentSavingTokenizer.commentLength(c); - } else { - length = c.getText().length(); + if (last < c.getSourcePos(0)) { + tokens.add(new RawTok(null, null, last, c.getSourcePos(0))); } - if (last < pos) { - tokens.add(new RawTok(null, null, last, pos)); - } - tokens.add(new RawTok(null, null, pos, pos + length)); - last = pos + length; + tokens.add( + new RawTok(null, null, c.getSourcePos(0), c.getSourcePos(0) + c.getText().length())); + last = c.getSourcePos(0) + c.getText().length(); } } if (stopTokens.contains(t.kind)) { @@ -176,25 +106,14 @@ public static ImmutableList getTokens( if (last < t.pos) { tokens.add(new RawTok(null, null, last, t.pos)); } - if (isStringFragment(t.kind)) { - int endPos = t.endPos; - int pos = t.pos; - if (nonTerminalStringFragments.contains(t.pos)) { - // Include the \ escape from \{...} in the preceding string fragment - endPos++; - } - tokens.add(new RawTok(source.substring(pos, endPos), t.kind, pos, endPos)); - last = endPos; - } else { - tokens.add( - new RawTok( - t.kind == TokenKind.STRINGLITERAL ? "\"" + t.stringVal() + "\"" : null, - t.kind, - t.pos, - t.endPos)); - last = t.endPos; - } - } + tokens.add( + new RawTok( + t.kind == TokenKind.STRINGLITERAL ? "\"" + t.stringVal() + "\"" : null, + t.kind, + t.pos, + t.endPos)); + last = t.endPos; + } while (scanner.token().kind != TokenKind.EOF); if (last < end) { tokens.add(new RawTok(null, null, last, end)); } @@ -203,32 +122,6 @@ public static ImmutableList getTokens( /** A {@link JavaTokenizer} that saves comments. */ static class CommentSavingTokenizer extends JavaTokenizer { - - private static final Method GET_RAW_CHARACTERS_METHOD = getRawCharactersMethod(); - - private static @Nullable Method getRawCharactersMethod() { - try { - // This is a method in PositionTrackingReader, but that class is not public. - return BasicComment.class.getMethod("getRawCharacters"); - } catch (NoSuchMethodException e) { - return null; - } - } - - static int commentLength(Comment comment) { - if (comment instanceof BasicComment && GET_RAW_CHARACTERS_METHOD != null) { - // If we've seen a BasicComment instead of a CommentWithTextAndPosition, getText() will - // be null, so we deduce the length using getRawCharacters. See also the comment at the - // usage of this method in getTokens. - try { - return ((char[]) GET_RAW_CHARACTERS_METHOD.invoke(((BasicComment) comment))).length; - } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); - } - } - return comment.getText().length(); - } - CommentSavingTokenizer(ScannerFactory fac, char[] buffer, int length) { super(fac, buffer, length); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java index 2192a32a9..859c9c0cf 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -23,7 +23,6 @@ import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.PatternCaseLabelTree; import com.sun.source.tree.PatternTree; -import com.sun.source.tree.StringTemplateTree; import com.sun.source.tree.Tree; import com.sun.tools.javac.tree.JCTree; import javax.lang.model.element.Name; @@ -63,7 +62,6 @@ public Void visitConstantCaseLabel(ConstantCaseLabelTree node, Void aVoid) { @Override public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unused) { - sync(node); scan(node.getDeconstructor(), null); builder.open(plusFour); token("("); @@ -82,25 +80,6 @@ public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unus return null; } - @SuppressWarnings("preview") - @Override - public Void visitStringTemplate(StringTemplateTree node, Void unused) { - sync(node); - builder.open(plusFour); - scan(node.getProcessor(), null); - token("."); - token(builder.peekToken().get()); - for (int i = 0; i < node.getFragments().size() - 1; i++) { - token("{"); - builder.breakOp(); - scan(node.getExpressions().get(i), null); - token("}"); - token(builder.peekToken().get()); - } - builder.close(); - return null; - } - @Override protected void variableName(Name name) { if (name.isEmpty()) { @@ -118,7 +97,7 @@ public Void scan(Tree tree, Void unused) { visitJcAnyPattern((JCTree.JCAnyPattern) tree); return null; } else { - return super.scan(tree, unused); + return super.scan(tree, null); } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index d31218e28..4a4cedc82 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -61,10 +61,8 @@ public class FormatterIntegrationTest { "I880", "Unnamed", "I981", - "StringTemplate", "I1020", - "I1037", - "TextBlockTemplates") + "I1037") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java index b0d7b4030..3835673d9 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterTest.java @@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.fail; -import static org.junit.Assume.assumeTrue; import com.google.common.base.Joiner; import com.google.common.io.CharStreams; @@ -511,27 +510,4 @@ public void removeTrailingTabsInComments() throws Exception { + " }\n" + "}\n"); } - - @Test - public void stringTemplateTests() throws Exception { - assumeTrue(Runtime.version().feature() >= 21); - assertThat( - new Formatter() - .formatSource( - "public class Foo {\n" - + " String test(){\n" - + " var simple = STR.\"mytemplate1XXXX \\{exampleXXXX.foo()}yyy\";\n" - + " var nested = STR.\"template \\{example. foo()+" - + " STR.\"templateInner\\{ example}\"}xxx }\";\n" - + " }\n" - + "}\n")) - .isEqualTo( - "public class Foo {\n" - + " String test() {\n" - + " var simple = STR.\"mytemplate1XXXX \\{exampleXXXX.foo()}yyy\";\n" - + " var nested = STR.\"template \\{example.foo() +" - + " STR.\"templateInner\\{example}\"}xxx }\";\n" - + " }\n" - + "}\n"); - } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.input deleted file mode 100644 index bba0b7267..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.input +++ /dev/null @@ -1,12 +0,0 @@ -class Foo { - private static final int X = 42; - private static final String A = STR."\{X} = \{X}"; - private static final String B = STR.""; - private static final String C = STR."\{X}"; - private static final String D = STR."\{X}\{X}"; - private static final String E = STR."\{X}\{X}\{X}"; - private static final String F = STR." \{X}"; - private static final String G = STR."\{X} "; - private static final String H = STR."\{X} one long incredibly unbroken sentence moving from "+"topic to topic so that no-one had a chance to interrupt"; - private static final String I = STR."\{X} \uD83D\uDCA9 "; -} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.output deleted file mode 100644 index ff173fb6a..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I981.output +++ /dev/null @@ -1,14 +0,0 @@ -class Foo { - private static final int X = 42; - private static final String A = STR."\{X} = \{X}"; - private static final String B = STR.""; - private static final String C = STR."\{X}"; - private static final String D = STR."\{X}\{X}"; - private static final String E = STR."\{X}\{X}\{X}"; - private static final String F = STR." \{X}"; - private static final String G = STR."\{X} "; - private static final String H = - STR."\{X} one long incredibly unbroken sentence moving from " - + "topic to topic so that no-one had a chance to interrupt"; - private static final String I = STR."\{X} \uD83D\uDCA9 "; -} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.input deleted file mode 100644 index 98a19bba7..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.input +++ /dev/null @@ -1,10 +0,0 @@ -public class StringTemplates { - void test(){ - var m = STR."template \{example}xxx"; - var nested = STR."template \{example.foo()+ STR."templateInner\{example}"}xxx }"; - var nestNested = STR."template \{example0. - foo() + - STR."templateInner\{example1.test(STR."\{example2 - }")}"}xxx }"; - } -} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.output deleted file mode 100644 index e60bab70b..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/StringTemplate.output +++ /dev/null @@ -1,9 +0,0 @@ -public class StringTemplates { - void test() { - var m = STR."template \{example}xxx"; - var nested = STR."template \{example.foo() + STR."templateInner\{example}"}xxx }"; - var nestNested = - STR."template \{ - example0.foo() + STR."templateInner\{example1.test(STR."\{example2}")}"}xxx }"; - } -} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.input deleted file mode 100644 index 2d00d3300..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.input +++ /dev/null @@ -1,11 +0,0 @@ -abstract class RSLs { - abstract String f(); - - String a = STR.""" - lorem - foo\{ /** a method */ f( // line comment - /* TODO */ - )}bar - ipsum - """; -} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.output deleted file mode 100644 index 36736724f..000000000 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/TextBlockTemplates.output +++ /dev/null @@ -1,14 +0,0 @@ -abstract class RSLs { - abstract String f(); - - String a = - STR.""" - lorem - foo\{ - /** a method */ - f( // line comment - /* TODO */ - )}bar - ipsum - """; -} From bec248bb39e6abd8b79e8f9900135d263b6f7ad9 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 1 May 2024 11:39:18 -0700 Subject: [PATCH 284/379] Add a test for trailing unicode escaped whitespace in text blocks PiperOrigin-RevId: 629785894 --- .../java/StringWrapperTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java index 5ef7cb51a..fd176ed4e 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -119,6 +119,35 @@ public void textBlockTrailingWhitespace() throws Exception { assertThat(actual).isEqualTo(expected); } + // It would be neat if the formatter could remove the trailing whitespace here, but in general + // it preserves unicode escapes from the original text. + @Test + public void textBlockTrailingWhitespaceUnicodeEscape() throws Exception { + assumeTrue(Runtime.version().feature() >= 15); + // We want a unicode escape in the Java source being formatted, so it needs to be escaped + // in the string literal in this test. + String input = + lines( + "public class T {", + " String s =", + " \"\"\"", + " lorem\\u0020", + " ipsum", + " \"\"\";", + "}"); + String expected = + lines( + "public class T {", + " String s =", + " \"\"\"", + " lorem\\u0020", + " ipsum", + " \"\"\";", + "}"); + String actual = StringWrapper.wrap(100, input, new Formatter()); + assertThat(actual).isEqualTo(expected); + } + @Test public void textBlockSpaceTabMix() throws Exception { assumeTrue(Runtime.version().feature() >= 15); From b9b6730b80a16798da559f2d50112cec3d8538ad Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 29 May 2024 09:28:19 -0700 Subject: [PATCH 285/379] Handle classes with no members and semi-colons PiperOrigin-RevId: 638312117 --- .../google/googlejavaformat/java/JavaInputAstVisitor.java | 6 ++++++ .../googlejavaformat/java/testdata/SemicolonInClass.input | 3 +++ .../googlejavaformat/java/testdata/SemicolonInClass.output | 3 +++ 3 files changed, 12 insertions(+) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SemicolonInClass.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SemicolonInClass.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 1e0675ffd..e00877e96 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -3744,6 +3744,12 @@ protected void addBodyDeclarations( tokenBreakTrailingComment("{", plusTwo); builder.blankLineWanted(BlankLineWanted.NO); builder.open(ZERO); + if (builder.peekToken().equals(Optional.of(";"))) { + builder.open(plusTwo); + dropEmptyDeclarations(); + builder.close(); + builder.forcedBreak(); + } token("}", plusTwo); builder.close(); } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SemicolonInClass.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SemicolonInClass.input new file mode 100644 index 000000000..52d3c1226 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SemicolonInClass.input @@ -0,0 +1,3 @@ +class SemicolonInClass { + ; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SemicolonInClass.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SemicolonInClass.output new file mode 100644 index 000000000..52d3c1226 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SemicolonInClass.output @@ -0,0 +1,3 @@ +class SemicolonInClass { + ; +} From 0b384e32b39117a8da2829d8543e7474338ddebe Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 30 May 2024 08:56:36 -0700 Subject: [PATCH 286/379] Prepare g-j-f for some internal javac API changes * Refactor comment handling in tokenization to avoid extending javac's internal Comment. This prepares for upcoming JDK changes to the Comment API, which break the current subclass approach by changing the return type of `Comment#getPos`, see also similar changes to Error Prone in unknown commit * `JCCompilationUnit#getImports` no longer returns `JCImport`, as part of the changes for modular imports. Supporting modular imports is future work, this change just avoids a crash formatting the existing syntax on the latest JDK versions. PiperOrigin-RevId: 638669955 --- .../googlejavaformat/java/JavacTokens.java | 77 ++++++++----------- .../java/RemoveUnusedImports.java | 8 +- 2 files changed, 36 insertions(+), 49 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java index 6daac33b9..793c6220c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavacTokens.java @@ -15,9 +15,9 @@ package com.google.googlejavaformat.java; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.collect.ImmutableList.toImmutableList; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; import com.sun.tools.javac.parser.JavaTokenizer; import com.sun.tools.javac.parser.Scanner; import com.sun.tools.javac.parser.ScannerFactory; @@ -25,8 +25,9 @@ import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.parser.Tokens.Token; import com.sun.tools.javac.parser.Tokens.TokenKind; -import com.sun.tools.javac.parser.UnicodeReader; import com.sun.tools.javac.util.Context; +import java.util.HashMap; +import java.util.Map; import java.util.Set; /** A wrapper around javac's lexer. */ @@ -79,8 +80,8 @@ public static ImmutableList getTokens( } ScannerFactory fac = ScannerFactory.instance(context); char[] buffer = (source + EOF_COMMENT).toCharArray(); - Scanner scanner = - new AccessibleScanner(fac, new CommentSavingTokenizer(fac, buffer, buffer.length)); + CommentSavingTokenizer tokenizer = new CommentSavingTokenizer(fac, buffer, buffer.length); + Scanner scanner = new AccessibleScanner(fac, tokenizer); ImmutableList.Builder tokens = ImmutableList.builder(); int end = source.length(); int last = 0; @@ -88,7 +89,7 @@ public static ImmutableList getTokens( scanner.nextToken(); Token t = scanner.token(); if (t.comments != null) { - for (Comment c : Lists.reverse(t.comments)) { + for (CommentWithTextAndPosition c : getComments(t, tokenizer.comments())) { if (last < c.getSourcePos(0)) { tokens.add(new RawTok(null, null, last, c.getSourcePos(0))); } @@ -120,17 +121,36 @@ public static ImmutableList getTokens( return tokens.build(); } + private static ImmutableList getComments( + Token token, Map comments) { + if (token.comments == null) { + return ImmutableList.of(); + } + // javac stores the comments in reverse declaration order + return token.comments.stream().map(comments::get).collect(toImmutableList()).reverse(); + } + /** A {@link JavaTokenizer} that saves comments. */ static class CommentSavingTokenizer extends JavaTokenizer { + + private final Map comments = new HashMap<>(); + CommentSavingTokenizer(ScannerFactory fac, char[] buffer, int length) { super(fac, buffer, length); } + Map comments() { + return comments; + } + @Override protected Comment processComment(int pos, int endPos, CommentStyle style) { char[] buf = getRawCharactersReflectively(pos, endPos); - return new CommentWithTextAndPosition( - pos, endPos, new AccessibleReader(fac, buf, buf.length), style); + Comment comment = super.processComment(pos, endPos, style); + CommentWithTextAndPosition commentWithTextAndPosition = + new CommentWithTextAndPosition(pos, endPos, new String(buf)); + comments.put(comment, commentWithTextAndPosition); + return comment; } private char[] getRawCharactersReflectively(int beginIndex, int endIndex) { @@ -153,21 +173,16 @@ private char[] getRawCharactersReflectively(int beginIndex, int endIndex) { } /** A {@link Comment} that saves its text and start position. */ - static class CommentWithTextAndPosition implements Comment { + static class CommentWithTextAndPosition { private final int pos; private final int endPos; - private final AccessibleReader reader; - private final CommentStyle style; - - private String text = null; + private final String text; - public CommentWithTextAndPosition( - int pos, int endPos, AccessibleReader reader, CommentStyle style) { + public CommentWithTextAndPosition(int pos, int endPos, String text) { this.pos = pos; this.endPos = endPos; - this.reader = reader; - this.style = style; + this.text = text; } /** @@ -176,7 +191,6 @@ public CommentWithTextAndPosition( *

The handling of javadoc comments in javac has more logic to skip over leading whitespace * and '*' characters when indexing into doc comments, but we don't need any of that. */ - @Override public int getSourcePos(int index) { checkArgument( 0 <= index && index < (endPos - pos), @@ -186,49 +200,22 @@ public int getSourcePos(int index) { return pos + index; } - @Override - public CommentStyle getStyle() { - return style; - } - - @Override public String getText() { - String text = this.text; - if (text == null) { - this.text = text = new String(reader.getRawCharacters()); - } return text; } - /** - * We don't care about {@code @deprecated} javadoc tags (see the DepAnn check). - * - * @return false - */ - @Override - public boolean isDeprecated() { - return false; - } - @Override public String toString() { return String.format("Comment: '%s'", getText()); } } - // Scanner(ScannerFactory, JavaTokenizer) is package-private + // Scanner(ScannerFactory, JavaTokenizer) is protected static class AccessibleScanner extends Scanner { protected AccessibleScanner(ScannerFactory fac, JavaTokenizer tokenizer) { super(fac, tokenizer); } } - // UnicodeReader(ScannerFactory, char[], int) is package-private - static class AccessibleReader extends UnicodeReader { - protected AccessibleReader(ScannerFactory fac, char[] buffer, int length) { - super(fac, buffer, length); - } - } - private JavacTokens() {} } diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index a0fc2f54a..8c3cae319 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -273,7 +273,7 @@ private static RangeMap buildReplacements( Set usedNames, Multimap> usedInJavadoc) { RangeMap replacements = TreeRangeMap.create(); - for (JCImport importTree : unit.getImports()) { + for (JCTree importTree : unit.getImports()) { String simpleName = getSimpleName(importTree); if (!isUnused(unit, usedNames, usedInJavadoc, importTree, simpleName)) { continue; @@ -291,7 +291,7 @@ private static RangeMap buildReplacements( return replacements; } - private static String getSimpleName(JCImport importTree) { + private static String getSimpleName(JCTree importTree) { return getQualifiedIdentifier(importTree).getIdentifier().toString(); } @@ -299,7 +299,7 @@ private static boolean isUnused( JCCompilationUnit unit, Set usedNames, Multimap> usedInJavadoc, - JCImport importTree, + JCTree importTree, String simpleName) { JCFieldAccess qualifiedIdentifier = getQualifiedIdentifier(importTree); String qualifier = qualifiedIdentifier.getExpression().toString(); @@ -322,7 +322,7 @@ private static boolean isUnused( return true; } - private static JCFieldAccess getQualifiedIdentifier(JCImport importTree) { + private static JCFieldAccess getQualifiedIdentifier(JCTree importTree) { // Use reflection because the return type is JCTree in some versions and JCFieldAccess in others try { return (JCFieldAccess) JCImport.class.getMethod("getQualifiedIdentifier").invoke(importTree); From db08589462600b26b69a2418b99d1de29026dcc9 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 31 May 2024 09:38:09 -0700 Subject: [PATCH 287/379] Automatic code cleanup. PiperOrigin-RevId: 639062534 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 152fdfde2..05a8fa9c5 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 32.1.3-jre 1.4.0 0.3.0 - 2.16 + 2.28.0 1.9 1.0.1 3.6.3 From 7fd9300499228717bcfee75ff4f836507df832ee Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 5 Jun 2024 08:29:51 -0700 Subject: [PATCH 288/379] Fix modifier order handling for `non-sealed` `non-sealed` is tokenized as three tokens, the modifier sorting logic was assuming it would show up as a single token. PiperOrigin-RevId: 640534518 --- .../java/ModifierOrderer.java | 142 ++++++++++++++---- .../java/FormatterIntegrationTest.java | 2 +- .../java/ModifierOrdererTest.java | 8 + .../java/testdata/Sealed.input | 6 + .../java/testdata/Sealed.output | 9 ++ 5 files changed, 140 insertions(+), 27 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/Sealed.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/Sealed.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java index e14b29036..1b26f7d69 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java @@ -16,6 +16,9 @@ package com.google.googlejavaformat.java; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.Iterables.getLast; + import com.google.common.collect.ImmutableList; import com.google.common.collect.Ordering; import com.google.common.collect.Range; @@ -26,12 +29,12 @@ import com.sun.tools.javac.parser.Tokens.TokenKind; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.lang.model.element.Modifier; +import org.jspecify.annotations.Nullable; /** Fixes sequences of modifiers to be in JLS order. */ final class ModifierOrderer { @@ -42,6 +45,71 @@ static JavaInput reorderModifiers(String text) throws FormatterException { new JavaInput(text), ImmutableList.of(Range.closedOpen(0, text.length()))); } + /** + * A class that contains the tokens corresponding to a modifier. This is usually a single token + * (e.g. for {@code public}), but may be multiple tokens for modifiers containing {@code -} (e.g. + * {@code non-sealed}). + */ + static class ModifierTokens implements Comparable { + private final ImmutableList tokens; + private final Modifier modifier; + + static ModifierTokens create(ImmutableList tokens) { + return new ModifierTokens(tokens, asModifier(tokens)); + } + + static ModifierTokens empty() { + return new ModifierTokens(ImmutableList.of(), null); + } + + ModifierTokens(ImmutableList tokens, Modifier modifier) { + this.tokens = tokens; + this.modifier = modifier; + } + + boolean isEmpty() { + return tokens.isEmpty() || modifier == null; + } + + Modifier modifier() { + return modifier; + } + + ImmutableList tokens() { + return tokens; + } + + private Token first() { + return tokens.get(0); + } + + private Token last() { + return getLast(tokens); + } + + int startPosition() { + return first().getTok().getPosition(); + } + + int endPosition() { + return last().getTok().getPosition() + last().getTok().getText().length(); + } + + ImmutableList getToksBefore() { + return first().getToksBefore(); + } + + ImmutableList getToksAfter() { + return last().getToksAfter(); + } + + @Override + public int compareTo(ModifierTokens o) { + checkState(!isEmpty()); // empty ModifierTokens are filtered out prior to sorting + return modifier.compareTo(o.modifier); + } + } + /** * Reorders all modifiers in the given text and within the given character ranges to be in JLS * order. @@ -57,43 +125,37 @@ static JavaInput reorderModifiers(JavaInput javaInput, Collection Iterator it = javaInput.getTokens().iterator(); TreeRangeMap replacements = TreeRangeMap.create(); while (it.hasNext()) { - Token token = it.next(); - if (!tokenRanges.contains(token.getTok().getIndex())) { - continue; - } - Modifier mod = asModifier(token); - if (mod == null) { + ModifierTokens tokens = getModifierTokens(it); + if (tokens.isEmpty() + || !tokens.tokens().stream() + .allMatch(token -> tokenRanges.contains(token.getTok().getIndex()))) { continue; } - List modifierTokens = new ArrayList<>(); - List mods = new ArrayList<>(); + List modifierTokens = new ArrayList<>(); - int begin = token.getTok().getPosition(); - mods.add(mod); - modifierTokens.add(token); + int begin = tokens.startPosition(); + modifierTokens.add(tokens); int end = -1; while (it.hasNext()) { - token = it.next(); - mod = asModifier(token); - if (mod == null) { + tokens = getModifierTokens(it); + if (tokens.isEmpty()) { break; } - mods.add(mod); - modifierTokens.add(token); - end = token.getTok().getPosition() + token.getTok().length(); + modifierTokens.add(tokens); + end = tokens.endPosition(); } - if (!Ordering.natural().isOrdered(mods)) { - Collections.sort(mods); + if (!Ordering.natural().isOrdered(modifierTokens)) { + List sorted = Ordering.natural().sortedCopy(modifierTokens); StringBuilder replacement = new StringBuilder(); - for (int i = 0; i < mods.size(); i++) { + for (int i = 0; i < sorted.size(); i++) { if (i > 0) { addTrivia(replacement, modifierTokens.get(i).getToksBefore()); } - replacement.append(mods.get(i)); - if (i < (modifierTokens.size() - 1)) { + replacement.append(sorted.get(i).modifier()); + if (i < (sorted.size() - 1)) { addTrivia(replacement, modifierTokens.get(i).getToksAfter()); } } @@ -109,11 +171,41 @@ private static void addTrivia(StringBuilder replacement, ImmutableList it) { + Token token = it.next(); + ImmutableList.Builder result = ImmutableList.builder(); + result.add(token); + if (!token.getTok().getText().equals("non")) { + return ModifierTokens.create(result.build()); + } + if (!it.hasNext()) { + return ModifierTokens.empty(); + } + Token dash = it.next(); + result.add(dash); + if (!dash.getTok().getText().equals("-") || !it.hasNext()) { + return ModifierTokens.empty(); + } + result.add(it.next()); + return ModifierTokens.create(result.build()); + } + + private static @Nullable Modifier asModifier(ImmutableList tokens) { + if (tokens.size() == 1) { + return asModifier(tokens.get(0)); + } + Modifier modifier = asModifier(getLast(tokens)); + if (modifier == null) { + return null; + } + return Modifier.valueOf("NON_" + modifier.name()); + } + /** * Returns the given token as a {@link javax.lang.model.element.Modifier}, or {@code null} if it * is not a modifier. */ - private static Modifier asModifier(Token token) { + private static @Nullable Modifier asModifier(Token token) { TokenKind kind = ((JavaInput.Tok) token.getTok()).kind(); if (kind != null) { switch (kind) { @@ -145,8 +237,6 @@ private static Modifier asModifier(Token token) { } } switch (token.getTok().getText()) { - case "non-sealed": - return Modifier.valueOf("NON_SEALED"); case "sealed": return Modifier.valueOf("SEALED"); default: diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 4a4cedc82..c7142b793 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -50,7 +50,7 @@ public class FormatterIntegrationTest { ImmutableMultimap.builder() .putAll(14, "I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574", "I594") .putAll(15, "I603") - .putAll(16, "I588") + .putAll(16, "I588", "Sealed") .putAll(17, "I683", "I684", "I696") .putAll( 21, diff --git a/core/src/test/java/com/google/googlejavaformat/java/ModifierOrdererTest.java b/core/src/test/java/com/google/googlejavaformat/java/ModifierOrdererTest.java index 1f8fc1721..0f01e9d3f 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/ModifierOrdererTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/ModifierOrdererTest.java @@ -17,6 +17,7 @@ package com.google.googlejavaformat.java; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.TruthJUnit.assume; import com.google.common.base.Joiner; import com.google.common.collect.Range; @@ -103,4 +104,11 @@ public void whitespace() throws FormatterException { .getText(); assertThat(output).contains("public\n static int a;"); } + + @Test + public void sealedClass() throws FormatterException { + assume().that(Runtime.version().feature()).isAtLeast(16); + assertThat(ModifierOrderer.reorderModifiers("non-sealed sealed public").getText()) + .isEqualTo("public sealed non-sealed"); + } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Sealed.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Sealed.input new file mode 100644 index 000000000..f19165843 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Sealed.input @@ -0,0 +1,6 @@ +class T { + sealed interface I extends A permits C, B {} + final class C implements I {} + sealed private interface A permits I {} + non-sealed private interface B extends I {} +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/Sealed.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Sealed.output new file mode 100644 index 000000000..4bafc6399 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/Sealed.output @@ -0,0 +1,9 @@ +class T { + sealed interface I extends A permits C, B {} + + final class C implements I {} + + private sealed interface A permits I {} + + private non-sealed interface B extends I {} +} From 3affd633ce2e798051defe2e09090b46c0a49098 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 17 Jun 2024 16:05:35 -0700 Subject: [PATCH 289/379] Adjust indentation of line comments inside expression switches For statement switches there's some ambiguity about whether a comment documents the previous or next case: ``` case 1: // case 1 falls through to 2 case 2: doSomething() ``` ``` // this is information about case 1 case 1: // this is information about case 2 case 2: doSomething() ``` For expression switches there is no fall through, so assume that a line comments before a case label always apply to the case label after it. PiperOrigin-RevId: 644163145 --- .../java/java17/Java17InputAstVisitor.java | 6 ++-- .../java/FormatterIntegrationTest.java | 11 ++++++- .../java/testdata/SwitchComment.input | 31 +++++++++++++++++++ .../java/testdata/SwitchComment.output | 31 +++++++++++++++++++ 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java index e502f49a1..486324fb7 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java @@ -19,6 +19,7 @@ import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; +import com.google.googlejavaformat.Indent; import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.OpsBuilder.BlankLineWanted; import com.google.googlejavaformat.java.JavaInputAstVisitor; @@ -232,10 +233,11 @@ public Void visitCase(CaseTree node, Void unused) { && !node.getBody().getKind().equals(Tree.Kind.BLOCK) ? plusFour : ZERO); + Indent commentIndent = node.getCaseKind().equals(CaseTree.CaseKind.RULE) ? ZERO : plusTwo; if (isDefault) { - token("default", plusTwo); + token("default", commentIndent); } else { - token("case", plusTwo); + token("case", commentIndent); builder.open(labels.size() > 1 ? plusFour : ZERO); builder.space(); boolean afterFirstToken = false; diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index c7142b793..3e4e175e6 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -48,7 +48,16 @@ public class FormatterIntegrationTest { private static final ImmutableMultimap VERSIONED_TESTS = ImmutableMultimap.builder() - .putAll(14, "I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574", "I594") + .putAll( + 14, + "I477", + "Records", + "RSLs", + "Var", + "ExpressionSwitch", + "I574", + "I594", + "SwitchComment") .putAll(15, "I603") .putAll(16, "I588", "Sealed") .putAll(17, "I683", "I684", "I696") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.input new file mode 100644 index 000000000..f43acd351 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.input @@ -0,0 +1,31 @@ +class T { + void f(String v) { + int x = + switch (v) { + // this is a line comment about "zero" + case "zero" -> 0; + case "one" -> + // this is a line comment about "one" + 1; + case "two" -> // this is a line comment about "two" + 2; + default -> -1; + }; + } + + void g(String v) { + int x = + switch (v) { + // this is a line comment about "zero" + case "zero": + return 0; + case "one": + // this is a line comment about "one" + return 1; + case "two": // this is a line comment about "two" + return 2; + default: + return -1; + }; + } +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.output new file mode 100644 index 000000000..ff4753b1e --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.output @@ -0,0 +1,31 @@ +class T { + void f(String v) { + int x = + switch (v) { + // this is a line comment about "zero" + case "zero" -> 0; + case "one" -> + // this is a line comment about "one" + 1; + case "two" -> // this is a line comment about "two" + 2; + default -> -1; + }; + } + + void g(String v) { + int x = + switch (v) { + // this is a line comment about "zero" + case "zero": + return 0; + case "one": + // this is a line comment about "one" + return 1; + case "two": // this is a line comment about "two" + return 2; + default: + return -1; + }; + } +} From f7543b2a7d3b9c5b8214b33e8762e9550f5ab20f Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 17 Jun 2024 17:53:11 -0700 Subject: [PATCH 290/379] Adjust line comment indentation inside statement switches Follow-up to https://github.com/google/google-java-format/commit/3affd633ce2e798051defe2e09090b46c0a49098 Fixes https://github.com/google/google-java-format/issues/876 PiperOrigin-RevId: 644190687 --- .../googlejavaformat/java/java17/Java17InputAstVisitor.java | 6 ++---- .../googlejavaformat/java/testdata/SwitchComment.output | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java index 486324fb7..a0037edb7 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java @@ -19,7 +19,6 @@ import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; -import com.google.googlejavaformat.Indent; import com.google.googlejavaformat.OpsBuilder; import com.google.googlejavaformat.OpsBuilder.BlankLineWanted; import com.google.googlejavaformat.java.JavaInputAstVisitor; @@ -233,11 +232,10 @@ public Void visitCase(CaseTree node, Void unused) { && !node.getBody().getKind().equals(Tree.Kind.BLOCK) ? plusFour : ZERO); - Indent commentIndent = node.getCaseKind().equals(CaseTree.CaseKind.RULE) ? ZERO : plusTwo; if (isDefault) { - token("default", commentIndent); + token("default", ZERO); } else { - token("case", commentIndent); + token("case", ZERO); builder.open(labels.size() > 1 ? plusFour : ZERO); builder.space(); boolean afterFirstToken = false; diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.output index ff4753b1e..f1afa6484 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchComment.output @@ -16,7 +16,7 @@ class T { void g(String v) { int x = switch (v) { - // this is a line comment about "zero" + // this is a line comment about "zero" case "zero": return 0; case "one": From 1296f1d90aef9bb96b2c859a834eb98dc7fb1d66 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 17 Jul 2024 12:56:57 -0700 Subject: [PATCH 291/379] Use JSpecify 1.0! PiperOrigin-RevId: 653332912 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 05a8fa9c5..96e613a0a 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ 1.8 32.1.3-jre 1.4.0 - 0.3.0 + 1.0.0 2.28.0 1.9 1.0.1 From de57db592b7e60cc4bab87a2e3f590d44e346675 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Mon, 29 Jul 2024 11:13:54 -0700 Subject: [PATCH 292/379] Add customization for google-java-format arguments Setting google-java-format-arguments to `'("--aosp")` makes it easy to format on Android java files. PiperOrigin-RevId: 657263779 --- core/src/main/scripts/google-java-format.el | 28 +++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/core/src/main/scripts/google-java-format.el b/core/src/main/scripts/google-java-format.el index f269ab361..5df8a1396 100644 --- a/core/src/main/scripts/google-java-format.el +++ b/core/src/main/scripts/google-java-format.el @@ -49,6 +49,13 @@ A string containing the name or the full path of the executable." :type '(file :must-match t :match (lambda (widget file) (file-executable-p file))) :risky t) +(defcustom google-java-format-arguments + '() + "Arguments to pass into google-java-format-executable" + :group 'google-java-format + :type '(repeat string) + :risky t) + ;;;###autoload (defun google-java-format-region (start end) "Use google-java-format to format the code between START and END. @@ -62,16 +69,17 @@ there is no region, then formats the current line." (temp-buffer (generate-new-buffer " *google-java-format-temp*")) (stderr-file (make-temp-file "google-java-format"))) (unwind-protect - (let ((status (call-process-region - ;; Note that emacs character positions are 1-indexed, - ;; and google-java-format is 0-indexed, so we have to - ;; subtract 1 from START to line it up correctly. - (point-min) (point-max) - google-java-format-executable - nil (list temp-buffer stderr-file) t - "--offset" (number-to-string (1- start)) - "--length" (number-to-string (- end start)) - "-")) + (let ((status (apply #'call-process-region + ;; Note that emacs character positions are 1-indexed, + ;; and google-java-format is 0-indexed, so we have to + ;; subtract 1 from START to line it up correctly. + (point-min) (point-max) + google-java-format-executable + nil (list temp-buffer stderr-file) t + (append google-java-format-arguments + `("--offset" ,(number-to-string (1- start)) + "--length" ,(number-to-string (- end start)) + "-")))) (stderr (with-temp-buffer (insert-file-contents stderr-file) From b3c7c11015646055a8029366d2410f9b3016c530 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 5 Aug 2024 11:16:38 -0700 Subject: [PATCH 293/379] Fix inconsistency in formatting of comments in switch statements This was introduced by https://github.com/google/google-java-format/commit/f7543b2a7d3b9c5b8214b33e8762e9550f5ab20f, which only updated the logic for for JDK 17+. Fixes https://github.com/google/google-java-format/issues/1127 PiperOrigin-RevId: 659616575 --- .../java/JavaInputAstVisitor.java | 4 ++-- .../java/testdata/LegacySwitchComment.input | 17 +++++++++++++++++ .../java/testdata/LegacySwitchComment.output | 17 +++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/LegacySwitchComment.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/LegacySwitchComment.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index e00877e96..01f9a3e05 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -1875,10 +1875,10 @@ public Void visitCase(CaseTree node, Void unused) { markForPartialFormat(); builder.forcedBreak(); if (node.getExpression() == null) { - token("default", plusTwo); + token("default", ZERO); token(":"); } else { - token("case", plusTwo); + token("case", ZERO); builder.space(); scan(node.getExpression(), null); token(":"); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/LegacySwitchComment.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/LegacySwitchComment.input new file mode 100644 index 000000000..07ce2f4d2 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/LegacySwitchComment.input @@ -0,0 +1,17 @@ +class T { + int test(String v) { + switch (v) { + // this is a line comment about "zero" + case "zero": + return 0; + case "one": + // this is a line comment about "one" + return 1; + // this is a line comment about "two" + case "two": + return 2; + default: + return -1; + } + } +} \ No newline at end of file diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/LegacySwitchComment.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/LegacySwitchComment.output new file mode 100644 index 000000000..70a0b6bea --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/LegacySwitchComment.output @@ -0,0 +1,17 @@ +class T { + int test(String v) { + switch (v) { + // this is a line comment about "zero" + case "zero": + return 0; + case "one": + // this is a line comment about "one" + return 1; + // this is a line comment about "two" + case "two": + return 2; + default: + return -1; + } + } +} From ebf9b52314d7adddeae4add42a1757f30c87c5d6 Mon Sep 17 00:00:00 2001 From: cpovirk Date: Tue, 20 Aug 2024 15:33:34 -0700 Subject: [PATCH 294/379] Avoid mangling `{@snippet ...}`. This CL also implements some minimal formatting behavior _around_ `{@snippet ...}` (namely, a blank line before and after). It does not make any effort to change formatting _inside_ `{@snippet ...}`, only to stop reflowing it blindly. PiperOrigin-RevId: 665555661 --- .../java/javadoc/JavadocFormatter.java | 6 +++ .../java/javadoc/JavadocLexer.java | 25 ++++++++++- .../java/javadoc/JavadocWriter.java | 32 ++++++++++++++ .../googlejavaformat/java/javadoc/Token.java | 4 ++ .../java/JavadocFormattingTest.java | 42 +++++++++++++++++++ 5 files changed, 107 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java index 03938a677..4d45c9874 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java @@ -66,6 +66,12 @@ private static String render(List input, int blockIndent) { case FOOTER_JAVADOC_TAG_START: output.writeFooterJavadocTagStart(token); break; + case SNIPPET_BEGIN: + output.writeSnippetBegin(token); + break; + case SNIPPET_END: + output.writeSnippetEnd(token); + break; case LIST_OPEN_TAG: output.writeListOpen(token); break; diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java index cc707ae7e..d40f34c6b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocLexer.java @@ -42,6 +42,8 @@ import static com.google.googlejavaformat.java.javadoc.Token.Type.PARAGRAPH_OPEN_TAG; import static com.google.googlejavaformat.java.javadoc.Token.Type.PRE_CLOSE_TAG; import static com.google.googlejavaformat.java.javadoc.Token.Type.PRE_OPEN_TAG; +import static com.google.googlejavaformat.java.javadoc.Token.Type.SNIPPET_BEGIN; +import static com.google.googlejavaformat.java.javadoc.Token.Type.SNIPPET_END; import static com.google.googlejavaformat.java.javadoc.Token.Type.TABLE_CLOSE_TAG; import static com.google.googlejavaformat.java.javadoc.Token.Type.TABLE_OPEN_TAG; import static com.google.googlejavaformat.java.javadoc.Token.Type.WHITESPACE; @@ -97,6 +99,7 @@ private static String stripJavadocBeginAndEnd(String input) { private final NestingCounter preDepth = new NestingCounter(); private final NestingCounter codeDepth = new NestingCounter(); private final NestingCounter tableDepth = new NestingCounter(); + private boolean outerInlineTagIsSnippet; private boolean somethingSinceNewline; private JavadocLexer(CharStream input) { @@ -158,13 +161,26 @@ private Type consumeToken() throws LexException { } somethingSinceNewline = true; - if (input.tryConsumeRegex(INLINE_TAG_OPEN_PATTERN)) { + if (input.tryConsumeRegex(SNIPPET_TAG_OPEN_PATTERN)) { + if (braceDepth.value() == 0) { + braceDepth.increment(); + outerInlineTagIsSnippet = true; + return SNIPPET_BEGIN; + } + braceDepth.increment(); + return LITERAL; + } else if (input.tryConsumeRegex(INLINE_TAG_OPEN_PATTERN)) { braceDepth.increment(); return LITERAL; } else if (input.tryConsume("{")) { braceDepth.incrementIfPositive(); return LITERAL; } else if (input.tryConsume("}")) { + if (outerInlineTagIsSnippet && braceDepth.value() == 1) { + braceDepth.decrementIfPositive(); + outerInlineTagIsSnippet = false; + return SNIPPET_END; + } braceDepth.decrementIfPositive(); return LITERAL; } @@ -239,7 +255,10 @@ private Type consumeToken() throws LexException { } private boolean preserveExistingFormatting() { - return preDepth.isPositive() || tableDepth.isPositive() || codeDepth.isPositive(); + return preDepth.isPositive() + || tableDepth.isPositive() + || codeDepth.isPositive() + || outerInlineTagIsSnippet; } private void checkMatchingTags() throws LexException { @@ -400,6 +419,7 @@ private static ImmutableList optionalizeSpacesAfterLinks(List inpu *

Also trim leading and trailing blank lines, and move the trailing `}` to its own line. */ private static ImmutableList deindentPreCodeBlocks(List input) { + // TODO: b/323389829 - De-indent {@snippet ...} blocks, too. ImmutableList.Builder output = ImmutableList.builder(); for (PeekingIterator tokens = peekingIterator(input.iterator()); tokens.hasNext(); ) { if (tokens.peek().getType() != PRE_OPEN_TAG) { @@ -528,6 +548,7 @@ private static boolean hasMultipleNewlines(String s) { private static final Pattern BLOCKQUOTE_OPEN_PATTERN = openTagPattern("blockquote"); private static final Pattern BLOCKQUOTE_CLOSE_PATTERN = closeTagPattern("blockquote"); private static final Pattern BR_PATTERN = openTagPattern("br"); + private static final Pattern SNIPPET_TAG_OPEN_PATTERN = compile("^[{]@snippet\\b"); private static final Pattern INLINE_TAG_OPEN_PATTERN = compile("^[{]@\\w*"); /* * We exclude < so that we don't swallow following HTML tags. This lets us fix up "foo

" (~400 diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java index 0361415a1..8a4100e45 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java @@ -123,6 +123,38 @@ void writeFooterJavadocTagStart(Token token) { continuingFooterTag = true; } + void writeSnippetBegin(Token token) { + requestBlankLine(); + writeToken(token); + /* + * We don't request a newline here because we should have at least a colon following on this + * line, and we may have attributes after that. + * + * (If we find it convenient, we could instead consume the entire rest of the line as part of + * the same token as `{@snippet` itself. But we already would never split the rest of the line + * across lines (because we preserve whitespace), so that might not accomplish anything. Plus, + * we'd probably want to be careful not to swallow an expectedly early closing `}`.) + */ + } + + void writeSnippetEnd(Token token) { + /* + * We don't request a newline here because we have preserved all newlines that existed in the + * input. TODO: b/323389829 - Improve upon that. Specifically: + * + * - If there is not yet a newline, we should add one. + * + * - If there are multiple newlines, we should probably collapse them. + * + * - If the closing brace isn't indented as we'd want (as in the link below, in which the whole + * @apiNote isn't indented), we should indent it. + * + * https://github.com/openjdk/jdk/blob/1ebf2cf639300728ffc024784f5dc1704317b0b3/src/java.base/share/classes/java/util/Collections.java#L5993-L6006 + */ + writeToken(token); + requestBlankLine(); + } + void writeListOpen(Token token) { requestBlankLine(); diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/Token.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/Token.java index d617824b0..f74996060 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/Token.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/Token.java @@ -41,6 +41,10 @@ enum Type { END_JAVADOC, /** The {@code @foo} that begins a block Javadoc tag like {@code @throws}. */ FOOTER_JAVADOC_TAG_START, + /** The opening {@code {@snippet} of a code snippet. */ + SNIPPET_BEGIN, + /** The closing {@code }} of a code snippet. */ + SNIPPET_END, LIST_OPEN_TAG, LIST_CLOSE_TAG, LIST_ITEM_OPEN_TAG, diff --git a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java index 6849c01f2..aab8ec5d4 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java @@ -906,6 +906,48 @@ public void unicodeCharacterCountArguableBug() { doFormatTest(input, expected); } + @Test + public void blankLinesAroundSnippetAndNoMangling() { + String[] input = { + "/**", // + " * hello world", + " * {@snippet :", + " * public class Foo {", + " * private String s;", + " * }", + " * }", + " * hello again", + " */", + "class Test {}", + }; + String[] expected = { + "/**", // + " * hello world", + " *", + " * {@snippet :", + " * public class Foo {", + " * private String s;", + " * }", + " * }", + " *", + " * hello again", + " */", + "class Test {}", + }; + doFormatTest(input, expected); + } + + @Test + public void notASnippetUnlessOuterTag() { + String[] input = { + "/** I would like to tell you about the {@code {@snippet ...}} tag. */", "class Test {}", + }; + String[] expected = { + "/** I would like to tell you about the {@code {@snippet ...}} tag. */", "class Test {}", + }; + doFormatTest(input, expected); + } + @Test public void blankLineBeforeParams() { String[] input = { From ac46c75fbc0387cb6daa45007ba1fa64f1885899 Mon Sep 17 00:00:00 2001 From: Nicholas Rayburn <52075362+nrayburn-tech@users.noreply.github.com> Date: Wed, 21 Aug 2024 07:43:53 -0700 Subject: [PATCH 295/379] Fix #1132 Load services outside of constructors and class initializers Fixes the error on startup by loading the service when needed and not when the class is initializing. IntelliJ docs on this, https://plugins.jetbrains.com/docs/intellij/plugin-services.html#retrieving-a-service. Tested locally with IntelliJ versions 2021.3 and 2024.2. #1134 has bug #1132 tagged, but I don't think it does anything to resolve the issue in it's current state. (I do agree that getting on the newer IntelliJ tooling is beneficial though, it offers inspections that catches issues like this.) Fixes #1132. Fixes #1138 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1138 from nrayburn-tech:fix/1132 5866980075b52167834dfd9d2e25a739b3f06760 PiperOrigin-RevId: 665876052 --- .../intellij/InitialConfigurationStartupActivity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java index 940def655..95e13d325 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java @@ -27,8 +27,6 @@ final class InitialConfigurationStartupActivity implements StartupActivity.Background { private static final String NOTIFICATION_TITLE = "Enable google-java-format"; - private static final NotificationGroup NOTIFICATION_GROUP = - NotificationGroupManager.getInstance().getNotificationGroup(NOTIFICATION_TITLE); @Override public void runActivity(@NotNull Project project) { @@ -43,9 +41,11 @@ public void runActivity(@NotNull Project project) { } private void displayNewUserNotification(Project project, GoogleJavaFormatSettings settings) { + NotificationGroupManager groupManager = NotificationGroupManager.getInstance(); + NotificationGroup group = groupManager.getNotificationGroup(NOTIFICATION_TITLE); Notification notification = new Notification( - NOTIFICATION_GROUP.getDisplayId(), + group.getDisplayId(), NOTIFICATION_TITLE, "The google-java-format plugin is disabled by default. " + "Enable for this project.", From 0ebb58884d418d5f168929e05c10891c631315e6 Mon Sep 17 00:00:00 2001 From: Matthias Maeller Date: Wed, 21 Aug 2024 07:56:18 -0700 Subject: [PATCH 296/379] #1132 Migrate to IntelliJ Platform Gradle Plugin 2.0 Hello, I have no experience in IntelliJ plugin development, but maybe I can support you that the required invest in time isn't that high. As far as I can tell the `gradle build` works. Due to the changes of the IntelliJ gradle plugin I was urged to raise the java compatibility to 17 as well as the supported IntelliJ version to at least 2022.3 (see [requirements](https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin.html#requirements)) #1132 Fixes #1134 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1134 from mmaeller:gh-1132 abed210e6c6da515e4d147b28a4058d7f1ef2c3d PiperOrigin-RevId: 665880070 --- idea_plugin/.gitignore | 3 ++- idea_plugin/build.gradle.kts | 51 +++++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/idea_plugin/.gitignore b/idea_plugin/.gitignore index 16bc65a53..a5e690ca2 100644 --- a/idea_plugin/.gitignore +++ b/idea_plugin/.gitignore @@ -2,4 +2,5 @@ build .gradle gradle gradlew -gradlew.bat \ No newline at end of file +gradlew.bat +.intellijPlatform \ No newline at end of file diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 0ba5032dc..3ece2f3fa 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -1,3 +1,4 @@ +import org.jetbrains.intellij.platform.gradle.TestFrameworkType /* * Copyright 2017 Google Inc. All Rights Reserved. * @@ -15,40 +16,42 @@ */ // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases -plugins { id("org.jetbrains.intellij") version "1.17.3" } - -apply(plugin = "org.jetbrains.intellij") +plugins { + id("org.jetbrains.intellij.platform") version "2.0.1" +} -apply(plugin = "java") +repositories { + mavenCentral() -repositories { mavenCentral() } + intellijPlatform { + defaultRepositories() + } +} // https://github.com/google/google-java-format/releases val googleJavaFormatVersion = "1.22.0" java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 -} - -intellij { - pluginName.set("google-java-format") - plugins.set(listOf("java")) - version.set("2021.3") + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } -tasks { - patchPluginXml { - version.set("${googleJavaFormatVersion}.0") - sinceBuild.set("213") - untilBuild.set("") +intellijPlatform { + pluginConfiguration { + name = "google-java-format" + version = "${googleJavaFormatVersion}.0" + ideaVersion { + sinceBuild = "223" + untilBuild = "" + } } - publishPlugin { - val jetbrainsPluginRepoToken: String by project - token.set(jetbrainsPluginRepoToken) + publishing { + token = System.getenv("ORG_GRADLE_PROJECT_intellijPlatform.publishing.token") } +} +tasks { withType().configureEach { jvmArgs( "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", @@ -62,6 +65,12 @@ tasks { } dependencies { + intellijPlatform { + intellijIdeaCommunity("2022.3") + bundledPlugin("com.intellij.java") + instrumentationTools() + testFramework(TestFrameworkType.Plugin.Java) + } implementation("com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}") // https://mvnrepository.com/artifact/junit/junit testImplementation("junit:junit:4.13.2") From 5544952d819554d040608462a46e7185edc2b216 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Wed, 21 Aug 2024 09:52:05 -0700 Subject: [PATCH 297/379] Update IntelliJ plugin to 1.23.0. PiperOrigin-RevId: 665921070 --- idea_plugin/build.gradle.kts | 35 ++++++++++++------- .../src/main/resources/META-INF/plugin.xml | 4 +++ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 3ece2f3fa..20ac33ffb 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -29,7 +29,7 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.22.0" +val googleJavaFormatVersion = "1.23.0" java { sourceCompatibility = JavaVersion.VERSION_17 @@ -42,25 +42,36 @@ intellijPlatform { version = "${googleJavaFormatVersion}.0" ideaVersion { sinceBuild = "223" - untilBuild = "" } } publishing { - token = System.getenv("ORG_GRADLE_PROJECT_intellijPlatform.publishing.token") + val jetbrainsPluginRepoToken: String by project + token.set(jetbrainsPluginRepoToken) + } +} + +var gjfRequiredJvmArgs = + listOf( + "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + ) + +tasks { + runIde { + jvmArgumentProviders += CommandLineArgumentProvider { + gjfRequiredJvmArgs + } } } tasks { withType().configureEach { - jvmArgs( - "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", - ) + jvmArgs(gjfRequiredJvmArgs) } } @@ -75,5 +86,5 @@ dependencies { // https://mvnrepository.com/artifact/junit/junit testImplementation("junit:junit:4.13.2") // https://mvnrepository.com/artifact/com.google.truth/truth - testImplementation("com.google.truth:truth:1.4.2") + testImplementation("com.google.truth:truth:1.4.4") } diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 378c2529c..8d7574539 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,10 @@ ]]> +

1.23.0.0
+
Updated to use google-java-format 1.23.0.
+
Fix crashes in IntelliJ 2024.2 (Thanks, @nrayburn-tech!)
+
Updated to the latest IntelliJ build system (Thanks, @mmaeller!)
1.22.0.0
Updated to use google-java-format 1.22.0.
1.21.0.0
From 3fe163bd894587db524f26fe844765118dce9319 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Wed, 21 Aug 2024 10:08:23 -0700 Subject: [PATCH 298/379] Fix the until-build property of the IntelliJ plugin. Setting it to "" creates a broken plugin, but omitting it sets it to the same as since-build. So apparently you have to do this. PiperOrigin-RevId: 665927556 --- idea_plugin/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 20ac33ffb..c7d1d4ba1 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -42,6 +42,7 @@ intellijPlatform { version = "${googleJavaFormatVersion}.0" ideaVersion { sinceBuild = "223" + untilBuild = provider { null } } } From f9eca5ac8c8b27df3cfcd68fb66d6d284352dc8f Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Wed, 21 Aug 2024 18:53:36 -0700 Subject: [PATCH 299/379] Update the README to point to JetBrains documentation where appropriate. Fixes https://github.com/google/google-java-format/issues/1136 PiperOrigin-RevId: 666125973 --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 38fdac5e8..83a524bbd 100644 --- a/README.md +++ b/README.md @@ -35,14 +35,14 @@ is available from the plugin repository. To install it, go to your IDE's settings and select the `Plugins` category. Click the `Marketplace` tab, search for the `google-java-format` plugin, and click the `Install` button. -The plugin will be disabled by default. To enable it in the current project, go -to `File→Settings...→google-java-format Settings` (or `IntelliJ -IDEA→Preferences...→Other Settings→google-java-format Settings` on macOS) and -check the `Enable google-java-format` checkbox. (A notification will be -presented when you first open a project offering to do this for you.) +The plugin will be disabled by default. To enable, +[open the Project settings](https://www.jetbrains.com/help/idea/configure-project-settings.html), +then click "google-java-format Settings" and check the "Enable +google-java-format" checkbox. -To enable it by default in new projects, use `File→Other Settings→Default -Settings...`. +To enable it by default in new projects, +[open the default settings for new projects](https://www.jetbrains.com/help/idea/configure-project-settings.html#new-default-settings) +and configure it under "Other Settings/google-java-format Settings". When enabled, it will replace the normal `Reformat Code` and `Optimize Imports` actions. @@ -50,8 +50,9 @@ actions. #### IntelliJ JRE Config The google-java-format plugin uses some internal classes that aren't available -without extra configuration. To use the plugin, go to `Help→Edit Custom VM -Options...` and paste in these lines: +without extra configuration. To use the plugin, you need to +[add some options to your IDE's Java runtime](https://www.jetbrains.com/help/idea/tuning-the-ide.html#procedure-jvm-options). +To do that, go to `Help→Edit Custom VM Options...` and paste in these lines: ``` --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED From 9f2611e348b87b503de2195c77b3e66f53ad314f Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Mon, 26 Aug 2024 13:32:39 -0700 Subject: [PATCH 300/379] Fix package version metadata #9. * ebnf-mode: Last change 13 years ago with open PR from phst from 2019. For the sake of the current package version metadata work, just slap in a pkg.el file for now. * llm-goose: Missing header. * gyp: Missing header. * lv: Include pkg.el added earlier. PiperOrigin-RevId: 667696660 --- core/src/main/scripts/google-java-format.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/scripts/google-java-format.el b/core/src/main/scripts/google-java-format.el index 5df8a1396..1bb3ffdc2 100644 --- a/core/src/main/scripts/google-java-format.el +++ b/core/src/main/scripts/google-java-format.el @@ -2,8 +2,6 @@ ;; ;; Copyright 2015 Google, Inc. All Rights Reserved. ;; -;; Package-Requires: ((emacs "24")) -;; ;; Licensed under the Apache License, Version 2.0 (the "License"); ;; you may not use this file except in compliance with the License. ;; You may obtain a copy of the License at @@ -17,6 +15,8 @@ ;; limitations under the License. ;; Keywords: tools, Java +;; Version: 0.1.0 +;; Package-Requires: ((emacs "24")) ;;; Commentary: @@ -109,5 +109,4 @@ there is no region, then formats the current line." (defalias 'google-java-format 'google-java-format-region) (provide 'google-java-format) - ;;; google-java-format.el ends here From 8a0e3b3d7cb2c4efeffe5610aa1146a85f0ffa10 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 11 Sep 2024 16:07:03 -0700 Subject: [PATCH 301/379] Add a regression test for handling of `///` comments https://github.com/google/google-java-format/issues/1153 PiperOrigin-RevId: 673574143 --- .../java/FormatterIntegrationTest.java | 2 ++ .../googlejavaformat/java/testdata/I1153.input | 15 +++++++++++++++ .../googlejavaformat/java/testdata/I1153.output | 15 +++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I1153.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I1153.output diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 3e4e175e6..d0817a2cf 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -72,6 +72,8 @@ public class FormatterIntegrationTest { "I981", "I1020", "I1037") + // TODO: https://github.com/google/google-java-format/issues/1153 + // .putAll(23, "I1153") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1153.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1153.input new file mode 100644 index 000000000..e2b27dde1 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1153.input @@ -0,0 +1,15 @@ +class I1153 { + void f() { + //// (1) one + int one; + + //// (2) two + int two; + + //// (2.1) if we need to collect data using multiple different collectors, e.g. taxonomy and + //// ranges, or even two taxonomy facets that use different Category List Field, we can + //// use MultiCollectorManager, e.g.: + // TODO: This should be (2.1) two point one + int twoPointOne; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1153.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1153.output new file mode 100644 index 000000000..e2b27dde1 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1153.output @@ -0,0 +1,15 @@ +class I1153 { + void f() { + //// (1) one + int one; + + //// (2) two + int two; + + //// (2.1) if we need to collect data using multiple different collectors, e.g. taxonomy and + //// ranges, or even two taxonomy facets that use different Category List Field, we can + //// use MultiCollectorManager, e.g.: + // TODO: This should be (2.1) two point one + int twoPointOne; + } +} From 5e0d9e3d08b3c4dee83059af5c10a6ed07575b26 Mon Sep 17 00:00:00 2001 From: Dawid Weiss Date: Fri, 13 Sep 2024 08:18:21 -0700 Subject: [PATCH 302/379] Fix different formatting of block line comments with openjdk 23+ Fixes #1153. Fixes #1161 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1161 from dweiss:1153-block-line-comments-in-java23 e3ed83c6d705589f28565ad6050631394bc75d49 PiperOrigin-RevId: 674304999 --- .../google/googlejavaformat/java/JavaCommentsHelper.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java b/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java index d34ecc43f..d54b2317e 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java @@ -49,7 +49,11 @@ public String rewrite(Tok tok, int maxWidth, int column0) { List lines = new ArrayList<>(); Iterator it = Newlines.lineIterator(text); while (it.hasNext()) { - lines.add(CharMatcher.whitespace().trimTrailingFrom(it.next())); + if (tok.isSlashSlashComment()) { + lines.add(CharMatcher.whitespace().trimFrom(it.next())); + } else { + lines.add(CharMatcher.whitespace().trimTrailingFrom(it.next())); + } } if (tok.isSlashSlashComment()) { return indentLineComments(lines, column0); From 40ac75ff3da2ddca7563aedb9e8fe5f47189adbc Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 13 Sep 2024 10:39:49 -0700 Subject: [PATCH 303/379] Always run integration test for #1161 The intent was to only run the test on JDK 23+ and to disable it until the linked issue was fixed, but it actually resulted in the test being discovered and run on all JDK versions. That's fine, because the test is backwards compatible (`///` comments are valid in all versions, they just aren't markdown comments until 23). The test is being fixed in https://github.com/google/google-java-format/pull/1161 PiperOrigin-RevId: 674352956 --- .../google/googlejavaformat/java/FormatterIntegrationTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index d0817a2cf..3e4e175e6 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -72,8 +72,6 @@ public class FormatterIntegrationTest { "I981", "I1020", "I1037") - // TODO: https://github.com/google/google-java-format/issues/1153 - // .putAll(23, "I1153") .build(); @Parameters(name = "{index}: {0}") From 8c652edd6bde53be99fe1a83377bce4e281ec957 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 16 Sep 2024 10:41:39 -0700 Subject: [PATCH 304/379] Print the problem line as context in error messages PiperOrigin-RevId: 675207795 --- .../java/FormatterException.java | 21 ++++++++++++++++ .../google/googlejavaformat/java/Main.java | 9 ++----- .../googlejavaformat/java/MainTest.java | 25 +++++++++++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java index 808916c2c..0eb06461b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java +++ b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java @@ -16,10 +16,13 @@ import static java.util.Locale.ENGLISH; +import com.google.common.base.CharMatcher; +import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.googlejavaformat.FormatterDiagnostic; import java.util.List; +import java.util.regex.Pattern; import javax.tools.Diagnostic; import javax.tools.JavaFileObject; @@ -55,4 +58,22 @@ private static FormatterDiagnostic toFormatterDiagnostic(Diagnostic input) { return FormatterDiagnostic.create( (int) input.getLineNumber(), (int) input.getColumnNumber(), input.getMessage(ENGLISH)); } + + public String formatDiagnostics(String path, String input) { + List lines = Splitter.on(NEWLINE_PATTERN).splitToList(input); + StringBuilder sb = new StringBuilder(); + for (FormatterDiagnostic diagnostic : diagnostics()) { + sb.append(path).append(":").append(diagnostic).append(System.lineSeparator()); + int line = diagnostic.line(); + int column = diagnostic.column(); + if (line != -1 && column != -1) { + sb.append(CharMatcher.breakingWhitespace().trimTrailingFrom(lines.get(line - 1))) + .append(System.lineSeparator()); + sb.append(" ".repeat(column)).append('^').append(System.lineSeparator()); + } + } + return sb.toString(); + } + + private static final Pattern NEWLINE_PATTERN = Pattern.compile("\\R"); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index 0845e0ec2..f1affa74d 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -20,7 +20,6 @@ import com.google.common.io.ByteStreams; import com.google.common.util.concurrent.MoreExecutors; -import com.google.googlejavaformat.FormatterDiagnostic; import com.google.googlejavaformat.java.JavaFormatterOptions.Style; import java.io.IOError; import java.io.IOException; @@ -175,9 +174,7 @@ private int formatFiles(CommandLineOptions parameters, JavaFormatterOptions opti for (FormatFileCallable.Result result : results) { Path path = result.path(); if (result.exception() != null) { - for (FormatterDiagnostic diagnostic : result.exception().diagnostics()) { - errWriter.println(path + ":" + diagnostic); - } + errWriter.print(result.exception().formatDiagnostics(path.toString(), result.input())); allOk = false; continue; } @@ -224,9 +221,7 @@ private int formatStdin(CommandLineOptions parameters, JavaFormatterOptions opti FormatFileCallable.Result result = new FormatFileCallable(parameters, null, input, options).call(); if (result.exception() != null) { - for (FormatterDiagnostic diagnostic : result.exception().diagnostics()) { - errWriter.println(stdinFilename + ":" + diagnostic); - } + errWriter.print(result.exception().formatDiagnostics(stdinFilename, input)); ok = false; } else { String output = result.output(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index 42e12d860..d7de40510 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -635,4 +635,29 @@ public void reorderModifiersOptionTest() throws Exception { .formatSource(source)) .isEqualTo(source); } + + @Test + public void badIdentifier() throws Exception { + Path path = testFolder.newFile("Test.java").toPath(); + String[] input = { + "class Test {", // + " void f(int package) {}", + "}", + "", + }; + String source = joiner.join(input); + Files.writeString(path, source, UTF_8); + StringWriter out = new StringWriter(); + StringWriter err = new StringWriter(); + Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); + int errorCode = main.format(path.toAbsolutePath().toString()); + assertWithMessage("Error Code").that(errorCode).isEqualTo(1); + String[] expected = { + path + ":2:14: error: expected", // + " void f(int package) {}", + " ^", + "", + }; + assertThat(err.toString()).isEqualTo(joiner.join(expected)); + } } From c101ee96bd281c3d61e46d795a0fbecf19772694 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 2 Oct 2024 07:52:59 -0700 Subject: [PATCH 305/379] Fix column numbers in diagnostics Despite documentation to the contrary, the column numbers are already 1-indexed. The comment was added in unknown commit when g-j-f was still implemented using ecj instead of javac, so maybe it was true then? PiperOrigin-RevId: 681451766 --- .../googlejavaformat/FormatterDiagnostic.java | 6 +-- .../java/FormatterException.java | 2 +- .../googlejavaformat/java/DiagnosticTest.java | 14 +++--- .../googlejavaformat/java/MainTest.java | 44 ++++++++++++++++--- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/FormatterDiagnostic.java b/core/src/main/java/com/google/googlejavaformat/FormatterDiagnostic.java index be7f8a6ca..252da5bdf 100644 --- a/core/src/main/java/com/google/googlejavaformat/FormatterDiagnostic.java +++ b/core/src/main/java/com/google/googlejavaformat/FormatterDiagnostic.java @@ -49,7 +49,7 @@ public int line() { } /** - * Returns the 0-indexed column number on which the error occurred, or {@code -1} if the error + * Returns the 1-indexed column number on which the error occurred, or {@code -1} if the error * does not have a column. */ public int column() { @@ -61,14 +61,14 @@ public String message() { return message; } + @Override public String toString() { StringBuilder sb = new StringBuilder(); if (lineNumber >= 0) { sb.append(lineNumber).append(':'); } if (column >= 0) { - // internal column numbers are 0-based, but diagnostics use 1-based indexing by convention - sb.append(column + 1).append(':'); + sb.append(column).append(':'); } if (lineNumber >= 0 || column >= 0) { sb.append(' '); diff --git a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java index 0eb06461b..5ca939bbb 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java +++ b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java @@ -69,7 +69,7 @@ public String formatDiagnostics(String path, String input) { if (line != -1 && column != -1) { sb.append(CharMatcher.breakingWhitespace().trimTrailingFrom(lines.get(line - 1))) .append(System.lineSeparator()); - sb.append(" ".repeat(column)).append('^').append(System.lineSeparator()); + sb.append(" ".repeat(column - 1)).append('^').append(System.lineSeparator()); } } return sb.toString(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java b/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java index fc966fac3..e05a37264 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/DiagnosticTest.java @@ -79,7 +79,7 @@ public void parseError() throws Exception { int result = main.format(path.toString()); assertThat(stdout.toString()).isEmpty(); - assertThat(stderr.toString()).contains("InvalidSyntax.java:2:29: error: expected"); + assertThat(stderr.toString()).contains("InvalidSyntax.java:2:28: error: expected"); assertThat(result).isEqualTo(1); } @@ -119,7 +119,7 @@ public void oneFileParseError() throws Exception { int result = main.format(pathOne.toString(), pathTwo.toString()); assertThat(stdout.toString()).isEqualTo(two); - assertThat(stderr.toString()).contains("One.java:1:13: error: reached end of file"); + assertThat(stderr.toString()).contains("One.java:1:12: error: reached end of file"); assertThat(result).isEqualTo(1); } @@ -141,7 +141,7 @@ public void oneFileParseErrorReplace() throws Exception { int result = main.format("-i", pathOne.toString(), pathTwo.toString()); assertThat(stdout.toString()).isEmpty(); - assertThat(stderr.toString()).contains("One.java:1:14: error: class, interface"); + assertThat(stderr.toString()).contains("One.java:1:13: error: class, interface"); assertThat(result).isEqualTo(1); // don't edit files with parse errors assertThat(Files.readAllLines(pathOne, UTF_8)).containsExactly("class One {}}"); @@ -164,7 +164,7 @@ public void parseError2() throws FormatterException, IOException, UsageException int exitCode = main.format(args); assertThat(exitCode).isEqualTo(1); - assertThat(err.toString()).contains("A.java:2:6: error: ';' expected"); + assertThat(err.toString()).contains("A.java:2:5: error: ';' expected"); } @Test @@ -179,7 +179,7 @@ public void parseErrorStdin() throws FormatterException, IOException, UsageExcep int exitCode = main.format(args); assertThat(exitCode).isEqualTo(1); - assertThat(err.toString()).contains(":2:6: error: ';' expected"); + assertThat(err.toString()).contains(":2:5: error: ';' expected"); } @Test @@ -198,7 +198,7 @@ public void lexError2() throws FormatterException, IOException, UsageException { int exitCode = main.format(args); assertThat(exitCode).isEqualTo(1); - assertThat(err.toString()).contains("A.java:2:5: error: unclosed character literal"); + assertThat(err.toString()).contains("A.java:2:4: error: unclosed character literal"); } @Test @@ -212,6 +212,6 @@ public void lexErrorStdin() throws FormatterException, IOException, UsageExcepti int exitCode = main.format(args); assertThat(exitCode).isEqualTo(1); - assertThat(err.toString()).contains(":2:5: error: unclosed character literal"); + assertThat(err.toString()).contains(":2:4: error: unclosed character literal"); } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java index d7de40510..2d9364082 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/MainTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/MainTest.java @@ -307,7 +307,7 @@ public void importRemoveErrorParseError() throws Exception { new PrintWriter(err, true), new ByteArrayInputStream(joiner.join(input).getBytes(UTF_8))); assertThat(main.format("-")).isEqualTo(1); - assertThat(err.toString()).contains(":4:3: error: class, interface"); + assertThat(err.toString()).contains(":4:2: error: class, interface"); } finally { Locale.setDefault(backupLocale); @@ -508,7 +508,7 @@ public void assumeFilename_error() throws Exception { new PrintWriter(err, true), new ByteArrayInputStream(joiner.join(input).getBytes(UTF_8))); assertThat(main.format("--assume-filename=Foo.java", "-")).isEqualTo(1); - assertThat(err.toString()).contains("Foo.java:1:15: error: class, interface"); + assertThat(err.toString()).contains("Foo.java:1:14: error: class, interface"); } @Test @@ -637,11 +637,13 @@ public void reorderModifiersOptionTest() throws Exception { } @Test - public void badIdentifier() throws Exception { + public void syntaxError() throws Exception { Path path = testFolder.newFile("Test.java").toPath(); String[] input = { "class Test {", // - " void f(int package) {}", + " void f(int package) {", + " int", + " }", "}", "", }; @@ -653,9 +655,37 @@ public void badIdentifier() throws Exception { int errorCode = main.format(path.toAbsolutePath().toString()); assertWithMessage("Error Code").that(errorCode).isEqualTo(1); String[] expected = { - path + ":2:14: error: expected", // - " void f(int package) {}", - " ^", + path + ":2:13: error: expected", + " void f(int package) {", + " ^", + path + ":3:5: error: not a statement", + " int", + " ^", + path + ":3:8: error: ';' expected", + " int", + " ^", + "", + }; + assertThat(err.toString()).isEqualTo(joiner.join(expected)); + } + + @Test + public void syntaxErrorBeginning() throws Exception { + Path path = testFolder.newFile("Test.java").toPath(); + String[] input = { + "error", // + }; + String source = joiner.join(input); + Files.writeString(path, source, UTF_8); + StringWriter out = new StringWriter(); + StringWriter err = new StringWriter(); + Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); + int errorCode = main.format(path.toAbsolutePath().toString()); + assertWithMessage("Error Code").that(errorCode).isEqualTo(1); + String[] expected = { + path + ":1:1: error: reached end of file while parsing", // + "error", + "^", "", }; assertThat(err.toString()).isEqualTo(joiner.join(expected)); From 4340416bbee832e690d9384c00895b677d6f1b2b Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Fri, 4 Oct 2024 11:21:12 -0700 Subject: [PATCH 306/379] Update the IntelliJ plugin to 1.24.0. PiperOrigin-RevId: 682389166 --- idea_plugin/build.gradle.kts | 4 ++-- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index c7d1d4ba1..d5eb59931 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -17,7 +17,7 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases plugins { - id("org.jetbrains.intellij.platform") version "2.0.1" + id("org.jetbrains.intellij.platform") version "2.1.0" } repositories { @@ -29,7 +29,7 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.23.0" +val googleJavaFormatVersion = "1.24.0" java { sourceCompatibility = JavaVersion.VERSION_17 diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 8d7574539..c09257baa 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
1.24.0.0
+
Updated to use google-java-format 1.24.0.
1.23.0.0
Updated to use google-java-format 1.23.0.
Fix crashes in IntelliJ 2024.2 (Thanks, @nrayburn-tech!)
From 6c436705fa75e7c8c16a94140222af4f44f3707e Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 4 Oct 2024 16:41:39 -0700 Subject: [PATCH 307/379] Remove JDK 11 from CI also use 21 for snapshot builds, see https://github.com/google/google-java-format/pull/1015 --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c623efe38..e64353d64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - java: [21, 17, 11] + java: [21, 17] experimental: [false] include: # Only test on MacOS and Windows with a single recent JDK to avoid a @@ -114,10 +114,10 @@ jobs: steps: - name: "Check out repository" uses: actions/checkout@v4 - - name: "Set up JDK 17" + - name: "Set up JDK 21" uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 distribution: "zulu" cache: "maven" server-id: sonatype-nexus-snapshots From a3737d91d9446acd4c56fb46e178423d3cf9b66a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 4 Oct 2024 17:46:43 -0700 Subject: [PATCH 308/379] Update google-java-format to build with Java 17 https://github.com/google/google-java-format/issues/1159 PiperOrigin-RevId: 682509011 --- core/pom.xml | 33 +++------------------------------ 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index c3753a150..5b6bbb4d7 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -93,7 +93,7 @@ maven-javadoc-plugin - 11 + 17 UTF-8 UTF-8 UTF-8 @@ -215,41 +215,14 @@ org.apache.maven.plugins maven-compiler-plugin - 11 - 11 + 17 + 17 - - jdk11 - - [11,17) - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - **/Java17InputAstVisitor.java - **/Java21InputAstVisitor.java - - - - - maven-javadoc-plugin - - com.google.googlejavaformat.java.java17 - com.google.googlejavaformat.java.java21 - - - - - jdk17 From 098431221007a0fce1b0d213ded10948087332a4 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 4 Oct 2024 18:07:08 -0700 Subject: [PATCH 309/379] Update Error Prone version to 2.32.0 Startblock: * unknown commit is submitted PiperOrigin-RevId: 682513849 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 96e613a0a..ebea1ed3e 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 32.1.3-jre 1.4.0 1.0.0 - 2.28.0 + 2.32.0 1.9 1.0.1 3.6.3 From 6586afee9abcb42f79b64314074f299f036099bd Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 18 Oct 2024 17:47:58 -0700 Subject: [PATCH 310/379] Update Error Prone version to 2.34.0 And pass `--should-stop=ifError=FLOW`, see https://github.com/google/error-prone/releases/tag/v2.34.0 PiperOrigin-RevId: 687476556 --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ebea1ed3e..c31340223 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 32.1.3-jre 1.4.0 1.0.0 - 2.32.0 + 2.34.0 1.9 1.0.1 3.6.3 @@ -196,6 +196,7 @@ -XDcompilePolicy=simple + --should-stop=ifError=FLOW -Xplugin:ErrorProne --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED From 00cce7b893508e986d91c8f00947948bdaefc76a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 28 Oct 2024 08:19:16 -0700 Subject: [PATCH 311/379] Place the trailing `"""` of a text block to appear on its own line PiperOrigin-RevId: 690618067 --- .../googlejavaformat/java/StringWrapper.java | 20 +++++++++++++------ .../java/StringWrapperTest.java | 3 ++- .../java/testdata/RSLs.output | 3 ++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 6814054a2..c0b4dc1db 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -65,6 +65,9 @@ /** Wraps string literals that exceed the column limit. */ public final class StringWrapper { + + public static final String TEXT_BLOCK_DELIMITER = "\"\"\""; + /** Reflows long string literals in the given Java source code. */ public static String wrap(String input, Formatter formatter) throws FormatterException { return StringWrapper.wrap(Formatter.MAX_LINE_LENGTH, input, formatter); @@ -162,7 +165,7 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) { return null; } int pos = getStartPosition(literalTree); - if (input.substring(pos, min(input.length(), pos + 3)).equals("\"\"\"")) { + if (input.substring(pos, min(input.length(), pos + 3)).equals(TEXT_BLOCK_DELIMITER)) { textBlocks.add(literalTree); return null; } @@ -206,7 +209,7 @@ private void indentTextBlocks( ? "" : " ".repeat(startColumn - 1); - StringBuilder output = new StringBuilder("\"\"\""); + StringBuilder output = new StringBuilder(TEXT_BLOCK_DELIMITER); for (int i = 0; i < lines.size(); i++) { String line = lines.get(i); String trimmed = line.stripLeading().stripTrailing(); @@ -215,11 +218,16 @@ private void indentTextBlocks( // Don't add incidental leading whitespace to empty lines output.append(prefix); } - if (i == lines.size() - 1 && trimmed.equals("\"\"\"")) { - // If the trailing line is just """, indenting is more than the prefix of incidental + if (i == lines.size() - 1) { + String withoutDelimiter = + trimmed.substring(0, trimmed.length() - TEXT_BLOCK_DELIMITER.length()); + if (!withoutDelimiter.isEmpty()) { + output.append(withoutDelimiter).append('\\').append(separator).append(prefix); + } + // If the trailing line is just """, indenting it more than the prefix of incidental // whitespace has no effect, and results in a javac text-blocks warning that 'trailing // white space will be removed'. - output.append("\"\"\""); + output.append(TEXT_BLOCK_DELIMITER); } else { output.append(line); } @@ -482,7 +490,7 @@ private static boolean needWrapping(int columnLimit, String input) { Iterator it = Newlines.lineIterator(input); while (it.hasNext()) { String line = it.next(); - if (line.length() > columnLimit || line.contains("\"\"\"")) { + if (line.length() > columnLimit || line.contains(TEXT_BLOCK_DELIMITER)) { return true; } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java index fd176ed4e..7854126c4 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -65,7 +65,8 @@ public void textBlock() throws Exception { " String str =", " \"\"\"", "{\"sourceEndpoint\":\"ri.something.1-1.object-internal.1\",\"targetEndpoint" - + "\":\"ri.something.1-1.object-internal.2\",\"typeId\":\"typeId\"}\"\"\";", + + "\":\"ri.something.1-1.object-internal.2\",\"typeId\":\"typeId\"}\\", + "\"\"\";", " myString = str;", " }", "}"); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output index 5ca1fb8cc..5f59bc5ea 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output @@ -23,7 +23,8 @@ class RSLs { """; String f = """ - ipsum"""; + ipsum\ + """; String g = """ lorem\ From 666fe33f770d07b1e79b2b6dd468735cead652a1 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 8 Nov 2024 07:59:30 -0800 Subject: [PATCH 312/379] Add an integration test for comments before text blocks PiperOrigin-RevId: 694499404 --- .../googlejavaformat/java/testdata/B377585941.input | 8 ++++++++ .../googlejavaformat/java/testdata/B377585941.output | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.input new file mode 100644 index 000000000..bd3107be4 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.input @@ -0,0 +1,8 @@ +class T { + { + f( + /* foo */ """ + hello + """); + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output new file mode 100644 index 000000000..1dfc49503 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output @@ -0,0 +1,8 @@ +class T { + { + f( + /* foo */ """ + hello + """); + } +} From 98c6bbd0534620901cf8d13cf0c843a4c888e947 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 8 Nov 2024 09:38:27 -0800 Subject: [PATCH 313/379] If a text block is outdented, outdent the opening `"""` too PiperOrigin-RevId: 694533649 --- .../googlejavaformat/java/JavaInputAstVisitor.java | 10 ++++++++++ .../google/googlejavaformat/java/StringWrapper.java | 6 +++--- .../googlejavaformat/java/StringWrapperTest.java | 2 +- .../googlejavaformat/java/testdata/B377585941.output | 4 ++-- .../google/googlejavaformat/java/testdata/RSLs.input | 7 +++++++ .../google/googlejavaformat/java/testdata/RSLs.output | 11 +++++++++-- 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 01f9a3e05..af9810114 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -70,6 +70,7 @@ import com.google.googlejavaformat.FormattingError; import com.google.googlejavaformat.Indent; import com.google.googlejavaformat.Input; +import com.google.googlejavaformat.Newlines; import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpenOp; import com.google.googlejavaformat.OpsBuilder; @@ -1667,6 +1668,15 @@ public Void visitMemberSelect(MemberSelectTree node, Void unused) { public Void visitLiteral(LiteralTree node, Void unused) { sync(node); String sourceForNode = getSourceForNode(node, getCurrentPath()); + if (sourceForNode.endsWith("\"\"\"") + && (Newlines.hasNewlineAt(sourceForNode, sourceForNode.length() - 4) != -1)) { + // If the closing delimiter of a text block starts at the margin, outdent the opening + // delimiter as well by adding a break with negative indentation. Outdenting for text blocks + // with wide contents is also handled by StringWrapper, but this means the behaviour for + // the opening delimiter is consistent if string wrapping is disabled, and also effectively + // preserves user choice about which text blocks stay de-indented. + builder.breakOp(Indent.Const.make(Integer.MIN_VALUE / indentMultiplier, indentMultiplier)); + } if (isUnaryMinusLiteral(sourceForNode)) { token("-"); sourceForNode = sourceForNode.substring(1).trim(); diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index c0b4dc1db..81ea800da 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -190,9 +190,10 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) { private void indentTextBlocks( TreeRangeMap replacements, List textBlocks) { for (Tree tree : textBlocks) { - int startPosition = getStartPosition(tree); + int startPosition = lineMap.getStartPosition(lineMap.getLineNumber(getStartPosition(tree))); int endPosition = getEndPosition(unit, tree); String text = input.substring(startPosition, endPosition); + int startColumn = CharMatcher.whitespace().negate().indexIn(text) + 1; // Find the source code of the text block with incidental whitespace removed. // The first line of the text block is always """, and it does not affect incidental @@ -203,13 +204,12 @@ private void indentTextBlocks( int deindent = initialLines.get(1).stripTrailing().length() - lines.get(0).stripTrailing().length(); - int startColumn = lineMap.getColumnNumber(startPosition); String prefix = (deindent == 0 || lines.stream().anyMatch(x -> x.length() + startColumn > columnLimit)) ? "" : " ".repeat(startColumn - 1); - StringBuilder output = new StringBuilder(TEXT_BLOCK_DELIMITER); + StringBuilder output = new StringBuilder(prefix).append(initialLines.get(0).stripLeading()); for (int i = 0; i < lines.size(); i++) { String line = lines.get(i); String trimmed = line.stripLeading().stripTrailing(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java index 7854126c4..bc1a93384 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -63,7 +63,7 @@ public void textBlock() throws Exception { " private String myString;", " private ReproBug() {", " String str =", - " \"\"\"", + "\"\"\"", "{\"sourceEndpoint\":\"ri.something.1-1.object-internal.1\",\"targetEndpoint" + "\":\"ri.something.1-1.object-internal.2\",\"typeId\":\"typeId\"}\\", "\"\"\";", diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output index 1dfc49503..bd3107be4 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output @@ -2,7 +2,7 @@ class T { { f( /* foo */ """ - hello - """); + hello + """); } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input index 22aa8f2b2..e557ea2ce 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input @@ -50,5 +50,12 @@ ipsum hello %s """ .formatted("world"); + f( + /* foo= */ """ + foo + """, + /* bar= */ """ + bar + """); } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output index 5f59bc5ea..7d291b15c 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output @@ -42,13 +42,13 @@ class RSLs { ipsum """; String j = - """ +""" lorem one long incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt ipsum """; String k = - """ +""" lorem ipsum """; @@ -65,5 +65,12 @@ ipsum hello %s """ .formatted("world"); + f( + /* foo= */ """ + foo + """, + /* bar= */ """ + bar + """); } } From 81e9e1c0293494a80dd15681f2500af73d640db7 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 8 Nov 2024 10:20:30 -0800 Subject: [PATCH 314/379] Always break between leading comments and opening delimiters of text blocks PiperOrigin-RevId: 694550141 --- core/src/main/java/com/google/googlejavaformat/Input.java | 5 +++++ .../main/java/com/google/googlejavaformat/OpsBuilder.java | 2 +- .../java/com/google/googlejavaformat/java/JavaInput.java | 5 +++++ .../google/googlejavaformat/java/testdata/B377585941.output | 3 ++- .../com/google/googlejavaformat/java/testdata/RSLs.output | 6 ++++-- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Input.java b/core/src/main/java/com/google/googlejavaformat/Input.java index 66a392190..d059111d9 100644 --- a/core/src/main/java/com/google/googlejavaformat/Input.java +++ b/core/src/main/java/com/google/googlejavaformat/Input.java @@ -71,6 +71,11 @@ public interface Tok { /** Is the {@code Tok} a comment? */ boolean isComment(); + + /** Is the {@code Tok} a text block? */ + default boolean isTextBlock() { + return false; + } } /** A {@code Token} is a language-level token. */ diff --git a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java index a45e83b9e..008be11f3 100644 --- a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java +++ b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java @@ -534,7 +534,7 @@ public final ImmutableList build() { space = tokBefore.isSlashStarComment(); newlines = 0; lastWasComment = true; - if (tokBefore.isJavadocComment()) { + if (tokBefore.isJavadocComment() || token.getTok().isTextBlock()) { tokOps.put(j, Doc.Break.makeForced()); } allowBlankAfterLastComment = diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 01c617776..6be39ab42 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -166,6 +166,11 @@ public boolean isComment() { return isSlashSlashComment() || isSlashStarComment(); } + @Override + public boolean isTextBlock() { + return originalText.startsWith("\"\"\""); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output index bd3107be4..7f57dfbef 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output @@ -1,7 +1,8 @@ class T { { f( - /* foo */ """ + /* foo */ + """ hello """); } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output index 7d291b15c..cfe77c934 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output @@ -66,10 +66,12 @@ ipsum """ .formatted("world"); f( - /* foo= */ """ + /* foo= */ + """ foo """, - /* bar= */ """ + /* bar= */ + """ bar """); } From d4b3f0dd7dafcb863141570f2ac4cb2a9cee0a7b Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 11 Nov 2024 08:22:56 -0800 Subject: [PATCH 315/379] Fix an off-by-one bug with column limit handling for text blocks PiperOrigin-RevId: 695348215 --- .../googlejavaformat/java/StringWrapper.java | 3 ++- .../java/testdata/B361077825.input | 15 +++++++++++++++ .../java/testdata/B361077825.output | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 81ea800da..ab4093a11 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -205,7 +205,8 @@ private void indentTextBlocks( initialLines.get(1).stripTrailing().length() - lines.get(0).stripTrailing().length(); String prefix = - (deindent == 0 || lines.stream().anyMatch(x -> x.length() + startColumn > columnLimit)) + (deindent == 0 + || lines.stream().anyMatch(x -> x.length() + startColumn - 1 > columnLimit)) ? "" : " ".repeat(startColumn - 1); diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.input new file mode 100644 index 000000000..c93942a5d --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.input @@ -0,0 +1,15 @@ +class T { + String a = + """ + # No implicit input file, because they can only be created outside a symbolic macro, + """; + + String b = + """ + # No implicit input file, because they can only be created outside a symbolic macro, + """; + String c = + """ + # No implicit input file, because they can only be created outside a symbolic macro, + """; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output new file mode 100644 index 000000000..b407bfe26 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output @@ -0,0 +1,15 @@ +class T { + String a = + """ + # No implicit input file, because they can only be created outside a symbolic macro, + """; + + String b = + """ + # No implicit input file, because they can only be created outside a symbolic macro, + """; + String c = +""" + # No implicit input file, because they can only be created outside a symbolic macro, +"""; +} From fc31690af3b057b0f9eeb3d78d8687c0831e0a1b Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 11 Nov 2024 08:46:09 -0800 Subject: [PATCH 316/379] More text block test cases PiperOrigin-RevId: 695356983 --- .../googlejavaformat/java/testdata/RSLs.input | 27 +++++++++++++++++ .../java/testdata/RSLs.output | 29 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input index e557ea2ce..6eaa28558 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input @@ -57,5 +57,32 @@ ipsum /* bar= */ """ bar """); + """ + hello + """.codePoints().forEach(System.err::println); + String s = + """ + foo + """ + + """ + bar + """; + String t = + """ +foo +""" + + """ +bar +"""; + String u = + stringVariableOne + + + """ + ... + """ + stringVariableTwo + + + """ + ... + """; } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output index cfe77c934..9993f5aa2 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output @@ -74,5 +74,34 @@ ipsum """ bar """); + """ + hello + """ + .codePoints() + .forEach(System.err::println); + String s = + """ + foo + """ + + """ + bar + """; + String t = +""" +foo +""" + + +""" +bar +"""; + String u = + stringVariableOne + + """ + ... + """ + + stringVariableTwo + + """ + ... + """; } } From 02b6ad1537afb8b6f59c49ce822394a258b2b810 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 11 Nov 2024 09:03:49 -0800 Subject: [PATCH 317/379] Back out text block special cases PiperOrigin-RevId: 695363436 --- .../java/com/google/googlejavaformat/Input.java | 5 ----- .../com/google/googlejavaformat/OpsBuilder.java | 2 +- .../google/googlejavaformat/java/JavaInput.java | 5 ----- .../java/JavaInputAstVisitor.java | 10 ---------- .../googlejavaformat/java/StringWrapper.java | 11 ++++++++--- .../googlejavaformat/java/StringWrapperTest.java | 2 +- .../java/testdata/B361077825.output | 2 +- .../java/testdata/B377585941.output | 3 +-- .../googlejavaformat/java/testdata/RSLs.output | 15 ++++++--------- 9 files changed, 18 insertions(+), 37 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Input.java b/core/src/main/java/com/google/googlejavaformat/Input.java index d059111d9..66a392190 100644 --- a/core/src/main/java/com/google/googlejavaformat/Input.java +++ b/core/src/main/java/com/google/googlejavaformat/Input.java @@ -71,11 +71,6 @@ public interface Tok { /** Is the {@code Tok} a comment? */ boolean isComment(); - - /** Is the {@code Tok} a text block? */ - default boolean isTextBlock() { - return false; - } } /** A {@code Token} is a language-level token. */ diff --git a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java index 008be11f3..a45e83b9e 100644 --- a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java +++ b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java @@ -534,7 +534,7 @@ public final ImmutableList build() { space = tokBefore.isSlashStarComment(); newlines = 0; lastWasComment = true; - if (tokBefore.isJavadocComment() || token.getTok().isTextBlock()) { + if (tokBefore.isJavadocComment()) { tokOps.put(j, Doc.Break.makeForced()); } allowBlankAfterLastComment = diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 6be39ab42..01c617776 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -166,11 +166,6 @@ public boolean isComment() { return isSlashSlashComment() || isSlashStarComment(); } - @Override - public boolean isTextBlock() { - return originalText.startsWith("\"\"\""); - } - @Override public String toString() { return MoreObjects.toStringHelper(this) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index af9810114..01f9a3e05 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -70,7 +70,6 @@ import com.google.googlejavaformat.FormattingError; import com.google.googlejavaformat.Indent; import com.google.googlejavaformat.Input; -import com.google.googlejavaformat.Newlines; import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpenOp; import com.google.googlejavaformat.OpsBuilder; @@ -1668,15 +1667,6 @@ public Void visitMemberSelect(MemberSelectTree node, Void unused) { public Void visitLiteral(LiteralTree node, Void unused) { sync(node); String sourceForNode = getSourceForNode(node, getCurrentPath()); - if (sourceForNode.endsWith("\"\"\"") - && (Newlines.hasNewlineAt(sourceForNode, sourceForNode.length() - 4) != -1)) { - // If the closing delimiter of a text block starts at the margin, outdent the opening - // delimiter as well by adding a break with negative indentation. Outdenting for text blocks - // with wide contents is also handled by StringWrapper, but this means the behaviour for - // the opening delimiter is consistent if string wrapping is disabled, and also effectively - // preserves user choice about which text blocks stay de-indented. - builder.breakOp(Indent.Const.make(Integer.MIN_VALUE / indentMultiplier, indentMultiplier)); - } if (isUnaryMinusLiteral(sourceForNode)) { token("-"); sourceForNode = sourceForNode.substring(1).trim(); diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index ab4093a11..42099d6b8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -190,10 +190,15 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) { private void indentTextBlocks( TreeRangeMap replacements, List textBlocks) { for (Tree tree : textBlocks) { - int startPosition = lineMap.getStartPosition(lineMap.getLineNumber(getStartPosition(tree))); + int startPosition = getStartPosition(tree); int endPosition = getEndPosition(unit, tree); String text = input.substring(startPosition, endPosition); - int startColumn = CharMatcher.whitespace().negate().indexIn(text) + 1; + int lineStartPosition = lineMap.getStartPosition(lineMap.getLineNumber(startPosition)); + int startColumn = + CharMatcher.whitespace() + .negate() + .indexIn(input.substring(lineStartPosition, endPosition)) + + 1; // Find the source code of the text block with incidental whitespace removed. // The first line of the text block is always """, and it does not affect incidental @@ -210,7 +215,7 @@ private void indentTextBlocks( ? "" : " ".repeat(startColumn - 1); - StringBuilder output = new StringBuilder(prefix).append(initialLines.get(0).stripLeading()); + StringBuilder output = new StringBuilder(initialLines.get(0).stripLeading()); for (int i = 0; i < lines.size(); i++) { String line = lines.get(i); String trimmed = line.stripLeading().stripTrailing(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java index bc1a93384..7854126c4 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -63,7 +63,7 @@ public void textBlock() throws Exception { " private String myString;", " private ReproBug() {", " String str =", - "\"\"\"", + " \"\"\"", "{\"sourceEndpoint\":\"ri.something.1-1.object-internal.1\",\"targetEndpoint" + "\":\"ri.something.1-1.object-internal.2\",\"typeId\":\"typeId\"}\\", "\"\"\";", diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output index b407bfe26..62344bd54 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output @@ -9,7 +9,7 @@ class T { # No implicit input file, because they can only be created outside a symbolic macro, """; String c = -""" + """ # No implicit input file, because they can only be created outside a symbolic macro, """; } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output index 7f57dfbef..bd3107be4 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B377585941.output @@ -1,8 +1,7 @@ class T { { f( - /* foo */ - """ + /* foo */ """ hello """); } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output index 9993f5aa2..6e9a3ae5b 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output @@ -42,13 +42,13 @@ class RSLs { ipsum """; String j = -""" + """ lorem one long incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt ipsum """; String k = -""" + """ lorem ipsum """; @@ -66,12 +66,10 @@ ipsum """ .formatted("world"); f( - /* foo= */ - """ + /* foo= */ """ foo """, - /* bar= */ - """ + /* bar= */ """ bar """); """ @@ -87,11 +85,10 @@ ipsum bar """; String t = -""" + """ foo """ - + -""" + + """ bar """; String u = From beacc083963eb2da09349cf5db9238085fad40bf Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 11 Nov 2024 09:58:30 -0800 Subject: [PATCH 318/379] Explicitly test that reformatting after formatting and string wrapping is idempotent There's some indirect coverage of this from line ending tests, but they don't exercise string wrapping. PiperOrigin-RevId: 695382884 --- .../java/FormatterIntegrationTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 3e4e175e6..ef6bef087 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -144,6 +144,19 @@ public void format() { } } + @Test + public void idempotent() { + try { + Formatter formatter = new Formatter(); + String formatted = formatter.formatSource(input); + formatted = StringWrapper.wrap(formatted, formatter); + String reformatted = formatter.formatSource(formatted); + assertEquals("bad output for " + name, formatted, reformatted); + } catch (FormatterException e) { + fail(String.format("Formatter crashed on %s: %s", name, e.getMessage())); + } + } + @Test public void idempotentLF() { try { From e35f60eaf3eae8661e1e3251a573a194cf861ada Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 11 Nov 2024 12:56:43 -0800 Subject: [PATCH 319/379] Reformat the formatter To avoid spurious diffs during other development. PiperOrigin-RevId: 695452895 --- .../java/com/google/googlejavaformat/Newlines.java | 2 +- .../java/com/google/googlejavaformat/OpsBuilder.java | 10 +++++----- .../googlejavaformat/java/JavaCommentsHelper.java | 1 - .../com/google/googlejavaformat/java/JavaOutput.java | 2 +- .../googlejavaformat/java/filer/FormattingFiler.java | 4 +++- .../googlejavaformat/java/javadoc/JavadocWriter.java | 1 + .../googlejavaformat/java/CommandLineFlagsTest.java | 4 +--- .../googlejavaformat/java/JavadocFormattingTest.java | 4 ++-- .../googlejavaformat/java/GoogleJavaFormatter.java | 4 +++- .../intellij/GoogleJavaFormatConfigurable.java | 4 +++- 10 files changed, 20 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Newlines.java b/core/src/main/java/com/google/googlejavaformat/Newlines.java index dbb82d3c5..86335981b 100644 --- a/core/src/main/java/com/google/googlejavaformat/Newlines.java +++ b/core/src/main/java/com/google/googlejavaformat/Newlines.java @@ -135,7 +135,7 @@ private void advance() { if (idx + 1 < input.length() && input.charAt(idx + 1) == '\n') { idx++; } - // falls through + // falls through case '\n': idx++; curr = idx; diff --git a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java index a45e83b9e..7f0fabb34 100644 --- a/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java +++ b/core/src/main/java/com/google/googlejavaformat/OpsBuilder.java @@ -38,7 +38,7 @@ */ public final class OpsBuilder { - /** @return the actual size of the AST node at position, including comments. */ + /** Returns the actual size of the AST node at position, including comments. */ public int actualSize(int position, int length) { Token startToken = input.getPositionTokenMap().get(position); int start = startToken.getTok().getPosition(); @@ -57,7 +57,7 @@ public int actualSize(int position, int length) { return end - start; } - /** @return the start column of the token at {@code position}, including leading comments. */ + /** Returns the start column of the token at {@code position}, including leading comments. */ public Integer actualStartColumn(int position) { Token startToken = input.getPositionTokenMap().get(position); int start = startToken.getTok().getPosition(); @@ -316,7 +316,7 @@ public final void guessToken(String token) { token, Doc.Token.RealOrImaginary.IMAGINARY, ZERO, - /* breakAndIndentTrailingComment= */ Optional.empty()); + /* breakAndIndentTrailingComment= */ Optional.empty()); } public final void token( @@ -359,7 +359,7 @@ public final void op(String op) { op.substring(i, i + 1), Doc.Token.RealOrImaginary.REAL, ZERO, - /* breakAndIndentTrailingComment= */ Optional.empty()); + /* breakAndIndentTrailingComment= */ Optional.empty()); } } @@ -427,7 +427,7 @@ public final void breakToFill(String flat) { * @param plusIndent extra indent if taken */ public final void breakOp(Doc.FillMode fillMode, String flat, Indent plusIndent) { - breakOp(fillMode, flat, plusIndent, /* optionalTag= */ Optional.empty()); + breakOp(fillMode, flat, plusIndent, /* optionalTag= */ Optional.empty()); } /** diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java b/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java index d54b2317e..9526b892c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaCommentsHelper.java @@ -185,4 +185,3 @@ private static boolean javadocShaped(List lines) { return true; } } - diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java index 656b65c83..ea3731131 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaOutput.java @@ -140,7 +140,7 @@ public void append(String text, Range range) { if (i + 1 < text.length() && text.charAt(i + 1) == '\n') { i++; } - // falls through + // falls through case '\n': spacesPending = new StringBuilder(); ++newlinesPending; diff --git a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java index ebdc8dfec..2f2e33cbe 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java +++ b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java @@ -37,7 +37,9 @@ public final class FormattingFiler implements Filer { private final Formatter formatter = new Formatter(); private final Messager messager; - /** @param delegate filer to decorate */ + /** + * @param delegate filer to decorate + */ public FormattingFiler(Filer delegate) { this(delegate, null); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java index 8a4100e45..5e6af1795 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocWriter.java @@ -40,6 +40,7 @@ final class JavadocWriter { private final int blockIndent; private final StringBuilder output = new StringBuilder(); + /** * Whether we are inside an {@code
  • } element, excluding the case in which the {@code
  • } * contains a {@code
      } or {@code
        } that we are also inside -- unless of course we're diff --git a/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java b/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java index e5fbc9f5f..928ce0078 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java @@ -21,9 +21,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Tests for command-line flags. - */ +/** Tests for command-line flags. */ @RunWith(JUnit4.class) public class CommandLineFlagsTest { diff --git a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java index aab8ec5d4..39d43c2f9 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/JavadocFormattingTest.java @@ -1084,7 +1084,7 @@ public void paragraphTag() { @Test public void xhtmlParagraphTag() { String[] input = { - "class Test {", + "class Test {", // " /**", " * hello

        world", " */", @@ -1093,7 +1093,7 @@ public void xhtmlParagraphTag() { "}", }; String[] expected = { - "class Test {", + "class Test {", // " /**", " * hello", " *", diff --git a/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java b/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java index c300514be..68ff908c5 100644 --- a/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java +++ b/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java @@ -106,7 +106,9 @@ private List> rangesFromRegions(IRegion[] regions) { return ranges; } - /** @return {@code true} if input and output texts are equal, else {@code false}. */ + /** + * @return {@code true} if input and output texts are equal, else {@code false}. + */ private boolean idempotent(String source, IRegion[] regions, List replacements) { // This implementation only checks for single replacement. if (replacements.size() == 1) { diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java index 759decc0f..3a98c2eb9 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/GoogleJavaFormatConfigurable.java @@ -199,7 +199,9 @@ private void createUIComponents() { false)); } - /** @noinspection ALL */ + /** + * @noinspection ALL + */ public JComponent $$$getRootComponent$$$() { return panel; } From 453ad0853c766d2ea74f95341948b875570195c9 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 12 Nov 2024 16:30:43 -0800 Subject: [PATCH 320/379] Add some more test cases for pattern guards PiperOrigin-RevId: 695910986 --- .../java/testdata/SwitchGuardClause.input | 48 ++++++++++++++++++ .../java/testdata/SwitchGuardClause.output | 50 +++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input index 25df58096..36eb21b16 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input @@ -6,4 +6,52 @@ class SwitchGuardClause { default -> true; }; } + + { + switch (o) { + case TypeWithVeryVeryVeryVeryLongName variableWithVeryLongName when variableWithVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + System.err.println(); + } + default -> {} + } + switch (o) { + case TypeWithVeryVeryVeryVeryLongName + variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + System.err.println(); + } + default -> {} + } + switch (o) { + case TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + System.err.println(); + } + default -> {} + } + switch (o) { + case TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName, + TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + System.err.println(); + } + default -> {} + } + switch (o) { + case TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName, + TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> + System.err.println(); + default -> {} + } + } } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output index 25df58096..1a81422c4 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output @@ -6,4 +6,54 @@ class SwitchGuardClause { default -> true; }; } + + { + switch (o) { + case TypeWithVeryVeryVeryVeryLongName variableWithVeryLongName when variableWithVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + System.err.println(); + } + default -> {} + } + switch (o) { + case TypeWithVeryVeryVeryVeryLongName + variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + System.err.println(); + } + default -> {} + } + switch (o) { + case TypeWithVeryVeryVeryVeryLongName + variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + System.err.println(); + } + default -> {} + } + switch (o) { + case TypeWithVeryVeryVeryVeryLongName + variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName, + TypeWithVeryVeryVeryVeryLongName + variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + System.err.println(); + } + default -> {} + } + switch (o) { + case TypeWithVeryVeryVeryVeryLongName + variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName, + TypeWithVeryVeryVeryVeryLongName + variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> + System.err.println(); + default -> {} + } + } } From 7e5fb80fec99ddb523f74a39bfbf40e4bd277210 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 13 Nov 2024 10:50:01 -0800 Subject: [PATCH 321/379] Allow breaks before pattern guards Previously there were never breaks before `when` pattern guards, which produced surprising results. There's possible future work here around evaluating how many level of continuation indents to take to differentiate between syntactic levels, but I think this is an improvement on the status quo. PiperOrigin-RevId: 696193971 --- .../java/java17/Java17InputAstVisitor.java | 16 ++---- .../java/testdata/SwitchGuardClause.input | 40 +++++++++---- .../java/testdata/SwitchGuardClause.output | 56 ++++++++++++------- 3 files changed, 70 insertions(+), 42 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java index a0037edb7..315523585 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java @@ -82,7 +82,6 @@ public Void visitBindingPattern(BindingPatternTree node, Void unused) { } private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) { - builder.open(plusFour); declareOne( DeclarationKind.PARAMETER, Direction.HORIZONTAL, @@ -95,7 +94,6 @@ private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) /* trailing= */ Optional.empty(), /* receiverExpression= */ Optional.empty(), /* typeWithDims= */ Optional.empty()); - builder.close(); } @Override @@ -227,16 +225,12 @@ public Void visitCase(CaseTree node, Void unused) { List labels = node.getLabels(); boolean isDefault = labels.size() == 1 && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL"); - builder.open( - node.getCaseKind().equals(CaseTree.CaseKind.RULE) - && !node.getBody().getKind().equals(Tree.Kind.BLOCK) - ? plusFour - : ZERO); + builder.open(node.getCaseKind().equals(CaseTree.CaseKind.RULE) ? plusFour : ZERO); if (isDefault) { token("default", ZERO); } else { token("case", ZERO); - builder.open(labels.size() > 1 ? plusFour : ZERO); + builder.open(ZERO); builder.space(); boolean afterFirstToken = false; for (Tree expression : labels) { @@ -252,7 +246,7 @@ public Void visitCase(CaseTree node, Void unused) { final ExpressionTree guard = getGuard(node); if (guard != null) { - builder.space(); + builder.breakToFill(" "); token("when"); builder.space(); scan(guard, null); @@ -264,12 +258,14 @@ public Void visitCase(CaseTree node, Void unused) { builder.open(plusTwo); visitStatements(node.getStatements()); builder.close(); + builder.close(); break; case RULE: builder.space(); token("-"); token(">"); if (node.getBody().getKind() == Tree.Kind.BLOCK) { + builder.close(); builder.space(); // Explicit call with {@link CollapseEmptyOrNot.YES} to handle empty case blocks. visitBlock( @@ -280,13 +276,13 @@ public Void visitCase(CaseTree node, Void unused) { } else { builder.breakOp(" "); scan(node.getBody(), null); + builder.close(); } builder.guessToken(";"); break; default: throw new AssertionError(node.getCaseKind()); } - builder.close(); return null; } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input index 36eb21b16..0f4b485b8 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.input @@ -27,7 +27,7 @@ class SwitchGuardClause { } switch (o) { case TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName - when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName .methodWithVeryVeryVeryVeryLongNameReturnThis() .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { System.err.println(); @@ -35,18 +35,34 @@ class SwitchGuardClause { default -> {} } switch (o) { - case TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName, - TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName - when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName - .methodWithVeryVeryVeryVeryLongNameReturnThis() - .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { - System.err.println(); - } - default -> {} - } + case SwitchRecord( + int one, + int two, + int three, + int four, + int five, + int six, + int seven, + int eight, + int variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName) + when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + System.err.println(); + } + default -> {} + } switch (o) { - case TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName, - TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + case SwitchRecord( + int one, + int two, + int three, + int four, + int five, + int six, + int seven, + int eight, + int variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName) when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName .methodWithVeryVeryVeryVeryLongNameReturnThis() .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output index 1a81422c4..ac0961d03 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/SwitchGuardClause.output @@ -9,47 +9,63 @@ class SwitchGuardClause { { switch (o) { - case TypeWithVeryVeryVeryVeryLongName variableWithVeryLongName when variableWithVeryLongName - .methodWithVeryVeryVeryVeryLongNameReturnThis() - .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + case TypeWithVeryVeryVeryVeryLongName variableWithVeryLongName + when variableWithVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { System.err.println(); } default -> {} } switch (o) { - case TypeWithVeryVeryVeryVeryLongName - variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName - .methodWithVeryVeryVeryVeryLongNameReturnThis() - .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + case TypeWithVeryVeryVeryVeryLongName variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { System.err.println(); } default -> {} } switch (o) { case TypeWithVeryVeryVeryVeryLongName - variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName - .methodWithVeryVeryVeryVeryLongNameReturnThis() - .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { System.err.println(); } default -> {} } switch (o) { - case TypeWithVeryVeryVeryVeryLongName - variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName, - TypeWithVeryVeryVeryVeryLongName - variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName - .methodWithVeryVeryVeryVeryLongNameReturnThis() - .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { + case SwitchRecord( + int one, + int two, + int three, + int four, + int five, + int six, + int seven, + int eight, + int variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName) + when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + .methodWithVeryVeryVeryVeryLongNameReturnThis() + .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> { System.err.println(); } default -> {} } switch (o) { - case TypeWithVeryVeryVeryVeryLongName - variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName, - TypeWithVeryVeryVeryVeryLongName - variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName + case SwitchRecord( + int one, + int two, + int three, + int four, + int five, + int six, + int seven, + int eight, + int variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName) + when variableWithVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName .methodWithVeryVeryVeryVeryLongNameReturnThis() .methodWithVeryVeryVeryVeryLongNameReturnBoolean() -> System.err.println(); From 3356bd342c53a84acaff74768ff5fb40b1f296e3 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 18 Nov 2024 14:20:52 -0800 Subject: [PATCH 322/379] Remove Java17InputAstVisitor JDk 17 is now the lowest supported version. https://github.com/google/google-java-format/issues/1159 PiperOrigin-RevId: 697756606 --- .../googlejavaformat/java/Formatter.java | 4 - .../java/JavaInputAstVisitor.java | 198 +++++++++++- .../java/java17/Java17InputAstVisitor.java | 292 ------------------ .../java/java21/Java21InputAstVisitor.java | 6 +- .../META-INF/native-image/reflect-config.json | 9 - 5 files changed, 186 insertions(+), 323 deletions(-) delete mode 100644 core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index 5aa7a1233..e3b2b3235 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -155,10 +155,6 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept visitor = createVisitor( "com.google.googlejavaformat.java.java21.Java21InputAstVisitor", builder, options); - } else if (Runtime.version().feature() >= 17) { - visitor = - createVisitor( - "com.google.googlejavaformat.java.java17.Java17InputAstVisitor", builder, options); } else { visitor = new JavaInputAstVisitor(builder, options.indentationMultiplier()); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 01f9a3e05..dcaa930e4 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -14,6 +14,7 @@ package com.google.googlejavaformat.java; +import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.Iterables.getLast; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.googlejavaformat.Doc.FillMode.INDEPENDENT; @@ -84,8 +85,10 @@ import com.sun.source.tree.AssertTree; import com.sun.source.tree.AssignmentTree; import com.sun.source.tree.BinaryTree; +import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.BlockTree; import com.sun.source.tree.BreakTree; +import com.sun.source.tree.CaseLabelTree; import com.sun.source.tree.CaseTree; import com.sun.source.tree.CatchTree; import com.sun.source.tree.ClassTree; @@ -125,6 +128,7 @@ import com.sun.source.tree.RequiresTree; import com.sun.source.tree.ReturnTree; import com.sun.source.tree.StatementTree; +import com.sun.source.tree.SwitchExpressionTree; import com.sun.source.tree.SwitchTree; import com.sun.source.tree.SynchronizedTree; import com.sun.source.tree.ThrowTree; @@ -138,11 +142,13 @@ import com.sun.source.tree.VariableTree; import com.sun.source.tree.WhileLoopTree; import com.sun.source.tree.WildcardTree; +import com.sun.source.tree.YieldTree; import com.sun.source.util.TreePath; import com.sun.source.util.TreePathScanner; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; import java.util.ArrayDeque; import java.util.ArrayList; @@ -410,7 +416,17 @@ public Void visitCompilationUnit(CompilationUnitTree node, Void unused) { return null; } - protected void handleModule(boolean afterFirstToken, CompilationUnitTree node) {} + protected void handleModule(boolean afterFirstToken, CompilationUnitTree node) { + ModuleTree module = node.getModule(); + if (module != null) { + if (afterFirstToken) { + builder.blankLineWanted(YES); + } + markForPartialFormat(); + visitModule(module, null); + builder.forcedBreak(); + } + } /** Skips over extra semi-colons at the top-level, or in a class member declaration lists. */ protected void dropEmptyDeclarations() { @@ -436,6 +452,9 @@ public Void visitClass(ClassTree tree, Void unused) { case ENUM: visitEnumDeclaration(tree); break; + case RECORD: + visitRecordDeclaration(tree); + break; default: throw new AssertionError(tree.getKind()); } @@ -928,6 +947,69 @@ public boolean visitEnumDeclaration(ClassTree node) { return false; } + public void visitRecordDeclaration(ClassTree node) { + sync(node); + typeDeclarationModifiers(node.getModifiers()); + Verify.verify(node.getExtendsClause() == null); + boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); + token("record"); + builder.space(); + visit(node.getSimpleName()); + if (!node.getTypeParameters().isEmpty()) { + token("<"); + } + builder.open(plusFour); + { + if (!node.getTypeParameters().isEmpty()) { + typeParametersRest(node.getTypeParameters(), hasSuperInterfaceTypes ? plusFour : ZERO); + } + ImmutableList parameters = JavaInputAstVisitor.recordVariables(node); + token("("); + if (!parameters.isEmpty()) { + // Break before args. + builder.breakToFill(""); + } + // record headers can't declare receiver parameters + visitFormals(/* receiver= */ Optional.empty(), parameters); + token(")"); + if (hasSuperInterfaceTypes) { + builder.breakToFill(" "); + builder.open(node.getImplementsClause().size() > 1 ? plusFour : ZERO); + token("implements"); + builder.space(); + boolean afterFirstToken = false; + for (Tree superInterfaceType : node.getImplementsClause()) { + if (afterFirstToken) { + token(","); + builder.breakOp(" "); + } + scan(superInterfaceType, null); + afterFirstToken = true; + } + builder.close(); + } + } + builder.close(); + if (node.getMembers() == null) { + token(";"); + } else { + ImmutableList members = + node.getMembers().stream() + .filter(t -> (TreeInfo.flags((JCTree) t) & Flags.GENERATED_MEMBER) == 0) + .collect(toImmutableList()); + addBodyDeclarations(members, BracesOrNot.YES, FirstDeclarationsOrNot.YES); + } + dropEmptyDeclarations(); + } + + private static ImmutableList recordVariables(ClassTree node) { + return node.getMembers().stream() + .filter(JCTree.JCVariableDecl.class::isInstance) + .map(JCTree.JCVariableDecl.class::cast) + .filter(m -> (m.mods.flags & RECORD) == RECORD) + .collect(toImmutableList()); + } + @Override public Void visitMemberReference(MemberReferenceTree node, Void unused) { builder.open(plusFour); @@ -1199,7 +1281,11 @@ public Void visitInstanceOf(InstanceOfTree node, Void unused) { builder.open(ZERO); token("instanceof"); builder.breakOp(" "); - scan(node.getType(), null); + if (node.getPattern() != null) { + scan(node.getPattern(), null); + } else { + scan(node.getType(), null); + } builder.close(); builder.close(); return null; @@ -1874,18 +1960,69 @@ public Void visitCase(CaseTree node, Void unused) { sync(node); markForPartialFormat(); builder.forcedBreak(); - if (node.getExpression() == null) { + List labels = node.getLabels(); + boolean isDefault = + labels.size() == 1 && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL"); + builder.open(node.getCaseKind().equals(CaseTree.CaseKind.RULE) ? plusFour : ZERO); + if (isDefault) { token("default", ZERO); - token(":"); } else { token("case", ZERO); + builder.open(ZERO); builder.space(); - scan(node.getExpression(), null); - token(":"); + boolean afterFirstToken = false; + for (Tree expression : labels) { + if (afterFirstToken) { + token(","); + builder.breakOp(" "); + } + scan(expression, null); + afterFirstToken = true; + } + builder.close(); + } + + final ExpressionTree guard = getGuard(node); + if (guard != null) { + builder.breakToFill(" "); + token("when"); + builder.space(); + scan(guard, null); + } + + switch (node.getCaseKind()) { + case STATEMENT: + token(":"); + builder.open(plusTwo); + visitStatements(node.getStatements()); + builder.close(); + builder.close(); + break; + case RULE: + builder.space(); + token("-"); + token(">"); + if (node.getBody().getKind() == BLOCK) { + builder.close(); + builder.space(); + // Explicit call with {@link CollapseEmptyOrNot.YES} to handle empty case blocks. + visitBlock( + (BlockTree) node.getBody(), + CollapseEmptyOrNot.YES, + AllowLeadingBlankLine.NO, + AllowTrailingBlankLine.NO); + } else { + builder.breakOp(" "); + scan(node.getBody(), null); + builder.close(); + } + builder.guessToken(";"); + break; } - builder.open(plusTwo); - visitStatements(node.getStatements()); - builder.close(); + return null; + } + + protected ExpressionTree getGuard(final CaseTree node) { return null; } @@ -2022,7 +2159,7 @@ public Void visitTry(TryTree node, Void unused) { public void visitClassDeclaration(ClassTree node) { sync(node); typeDeclarationModifiers(node.getModifiers()); - List permitsTypes = getPermitsClause(node); + List permitsTypes = node.getPermitsClause(); boolean hasSuperclassType = node.getExtendsClause() != null; boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); boolean hasPermitsTypes = !permitsTypes.isEmpty(); @@ -3800,11 +3937,6 @@ protected void addBodyDeclarations( } } - /** Gets the permits clause for the given node. This is only available in Java 15 and later. */ - protected List getPermitsClause(ClassTree node) { - return ImmutableList.of(); - } - private void classDeclarationTypeList(String token, List types) { if (types.isEmpty()) { return; @@ -3966,4 +4098,40 @@ final BreakTag genSym() { public final String toString() { return MoreObjects.toStringHelper(this).add("builder", builder).toString(); } + + @Override + public Void visitBindingPattern(BindingPatternTree node, Void unused) { + sync(node); + VariableTree variableTree = node.getVariable(); + declareOne( + DeclarationKind.PARAMETER, + Direction.HORIZONTAL, + Optional.of(variableTree.getModifiers()), + variableTree.getType(), + variableTree.getName(), + /* op= */ "", + /* equals= */ "", + /* initializer= */ Optional.empty(), + /* trailing= */ Optional.empty(), + /* receiverExpression= */ Optional.empty(), + /* typeWithDims= */ Optional.empty()); + return null; + } + + @Override + public Void visitYield(YieldTree node, Void aVoid) { + sync(node); + token("yield"); + builder.space(); + scan(node.getValue(), null); + token(";"); + return null; + } + + @Override + public Void visitSwitchExpression(SwitchExpressionTree node, Void aVoid) { + sync(node); + visitSwitch(node.getExpression(), node.getCases()); + return null; + } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java deleted file mode 100644 index 315523585..000000000 --- a/core/src/main/java/com/google/googlejavaformat/java/java17/Java17InputAstVisitor.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2020 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.googlejavaformat.java.java17; - -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.Iterables.getOnlyElement; - -import com.google.common.base.Verify; -import com.google.common.collect.ImmutableList; -import com.google.googlejavaformat.OpsBuilder; -import com.google.googlejavaformat.OpsBuilder.BlankLineWanted; -import com.google.googlejavaformat.java.JavaInputAstVisitor; -import com.sun.source.tree.BindingPatternTree; -import com.sun.source.tree.BlockTree; -import com.sun.source.tree.CaseLabelTree; -import com.sun.source.tree.CaseTree; -import com.sun.source.tree.ClassTree; -import com.sun.source.tree.CompilationUnitTree; -import com.sun.source.tree.ExpressionTree; -import com.sun.source.tree.InstanceOfTree; -import com.sun.source.tree.ModifiersTree; -import com.sun.source.tree.ModuleTree; -import com.sun.source.tree.SwitchExpressionTree; -import com.sun.source.tree.Tree; -import com.sun.source.tree.VariableTree; -import com.sun.source.tree.YieldTree; -import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.TreeInfo; -import java.util.List; -import java.util.Optional; -import javax.lang.model.element.Name; - -/** - * Extends {@link JavaInputAstVisitor} with support for AST nodes that were added or modified in - * Java 17. - */ -public class Java17InputAstVisitor extends JavaInputAstVisitor { - - public Java17InputAstVisitor(OpsBuilder builder, int indentMultiplier) { - super(builder, indentMultiplier); - } - - @Override - protected void handleModule(boolean afterFirstToken, CompilationUnitTree node) { - ModuleTree module = node.getModule(); - if (module != null) { - if (afterFirstToken) { - builder.blankLineWanted(BlankLineWanted.YES); - } - markForPartialFormat(); - visitModule(module, null); - builder.forcedBreak(); - } - } - - @Override - protected List getPermitsClause(ClassTree node) { - return node.getPermitsClause(); - } - - @Override - public Void visitBindingPattern(BindingPatternTree node, Void unused) { - sync(node); - VariableTree variableTree = node.getVariable(); - visitBindingPattern( - variableTree.getModifiers(), variableTree.getType(), variableTree.getName()); - return null; - } - - private void visitBindingPattern(ModifiersTree modifiers, Tree type, Name name) { - declareOne( - DeclarationKind.PARAMETER, - Direction.HORIZONTAL, - Optional.of(modifiers), - type, - name, - /* op= */ "", - /* equals= */ "", - /* initializer= */ Optional.empty(), - /* trailing= */ Optional.empty(), - /* receiverExpression= */ Optional.empty(), - /* typeWithDims= */ Optional.empty()); - } - - @Override - public Void visitYield(YieldTree node, Void aVoid) { - sync(node); - token("yield"); - builder.space(); - scan(node.getValue(), null); - token(";"); - return null; - } - - @Override - public Void visitSwitchExpression(SwitchExpressionTree node, Void aVoid) { - sync(node); - visitSwitch(node.getExpression(), node.getCases()); - return null; - } - - @Override - public Void visitClass(ClassTree tree, Void unused) { - switch (tree.getKind()) { - case ANNOTATION_TYPE: - visitAnnotationType(tree); - break; - case CLASS: - case INTERFACE: - visitClassDeclaration(tree); - break; - case ENUM: - visitEnumDeclaration(tree); - break; - case RECORD: - visitRecordDeclaration(tree); - break; - default: - throw new AssertionError(tree.getKind()); - } - return null; - } - - public void visitRecordDeclaration(ClassTree node) { - sync(node); - typeDeclarationModifiers(node.getModifiers()); - Verify.verify(node.getExtendsClause() == null); - boolean hasSuperInterfaceTypes = !node.getImplementsClause().isEmpty(); - token("record"); - builder.space(); - visit(node.getSimpleName()); - if (!node.getTypeParameters().isEmpty()) { - token("<"); - } - builder.open(plusFour); - { - if (!node.getTypeParameters().isEmpty()) { - typeParametersRest(node.getTypeParameters(), hasSuperInterfaceTypes ? plusFour : ZERO); - } - ImmutableList parameters = recordVariables(node); - token("("); - if (!parameters.isEmpty()) { - // Break before args. - builder.breakToFill(""); - } - // record headers can't declare receiver parameters - visitFormals(/* receiver= */ Optional.empty(), parameters); - token(")"); - if (hasSuperInterfaceTypes) { - builder.breakToFill(" "); - builder.open(node.getImplementsClause().size() > 1 ? plusFour : ZERO); - token("implements"); - builder.space(); - boolean afterFirstToken = false; - for (Tree superInterfaceType : node.getImplementsClause()) { - if (afterFirstToken) { - token(","); - builder.breakOp(" "); - } - scan(superInterfaceType, null); - afterFirstToken = true; - } - builder.close(); - } - } - builder.close(); - if (node.getMembers() == null) { - token(";"); - } else { - List members = - node.getMembers().stream() - .filter(t -> (TreeInfo.flags((JCTree) t) & Flags.GENERATED_MEMBER) == 0) - .collect(toImmutableList()); - addBodyDeclarations(members, BracesOrNot.YES, FirstDeclarationsOrNot.YES); - } - dropEmptyDeclarations(); - } - - private static ImmutableList recordVariables(ClassTree node) { - return node.getMembers().stream() - .filter(JCVariableDecl.class::isInstance) - .map(JCVariableDecl.class::cast) - .filter(m -> (m.mods.flags & RECORD) == RECORD) - .collect(toImmutableList()); - } - - @Override - public Void visitInstanceOf(InstanceOfTree node, Void unused) { - sync(node); - builder.open(plusFour); - scan(node.getExpression(), null); - builder.breakOp(" "); - builder.open(ZERO); - token("instanceof"); - builder.breakOp(" "); - if (node.getPattern() != null) { - scan(node.getPattern(), null); - } else { - scan(node.getType(), null); - } - builder.close(); - builder.close(); - return null; - } - - @Override - public Void visitCase(CaseTree node, Void unused) { - sync(node); - markForPartialFormat(); - builder.forcedBreak(); - List labels = node.getLabels(); - boolean isDefault = - labels.size() == 1 && getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL"); - builder.open(node.getCaseKind().equals(CaseTree.CaseKind.RULE) ? plusFour : ZERO); - if (isDefault) { - token("default", ZERO); - } else { - token("case", ZERO); - builder.open(ZERO); - builder.space(); - boolean afterFirstToken = false; - for (Tree expression : labels) { - if (afterFirstToken) { - token(","); - builder.breakOp(" "); - } - scan(expression, null); - afterFirstToken = true; - } - builder.close(); - } - - final ExpressionTree guard = getGuard(node); - if (guard != null) { - builder.breakToFill(" "); - token("when"); - builder.space(); - scan(guard, null); - } - - switch (node.getCaseKind()) { - case STATEMENT: - token(":"); - builder.open(plusTwo); - visitStatements(node.getStatements()); - builder.close(); - builder.close(); - break; - case RULE: - builder.space(); - token("-"); - token(">"); - if (node.getBody().getKind() == Tree.Kind.BLOCK) { - builder.close(); - builder.space(); - // Explicit call with {@link CollapseEmptyOrNot.YES} to handle empty case blocks. - visitBlock( - (BlockTree) node.getBody(), - CollapseEmptyOrNot.YES, - AllowLeadingBlankLine.NO, - AllowTrailingBlankLine.NO); - } else { - builder.breakOp(" "); - scan(node.getBody(), null); - builder.close(); - } - builder.guessToken(";"); - break; - default: - throw new AssertionError(node.getCaseKind()); - } - return null; - } - - protected ExpressionTree getGuard(final CaseTree node) { - return null; - } -} diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java index 859c9c0cf..029da8e04 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java @@ -15,7 +15,7 @@ package com.google.googlejavaformat.java.java21; import com.google.googlejavaformat.OpsBuilder; -import com.google.googlejavaformat.java.java17.Java17InputAstVisitor; +import com.google.googlejavaformat.java.JavaInputAstVisitor; import com.sun.source.tree.CaseTree; import com.sun.source.tree.ConstantCaseLabelTree; import com.sun.source.tree.DeconstructionPatternTree; @@ -28,10 +28,10 @@ import javax.lang.model.element.Name; /** - * Extends {@link Java17InputAstVisitor} with support for AST nodes that were added or modified in + * Extends {@link JavaInputAstVisitor} with support for AST nodes that were added or modified in * Java 21. */ -public class Java21InputAstVisitor extends Java17InputAstVisitor { +public class Java21InputAstVisitor extends JavaInputAstVisitor { public Java21InputAstVisitor(OpsBuilder builder, int indentMultiplier) { super(builder, indentMultiplier); diff --git a/core/src/main/resources/META-INF/native-image/reflect-config.json b/core/src/main/resources/META-INF/native-image/reflect-config.json index 4d30840f1..89577c035 100644 --- a/core/src/main/resources/META-INF/native-image/reflect-config.json +++ b/core/src/main/resources/META-INF/native-image/reflect-config.json @@ -3,15 +3,6 @@ "name": "com.sun.tools.javac.parser.UnicodeReader", "allDeclaredMethods": true }, - { - "name": "com.google.googlejavaformat.java.java17.Java17InputAstVisitor", - "methods": [ - { - "name": "", - "parameterTypes": ["com.google.googlejavaformat.OpsBuilder", "int"] - } - ] - }, { "name": "com.google.googlejavaformat.java.java21.Java21InputAstVisitor", "methods": [ From 52696257a3f71158e4730ba47b569d7d6eae75a4 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 18 Nov 2024 15:54:34 -0800 Subject: [PATCH 323/379] Fix logic for checking if text blocks are already deindented Check the last line instead of the first line of the text block contents. Empty lines in the text block have no leading whitespace but do not indicate the contents are deindented, only non-empty lines should be considered. The last line will never be empty, it contains at least the close delimiter. PiperOrigin-RevId: 697785256 --- .../googlejavaformat/java/StringWrapper.java | 3 ++- .../java/StringWrapperTest.java | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 42099d6b8..c3a36ab50 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -207,7 +207,8 @@ private void indentTextBlocks( String stripped = stripIndent(initialLines.stream().skip(1).collect(joining(separator))); ImmutableList lines = stripped.lines().collect(toImmutableList()); int deindent = - initialLines.get(1).stripTrailing().length() - lines.get(0).stripTrailing().length(); + getLast(initialLines).stripTrailing().length() + - getLast(lines).stripTrailing().length(); String prefix = (deindent == 0 diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java index 7854126c4..339ed1340 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -174,6 +174,33 @@ public void textBlockSpaceTabMix() throws Exception { assertThat(actual).isEqualTo(expected); } + @Test + public void leadingBlankLine() throws Exception { + assumeTrue(Runtime.version().feature() >= 15); + String input = + lines( + "public class T {", + " String s =", + " \"\"\"", + "", + " lorem", + " ipsum", + " \"\"\";", + "}"); + String expected = + lines( + "public class T {", + " String s =", + " \"\"\"", + "", + " lorem", + " ipsum", + " \"\"\";", + "}"); + String actual = StringWrapper.wrap(100, input, new Formatter()); + assertThat(actual).isEqualTo(expected); + } + private static String lines(String... line) { return Joiner.on('\n').join(line) + '\n'; } From 20c526c79799c2f4a986bd2df621b022aa4c875e Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 19 Nov 2024 07:56:12 -0800 Subject: [PATCH 324/379] Update Error Prone to version 2.36.0 PiperOrigin-RevId: 698016480 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c31340223..f6efb7b7d 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 32.1.3-jre 1.4.0 1.0.0 - 2.34.0 + 2.36.0 1.9 1.0.1 3.6.3 From a4991be14c8375bc3258b3af02380e40362419f3 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 21 Nov 2024 15:41:18 -0800 Subject: [PATCH 325/379] Fix a bug where leading whitespace was removed from the last line of a text block If the last line contains contents other than the closing delimiter, it may have significant leading whitespace. This change prevents that whitespace from being removed. https://github.com/google/google-java-format/issues/1195 PiperOrigin-RevId: 698939557 --- .../google/googlejavaformat/java/StringWrapper.java | 4 ++-- .../java/FormatterIntegrationTest.java | 3 ++- .../googlejavaformat/java/testdata/B380299722.input | 9 +++++++++ .../googlejavaformat/java/testdata/B380299722.output | 11 +++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B380299722.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B380299722.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index c3a36ab50..eb7eacfa4 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -219,7 +219,7 @@ private void indentTextBlocks( StringBuilder output = new StringBuilder(initialLines.get(0).stripLeading()); for (int i = 0; i < lines.size(); i++) { String line = lines.get(i); - String trimmed = line.stripLeading().stripTrailing(); + String trimmed = line.stripTrailing(); output.append(separator); if (!trimmed.isEmpty()) { // Don't add incidental leading whitespace to empty lines @@ -228,7 +228,7 @@ private void indentTextBlocks( if (i == lines.size() - 1) { String withoutDelimiter = trimmed.substring(0, trimmed.length() - TEXT_BLOCK_DELIMITER.length()); - if (!withoutDelimiter.isEmpty()) { + if (!withoutDelimiter.stripLeading().isEmpty()) { output.append(withoutDelimiter).append('\\').append(separator).append(prefix); } // If the trailing line is just """, indenting it more than the prefix of incidental diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index ef6bef087..b83be477b 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -57,7 +57,8 @@ public class FormatterIntegrationTest { "ExpressionSwitch", "I574", "I594", - "SwitchComment") + "SwitchComment", + "B380299722") .putAll(15, "I603") .putAll(16, "I588", "Sealed") .putAll(17, "I683", "I684", "I696") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B380299722.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B380299722.input new file mode 100644 index 000000000..8da9601c9 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B380299722.input @@ -0,0 +1,9 @@ +package com.helloworld; + +class Foo { + void foo() { + var bar = """ + bar\ + bar"""; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B380299722.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B380299722.output new file mode 100644 index 000000000..397073147 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B380299722.output @@ -0,0 +1,11 @@ +package com.helloworld; + +class Foo { + void foo() { + var bar = + """ + bar\ + bar\ + """; + } +} From a6e5bd96de304510d0d338ae1dd149114f3e3a78 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 22 Nov 2024 11:29:59 -0800 Subject: [PATCH 326/379] Remove some unnecessary reflection now that the formatter only supports JDK 17 PiperOrigin-RevId: 699235273 --- .../googlejavaformat/java/StringWrapper.java | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index eb7eacfa4..c1c38d34b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -45,7 +45,6 @@ import com.sun.tools.javac.util.Position; import java.io.IOException; import java.io.UncheckedIOException; -import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayDeque; import java.util.ArrayList; @@ -61,7 +60,6 @@ import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import javax.tools.StandardLocation; -import org.jspecify.annotations.Nullable; /** Wraps string literals that exceed the column limit. */ public final class StringWrapper { @@ -204,7 +202,7 @@ private void indentTextBlocks( // The first line of the text block is always """, and it does not affect incidental // whitespace. ImmutableList initialLines = text.lines().collect(toImmutableList()); - String stripped = stripIndent(initialLines.stream().skip(1).collect(joining(separator))); + String stripped = initialLines.stream().skip(1).collect(joining(separator)).stripIndent(); ImmutableList lines = stripped.lines().collect(toImmutableList()); int deindent = getLast(initialLines).stripTrailing().length() @@ -280,30 +278,6 @@ private void wrapLongStrings( } } - private static final Method STRIP_INDENT = getStripIndent(); - - private static @Nullable Method getStripIndent() { - if (Runtime.version().feature() < 15) { - return null; - } - try { - return String.class.getMethod("stripIndent"); - } catch (NoSuchMethodException e) { - throw new LinkageError(e.getMessage(), e); - } - } - - private static String stripIndent(String input) { - if (STRIP_INDENT == null) { - return input; - } - try { - return (String) STRIP_INDENT.invoke(input); - } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); - } - } - /** * Returns the source text of the given string literal trees, excluding the leading and trailing * double-quotes and the `+` operator. From 07e6d604cf24141f70b0f9d8eaf61cd0f7920928 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Fri, 22 Nov 2024 12:39:09 -0800 Subject: [PATCH 327/379] Update the IntelliJ plugin to 1.25.0. PiperOrigin-RevId: 699256809 --- idea_plugin/build.gradle.kts | 5 +++-- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index d5eb59931..74cd1bd0d 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -1,4 +1,3 @@ -import org.jetbrains.intellij.platform.gradle.TestFrameworkType /* * Copyright 2017 Google Inc. All Rights Reserved. * @@ -15,6 +14,8 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType * limitations under the License. */ +import org.jetbrains.intellij.platform.gradle.TestFrameworkType + // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases plugins { id("org.jetbrains.intellij.platform") version "2.1.0" @@ -29,7 +30,7 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.24.0" +val googleJavaFormatVersion = "1.25.0" java { sourceCompatibility = JavaVersion.VERSION_17 diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index c09257baa..612f922c2 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +

        1.25.0.0
        +
        Updated to use google-java-format 1.25.0.
        1.24.0.0
        Updated to use google-java-format 1.24.0.
        1.23.0.0
        From cbeef0f95142bd88056fd57240a0960e31aaeeb0 Mon Sep 17 00:00:00 2001 From: Kurt Alfred Kluever Date: Wed, 27 Nov 2024 10:23:56 -0800 Subject: [PATCH 328/379] Add google-java-format unit tests for existing `@Annotation()` behavior. PiperOrigin-RevId: 700741432 --- .../googlejavaformat/java/testdata/B381242320.input | 11 +++++++++++ .../googlejavaformat/java/testdata/B381242320.output | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B381242320.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/B381242320.output diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B381242320.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B381242320.input new file mode 100644 index 000000000..4c5e12e53 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B381242320.input @@ -0,0 +1,11 @@ +class B381242320 { + @Deprecated() + public int deprecatedMethod() { + return 42; + } + + @Override() + public int hashCode() { + return 42; + } +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B381242320.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B381242320.output new file mode 100644 index 000000000..4c5e12e53 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B381242320.output @@ -0,0 +1,11 @@ +class B381242320 { + @Deprecated() + public int deprecatedMethod() { + return 42; + } + + @Override() + public int hashCode() { + return 42; + } +} From ad29696272d6e5b7e3306ba10186490ac246027e Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Tue, 10 Dec 2024 07:12:59 -0800 Subject: [PATCH 329/379] Update the IntelliJ plugin to 1.25.1. PiperOrigin-RevId: 704697540 --- idea_plugin/build.gradle.kts | 4 ++-- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 74cd1bd0d..b2405603c 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -18,7 +18,7 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases plugins { - id("org.jetbrains.intellij.platform") version "2.1.0" + id("org.jetbrains.intellij.platform") version "2.2.0" } repositories { @@ -30,7 +30,7 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.25.0" +val googleJavaFormatVersion = "1.25.1" java { sourceCompatibility = JavaVersion.VERSION_17 diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 612f922c2..edede3151 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
        1.25.1.0
        +
        Updated to use google-java-format 1.25.1.
        1.25.0.0
        Updated to use google-java-format 1.25.0.
        1.24.0.0
        From 3d2f63e1a2363e1c2a225e37db5d7a95b0d64325 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 11 Dec 2024 13:24:53 -0800 Subject: [PATCH 330/379] Fix another text block special case Handle removing trailing whitespace when the closing delimiter is on the same line as the final line of the text block. Fixes https://github.com/google/google-java-format/issues/1205 PiperOrigin-RevId: 705218533 --- .../com/google/googlejavaformat/java/StringWrapper.java | 4 +++- .../com/google/googlejavaformat/java/testdata/I1205.input | 7 +++++++ .../google/googlejavaformat/java/testdata/I1205.output | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I1205.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/I1205.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index c1c38d34b..5d10da388 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -225,7 +225,9 @@ private void indentTextBlocks( } if (i == lines.size() - 1) { String withoutDelimiter = - trimmed.substring(0, trimmed.length() - TEXT_BLOCK_DELIMITER.length()); + trimmed + .substring(0, trimmed.length() - TEXT_BLOCK_DELIMITER.length()) + .stripTrailing(); if (!withoutDelimiter.stripLeading().isEmpty()) { output.append(withoutDelimiter).append('\\').append(separator).append(prefix); } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1205.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1205.input new file mode 100644 index 000000000..8f8acaa16 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1205.input @@ -0,0 +1,7 @@ +public interface Foo { + + private static String foo = + """ + foo\ + bar """; +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1205.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1205.output new file mode 100644 index 000000000..c82862c09 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/I1205.output @@ -0,0 +1,8 @@ +public interface Foo { + + private static String foo = + """ + foo\ + bar\ + """; +} From 36deed0ccc64ad18ea7e313579ac94344dabe5ba Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 11 Dec 2024 14:17:02 -0800 Subject: [PATCH 331/379] Remove conditional logic in tests for unsupported JDK versions JDK 17 is now the minimum supported version. PiperOrigin-RevId: 705237702 --- .../java/FormatterIntegrationTest.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index b83be477b..6a73da185 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -48,20 +48,6 @@ public class FormatterIntegrationTest { private static final ImmutableMultimap VERSIONED_TESTS = ImmutableMultimap.builder() - .putAll( - 14, - "I477", - "Records", - "RSLs", - "Var", - "ExpressionSwitch", - "I574", - "I594", - "SwitchComment", - "B380299722") - .putAll(15, "I603") - .putAll(16, "I588", "Sealed") - .putAll(17, "I683", "I684", "I696") .putAll( 21, "SwitchGuardClause", From 88614098a58fea1bfe214c464fde019bd725c891 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Wed, 11 Dec 2024 19:08:23 -0800 Subject: [PATCH 332/379] Update the IntelliJ plugin to 1.25.2. PiperOrigin-RevId: 705324566 --- idea_plugin/build.gradle.kts | 2 +- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index b2405603c..d99451333 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -30,7 +30,7 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.25.1" +val googleJavaFormatVersion = "1.25.2" java { sourceCompatibility = JavaVersion.VERSION_17 diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index edede3151..f7188f929 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
        1.25.2.0
        +
        Updated to use google-java-format 1.25.2.
        1.25.1.0
        Updated to use google-java-format 1.25.1.
        1.25.0.0
        From eb0b7682f15ec6a2bd03d12b53bdf951dd924266 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 19 Dec 2024 17:38:22 -0800 Subject: [PATCH 333/379] Increase JAXP limits to fix Tycho plugin See https://github.com/google/google-java-format/issues/1210 PiperOrigin-RevId: 708100474 --- .mvn/jvm.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.mvn/jvm.config b/.mvn/jvm.config index 504456f90..2e8f1d41f 100644 --- a/.mvn/jvm.config +++ b/.mvn/jvm.config @@ -8,3 +8,6 @@ --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED + +-Djdk.xml.maxGeneralEntitySizeLimit=0 +-Djdk.xml.totalEntitySizeLimit=0 \ No newline at end of file From ccb56c79b0bf4cec457e06f1156a0a0234ca576d Mon Sep 17 00:00:00 2001 From: Halil Sener Date: Thu, 13 Feb 2025 14:18:00 +0100 Subject: [PATCH 334/379] Publish Linux arm64 GraalVM native-image binary --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2ce2beae..dc0b4a465 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -89,10 +89,10 @@ jobs: # Use "oldest" available ubuntu-* instead of -latest, # see https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories; # due to https://github.com/google/google-java-format/issues/1072. - os: [ubuntu-20.04, macos-latest, windows-latest] + os: [ubuntu-20.04, ubuntu-22.04-arm, macos-latest, windows-latest] env: # NB: Must keep the keys in this inline JSON below in line with the os: above! - SUFFIX: ${{fromJson('{"ubuntu-20.04":"linux-x86-64", "macos-latest":"darwin-arm64", "windows-latest":"windows-x86-64"}')[matrix.os]}} + SUFFIX: ${{fromJson('{"ubuntu-20.04":"linux-x86-64", "ubuntu-22.04-arm":"linux-arm64", "macos-latest":"darwin-arm64", "windows-latest":"windows-x86-64"}')[matrix.os]}} EXTENSION: ${{ matrix.os == 'windows-latest' && '.exe' || '' }} steps: - name: "Check out repository" From dae09ec63ca58c04dd72555e5a82304fb32a25a1 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 20 Mar 2025 11:17:34 -0700 Subject: [PATCH 335/379] Update Error Prone version PiperOrigin-RevId: 738874322 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f6efb7b7d..46ccad473 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 32.1.3-jre 1.4.0 1.0.0 - 2.36.0 + 2.37.0 1.9 1.0.1 3.6.3 From 4e0eb5ae736b42c12ae667ec2a05b668704f9b89 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 24 Mar 2025 09:25:53 -0700 Subject: [PATCH 336/379] Text block formatting refinements * Don't automatically deindent long text blocks to start at column 0. For text blocks that are already deindented the existing choice will be preserved, but it won't happen automatically. * For deindented text blocks, put the opening `"""` at column 0 instead of indenting it PiperOrigin-RevId: 739966701 --- .../java/JavaInputAstVisitor.java | 19 +++++++++++++++++ .../googlejavaformat/java/StringWrapper.java | 21 ++++++------------- .../java/StringWrapperTest.java | 2 +- .../java/testdata/B361077825.output | 4 ++-- .../googlejavaformat/java/testdata/RSLs.input | 5 +++++ .../java/testdata/RSLs.output | 21 ++++++++++++------- 6 files changed, 47 insertions(+), 25 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index dcaa930e4..f21f86a5c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -42,6 +42,7 @@ import static com.sun.source.tree.Tree.Kind.STRING_LITERAL; import static com.sun.source.tree.Tree.Kind.UNION_TYPE; import static com.sun.source.tree.Tree.Kind.VARIABLE; +import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; import com.google.auto.value.AutoOneOf; @@ -71,6 +72,7 @@ import com.google.googlejavaformat.FormattingError; import com.google.googlejavaformat.Indent; import com.google.googlejavaformat.Input; +import com.google.googlejavaformat.Newlines; import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpenOp; import com.google.googlejavaformat.OpsBuilder; @@ -1753,6 +1755,23 @@ public Void visitMemberSelect(MemberSelectTree node, Void unused) { public Void visitLiteral(LiteralTree node, Void unused) { sync(node); String sourceForNode = getSourceForNode(node, getCurrentPath()); + if (sourceForNode.startsWith("\"\"\"")) { + String separator = Newlines.guessLineSeparator(sourceForNode); + ImmutableList initialLines = sourceForNode.lines().collect(toImmutableList()); + String stripped = initialLines.stream().skip(1).collect(joining(separator)).stripIndent(); + // Use the last line of the text block to determine if it is deindented to column 0, by + // comparing the length of the line in the input source with the length after processing + // the text block contents with stripIndent(). + boolean deindent = + getLast(initialLines).stripTrailing().length() + == Streams.findLast(stripped.lines()).orElseThrow().stripTrailing().length(); + if (deindent) { + Indent indent = Indent.Const.make(Integer.MIN_VALUE / indentMultiplier, indentMultiplier); + builder.breakOp(indent); + } + token(sourceForNode); + return null; + } if (isUnaryMinusLiteral(sourceForNode)) { token("-"); sourceForNode = sourceForNode.substring(1).trim(); diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 5d10da388..27450d82f 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -188,15 +188,10 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) { private void indentTextBlocks( TreeRangeMap replacements, List textBlocks) { for (Tree tree : textBlocks) { - int startPosition = getStartPosition(tree); + int startPosition = lineMap.getStartPosition(lineMap.getLineNumber(getStartPosition(tree))); int endPosition = getEndPosition(unit, tree); String text = input.substring(startPosition, endPosition); - int lineStartPosition = lineMap.getStartPosition(lineMap.getLineNumber(startPosition)); - int startColumn = - CharMatcher.whitespace() - .negate() - .indexIn(input.substring(lineStartPosition, endPosition)) - + 1; + int leadingWhitespace = CharMatcher.whitespace().negate().indexIn(text); // Find the source code of the text block with incidental whitespace removed. // The first line of the text block is always """, and it does not affect incidental @@ -204,17 +199,13 @@ private void indentTextBlocks( ImmutableList initialLines = text.lines().collect(toImmutableList()); String stripped = initialLines.stream().skip(1).collect(joining(separator)).stripIndent(); ImmutableList lines = stripped.lines().collect(toImmutableList()); - int deindent = + boolean deindent = getLast(initialLines).stripTrailing().length() - - getLast(lines).stripTrailing().length(); + == getLast(lines).stripTrailing().length(); - String prefix = - (deindent == 0 - || lines.stream().anyMatch(x -> x.length() + startColumn - 1 > columnLimit)) - ? "" - : " ".repeat(startColumn - 1); + String prefix = deindent ? "" : " ".repeat(leadingWhitespace); - StringBuilder output = new StringBuilder(initialLines.get(0).stripLeading()); + StringBuilder output = new StringBuilder(prefix).append(initialLines.get(0).stripLeading()); for (int i = 0; i < lines.size(); i++) { String line = lines.get(i); String trimmed = line.stripTrailing(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java index 339ed1340..a9ceeacb6 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperTest.java @@ -63,7 +63,7 @@ public void textBlock() throws Exception { " private String myString;", " private ReproBug() {", " String str =", - " \"\"\"", + "\"\"\"", "{\"sourceEndpoint\":\"ri.something.1-1.object-internal.1\",\"targetEndpoint" + "\":\"ri.something.1-1.object-internal.2\",\"typeId\":\"typeId\"}\\", "\"\"\";", diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output index 62344bd54..c93942a5d 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/B361077825.output @@ -10,6 +10,6 @@ class T { """; String c = """ - # No implicit input file, because they can only be created outside a symbolic macro, -"""; + # No implicit input file, because they can only be created outside a symbolic macro, + """; } diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input index 6eaa28558..002b3653a 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.input @@ -40,6 +40,11 @@ class RSLs { lorem ipsum """; + String l = + """ + foo +bar + baz"""; { f(""" lorem diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output index 6e9a3ae5b..af4a8a6fc 100644 --- a/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/RSLs.output @@ -43,14 +43,20 @@ class RSLs { """; String j = """ -lorem -one long incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt -ipsum -"""; + lorem + one long incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt + ipsum + """; String k = - """ +""" lorem ipsum +"""; + String l = +""" + foo +bar + baz\ """; { @@ -85,10 +91,11 @@ ipsum bar """; String t = - """ +""" foo """ - + """ + + +""" bar """; String u = From 14ae0a786ed7ff88e34b7b7f26c55123df997589 Mon Sep 17 00:00:00 2001 From: "Michael Vorburger.ch" Date: Thu, 27 Mar 2025 02:37:24 -0700 Subject: [PATCH 337/379] Clarify impact of java version used on /google_java_format README. Manually created Google internal equivalent of public https://github.com/google/google-java-format/pull/1228, just in case it's easier to review here instead of there; quote with rationale for this, from public PR description: It at first confused the hell out of me why clearly the exact SAME version of google-java-format worked great locally but failed with errors (due to my use of record matching pattern syntax) on a GitHub Action - until I've noticed that it still ran under Java 17 - and that this matters to google-java-format (my naive initial assumption was that only the google-java-format version itself was relevant). PiperOrigin-RevId: 741076633 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 83a524bbd..d3836efb2 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,11 @@ and run it with: java -jar /path/to/google-java-format-${GJF_VERSION?}-all-deps.jar [files...] ``` +Note that it uses the `jdk.compiler` module to parse the Java source code. The +`java` binary version used must therefore be from a JDK (not JRE) with a version +equal to or newer than the Java language version of the files being formatted. +An alternative is to use the available GraalVM based native binaries instead. + The formatter can act on whole files, on limited lines (`--lines`), on specific offsets (`--offset`), passing through to standard-out (default) or altered in-place (`--replace`). From 9d16612acaf98bfdd46ca4733ee0b935e4d1f54d Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 27 Mar 2025 10:09:56 -0700 Subject: [PATCH 338/379] Update release.yml More permissions --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dc0b4a465..5b2610d97 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: build-maven-jars: runs-on: ubuntu-latest permissions: - contents: write + contents: write-all steps: - name: Checkout uses: actions/checkout@v4 From 1bdb10b85170fb6812ada6dbf9e151023ef3fff2 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 27 Mar 2025 10:14:03 -0700 Subject: [PATCH 339/379] Update release.yml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5b2610d97..dc0b4a465 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: build-maven-jars: runs-on: ubuntu-latest permissions: - contents: write-all + contents: write steps: - name: Checkout uses: actions/checkout@v4 From e77d28a00bcb3d7fc7bce3a9b4e0bfe29bce3d66 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 27 Mar 2025 10:14:45 -0700 Subject: [PATCH 340/379] Update release.yml --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dc0b4a465..1db537e39 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -83,6 +83,8 @@ jobs: build-native-image: name: "Build GraalVM native-image on ${{ matrix.os }}" runs-on: ${{ matrix.os }} + permissions: + contents: write needs: build-maven-jars strategy: matrix: From ec9826b725a79e5dc36c46c1f51f1f9edc27faee Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Thu, 27 Mar 2025 12:57:12 -0700 Subject: [PATCH 341/379] Update the IntelliJ plugin to 1.26.0. PiperOrigin-RevId: 741251928 --- idea_plugin/build.gradle.kts | 4 ++-- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index d99451333..760a8b94c 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -18,7 +18,7 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases plugins { - id("org.jetbrains.intellij.platform") version "2.2.0" + id("org.jetbrains.intellij.platform") version "2.4.0" } repositories { @@ -30,7 +30,7 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.25.2" +val googleJavaFormatVersion = "1.26.0" java { sourceCompatibility = JavaVersion.VERSION_17 diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index f7188f929..28e6d3e35 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
        1.26.0.0
        +
        Updated to use google-java-format 1.26.0.
        1.25.2.0
        Updated to use google-java-format 1.25.2.
        1.25.1.0
        From aee16ed8015733ea3ebd344e6aeebb1cd813b05f Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Fri, 28 Mar 2025 08:31:07 -0700 Subject: [PATCH 342/379] docs: Clarify minimum Java version in README (see #1225) @kwin re. #1225 @cushon merge? Fixes #1235 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1235 from vorburger:patch-7 38255fae85c988972cf1c68a721efab62256d63c PiperOrigin-RevId: 741534873 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d3836efb2..ab55679ab 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ java -jar /path/to/google-java-format-${GJF_VERSION?}-all-deps.jar [fi Note that it uses the `jdk.compiler` module to parse the Java source code. The `java` binary version used must therefore be from a JDK (not JRE) with a version equal to or newer than the Java language version of the files being formatted. -An alternative is to use the available GraalVM based native binaries instead. +The minimum Java version can be found in `core/pom.xml` (currently Java 17). An +alternative is to use the available GraalVM based native binaries instead. The formatter can act on whole files, on limited lines (`--lines`), on specific offsets (`--offset`), passing through to standard-out (default) or altered From 86338266807cb8d78082179733b31a8fd0be972c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 4 Apr 2025 14:10:48 -0700 Subject: [PATCH 343/379] Optimize string wrapping PiperOrigin-RevId: 744065507 --- .../googlejavaformat/java/StringWrapper.java | 36 ++++++---- .../java/StringWrapperIntegrationTest.java | 65 +++++++++++++++++++ 2 files changed, 89 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 27450d82f..f1014e52f 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -53,7 +53,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Stream; import javax.tools.Diagnostic; import javax.tools.DiagnosticCollector; import javax.tools.DiagnosticListener; @@ -316,19 +315,21 @@ private static ImmutableList stringComponents( } static int hasEscapedWhitespaceAt(String input, int idx) { - return Stream.of("\\t") - .mapToInt(x -> input.startsWith(x, idx) ? x.length() : -1) - .filter(x -> x != -1) - .findFirst() - .orElse(-1); + if (input.startsWith("\\t", idx)) { + return 2; + } + return -1; } static int hasEscapedNewlineAt(String input, int idx) { - return Stream.of("\\r\\n", "\\r", "\\n") - .mapToInt(x -> input.startsWith(x, idx) ? x.length() : -1) - .filter(x -> x != -1) - .findFirst() - .orElse(-1); + int offset = 0; + if (input.startsWith("\\r", idx)) { + offset += 2; + } + if (input.startsWith("\\n", idx)) { + offset += 2; + } + return offset > 0 ? offset : -1; } /** @@ -360,7 +361,7 @@ private static String reflow( List line = new ArrayList<>(); // If we know this is going to be the last line, then remove a bit of width to account for the // trailing characters. - if (input.stream().mapToInt(String::length).sum() <= width) { + if (totalLengthLessThanOrEqual(input, width)) { // This isn’t quite optimal, but arguably good enough. See b/179561701 width -= trailing; } @@ -391,6 +392,17 @@ private static String reflow( "\"")); } + private static boolean totalLengthLessThanOrEqual(Iterable input, int length) { + int total = 0; + for (String s : input) { + total += s.length(); + if (total > length) { + return false; + } + } + return true; + } + /** * Flattens the given binary expression tree, and extracts the subset that contains the given path * and any adjacent nodes that are also string literals. diff --git a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java index 53fb54d91..5032ac97c 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/StringWrapperIntegrationTest.java @@ -365,6 +365,71 @@ public static Collection parameters() { "}" }, }, + { + { + "class T {", // + " String s = \"\\r\\rone\\rlong\\rincredibly\\runbroken\\rsentence\\rmoving\\rfrom\\r" + + " topic\\rto\\r topic\\rso\\rthat\\rno-one\\rhad\\ra\\rchance\\rto\\rinterrupt\";", + "}" + }, + { + "class T {", + " String s =", + " \"\\r\\r\"", + " + \"one\\r\"", + " + \"long\\r\"", + " + \"incredibly\\r\"", + " + \"unbroken\\r\"", + " + \"sentence\\r\"", + " + \"moving\\r\"", + " + \"from\\r\"", + " + \" topic\\r\"", + " + \"to\\r\"", + " + \" topic\\r\"", + " + \"so\\r\"", + " + \"that\\r\"", + " + \"no-one\\r\"", + " + \"had\\r\"", + " + \"a\\r\"", + " + \"chance\\r\"", + " + \"to\\r\"", + " + \"interrupt\";", + "}", + }, + }, + { + { + "class T {", // + " String s = \"\\r\\n\\r\\none\\r\\nlong\\r\\nincredibly\\r\\nunbroken\\r\\nsentence" + + "\\r\\nmoving\\r\\nfrom\\r\\n topic\\r\\nto\\r\\n topic\\r\\nso\\r\\nthat\\r\\n" + + "no-one\\r\\nhad\\r\\na\\r\\nchance\\r\\nto\\r\\ninterrupt\";", + "}" + }, + { + "class T {", + " String s =", + " \"\\r\\n\\r\\n\"", + " + \"one\\r\\n\"", + " + \"long\\r\\n\"", + " + \"incredibly\\r\\n\"", + " + \"unbroken\\r\\n\"", + " + \"sentence\\r\\n\"", + " + \"moving\\r\\n\"", + " + \"from\\r\\n\"", + " + \" topic\\r\\n\"", + " + \"to\\r\\n\"", + " + \" topic\\r\\n\"", + " + \"so\\r\\n\"", + " + \"that\\r\\n\"", + " + \"no-one\\r\\n\"", + " + \"had\\r\\n\"", + " + \"a\\r\\n\"", + " + \"chance\\r\\n\"", + " + \"to\\r\\n\"", + " + \"interrupt\";", + "}", + }, + }, }; return Arrays.stream(inputsAndOutputs) .map( From db2713a7b81e20cb135d58f3a48a634bc7df2f05 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 8 Apr 2025 16:48:38 -0700 Subject: [PATCH 344/379] Migrate to CommandLineOptions to a record and AutoBuilder This allows the CheckReturnValue analysis to tell that it's a builder and ignore the results of builder methods. PiperOrigin-RevId: 745341492 --- .../java/CommandLineOptions.java | 322 +++++------------- .../java/CommandLineOptionsParser.java | 8 +- 2 files changed, 83 insertions(+), 247 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java index d5480a790..e794a1815 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java @@ -14,291 +14,121 @@ package com.google.googlejavaformat.java; +import com.google.auto.value.AutoBuilder; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableRangeSet; -import com.google.common.collect.RangeSet; -import com.google.common.collect.TreeRangeSet; +import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.util.Optional; /** * Command line options for google-java-format. * - *

        google-java-format doesn't depend on AutoValue, to allow AutoValue to depend on - * google-java-format. + * @param files The files to format. + * @param inPlace Format files in place. + * @param lines Line ranges to format. + * @param offsets Character offsets for partial formatting, paired with {@code lengths}. + * @param lengths Partial formatting region lengths, paired with {@code offsets}. + * @param aosp Use AOSP style instead of Google Style (4-space indentation). + * @param version Print the version. + * @param help Print usage information. + * @param stdin Format input from stdin. + * @param fixImportsOnly Fix imports, but do no formatting. + * @param sortImports Sort imports. + * @param removeUnusedImports Remove unused imports. + * @param dryRun Print the paths of the files whose contents would change if the formatter were run + * normally. + * @param setExitIfChanged Return exit code 1 if there are any formatting changes. + * @param assumeFilename Return the name to use for diagnostics when formatting standard input. */ -final class CommandLineOptions { - - private final ImmutableList files; - private final boolean inPlace; - private final ImmutableRangeSet lines; - private final ImmutableList offsets; - private final ImmutableList lengths; - private final boolean aosp; - private final boolean version; - private final boolean help; - private final boolean stdin; - private final boolean fixImportsOnly; - private final boolean sortImports; - private final boolean removeUnusedImports; - private final boolean dryRun; - private final boolean setExitIfChanged; - private final Optional assumeFilename; - private final boolean reflowLongStrings; - private final boolean formatJavadoc; - - CommandLineOptions( - ImmutableList files, - boolean inPlace, - ImmutableRangeSet lines, - ImmutableList offsets, - ImmutableList lengths, - boolean aosp, - boolean version, - boolean help, - boolean stdin, - boolean fixImportsOnly, - boolean sortImports, - boolean removeUnusedImports, - boolean dryRun, - boolean setExitIfChanged, - Optional assumeFilename, - boolean reflowLongStrings, - boolean formatJavadoc) { - this.files = files; - this.inPlace = inPlace; - this.lines = lines; - this.offsets = offsets; - this.lengths = lengths; - this.aosp = aosp; - this.version = version; - this.help = help; - this.stdin = stdin; - this.fixImportsOnly = fixImportsOnly; - this.sortImports = sortImports; - this.removeUnusedImports = removeUnusedImports; - this.dryRun = dryRun; - this.setExitIfChanged = setExitIfChanged; - this.assumeFilename = assumeFilename; - this.reflowLongStrings = reflowLongStrings; - this.formatJavadoc = formatJavadoc; - } - - /** The files to format. */ - ImmutableList files() { - return files; - } - - /** Format files in place. */ - boolean inPlace() { - return inPlace; - } - - /** Line ranges to format. */ - ImmutableRangeSet lines() { - return lines; - } - - /** Character offsets for partial formatting, paired with {@code lengths}. */ - ImmutableList offsets() { - return offsets; - } - - /** Partial formatting region lengths, paired with {@code offsets}. */ - ImmutableList lengths() { - return lengths; - } - - /** Use AOSP style instead of Google Style (4-space indentation). */ - boolean aosp() { - return aosp; - } - - /** Print the version. */ - boolean version() { - return version; - } - - /** Print usage information. */ - boolean help() { - return help; - } - - /** Format input from stdin. */ - boolean stdin() { - return stdin; - } - - /** Fix imports, but do no formatting. */ - boolean fixImportsOnly() { - return fixImportsOnly; - } - - /** Sort imports. */ - boolean sortImports() { - return sortImports; - } - - /** Remove unused imports. */ - boolean removeUnusedImports() { - return removeUnusedImports; - } - - /** - * Print the paths of the files whose contents would change if the formatter were run normally. - */ - boolean dryRun() { - return dryRun; - } - - /** Return exit code 1 if there are any formatting changes. */ - boolean setExitIfChanged() { - return setExitIfChanged; - } - - /** Return the name to use for diagnostics when formatting standard input. */ - Optional assumeFilename() { - return assumeFilename; - } - - boolean reflowLongStrings() { - return reflowLongStrings; - } +record CommandLineOptions( + ImmutableList files, + boolean inPlace, + ImmutableRangeSet lines, + ImmutableList offsets, + ImmutableList lengths, + boolean aosp, + boolean version, + boolean help, + boolean stdin, + boolean fixImportsOnly, + boolean sortImports, + boolean removeUnusedImports, + boolean dryRun, + boolean setExitIfChanged, + Optional assumeFilename, + boolean reflowLongStrings, + boolean formatJavadoc) { /** Returns true if partial formatting was selected. */ boolean isSelection() { return !lines().isEmpty() || !offsets().isEmpty() || !lengths().isEmpty(); } - boolean formatJavadoc() { - return formatJavadoc; - } - static Builder builder() { - return new Builder(); + return new AutoBuilder_CommandLineOptions_Builder() + .sortImports(true) + .removeUnusedImports(true) + .reflowLongStrings(true) + .formatJavadoc(true) + .aosp(false) + .version(false) + .help(false) + .stdin(false) + .fixImportsOnly(false) + .dryRun(false) + .setExitIfChanged(false) + .inPlace(false); } - static class Builder { + @AutoBuilder + interface Builder { - private final ImmutableList.Builder files = ImmutableList.builder(); - private final RangeSet lines = TreeRangeSet.create(); - private final ImmutableList.Builder offsets = ImmutableList.builder(); - private final ImmutableList.Builder lengths = ImmutableList.builder(); - private boolean inPlace = false; - private boolean aosp = false; - private boolean version = false; - private boolean help = false; - private boolean stdin = false; - private boolean fixImportsOnly = false; - private boolean sortImports = true; - private boolean removeUnusedImports = true; - private boolean dryRun = false; - private boolean setExitIfChanged = false; - private Optional assumeFilename = Optional.empty(); - private boolean reflowLongStrings = true; - private boolean formatJavadoc = true; + ImmutableList.Builder filesBuilder(); - ImmutableList.Builder filesBuilder() { - return files; - } + Builder inPlace(boolean inPlace); - Builder inPlace(boolean inPlace) { - this.inPlace = inPlace; - return this; - } + Builder lines(ImmutableRangeSet lines); - RangeSet linesBuilder() { - return lines; - } + ImmutableList.Builder offsetsBuilder(); - Builder addOffset(Integer offset) { - offsets.add(offset); + @CanIgnoreReturnValue + default Builder addOffset(Integer offset) { + offsetsBuilder().add(offset); return this; } - Builder addLength(Integer length) { - lengths.add(length); - return this; - } + ImmutableList.Builder lengthsBuilder(); - Builder aosp(boolean aosp) { - this.aosp = aosp; + @CanIgnoreReturnValue + default Builder addLength(Integer length) { + lengthsBuilder().add(length); return this; } - Builder version(boolean version) { - this.version = version; - return this; - } + Builder aosp(boolean aosp); - Builder help(boolean help) { - this.help = help; - return this; - } + Builder version(boolean version); - Builder stdin(boolean stdin) { - this.stdin = stdin; - return this; - } + Builder help(boolean help); - Builder fixImportsOnly(boolean fixImportsOnly) { - this.fixImportsOnly = fixImportsOnly; - return this; - } + Builder stdin(boolean stdin); - Builder sortImports(boolean sortImports) { - this.sortImports = sortImports; - return this; - } + Builder fixImportsOnly(boolean fixImportsOnly); - Builder removeUnusedImports(boolean removeUnusedImports) { - this.removeUnusedImports = removeUnusedImports; - return this; - } + Builder sortImports(boolean sortImports); - Builder dryRun(boolean dryRun) { - this.dryRun = dryRun; - return this; - } + Builder removeUnusedImports(boolean removeUnusedImports); - Builder setExitIfChanged(boolean setExitIfChanged) { - this.setExitIfChanged = setExitIfChanged; - return this; - } + Builder dryRun(boolean dryRun); - Builder assumeFilename(String assumeFilename) { - this.assumeFilename = Optional.of(assumeFilename); - return this; - } + Builder setExitIfChanged(boolean setExitIfChanged); - Builder reflowLongStrings(boolean reflowLongStrings) { - this.reflowLongStrings = reflowLongStrings; - return this; - } + Builder assumeFilename(String assumeFilename); - Builder formatJavadoc(boolean formatJavadoc) { - this.formatJavadoc = formatJavadoc; - return this; - } + Builder reflowLongStrings(boolean reflowLongStrings); - CommandLineOptions build() { - return new CommandLineOptions( - files.build(), - inPlace, - ImmutableRangeSet.copyOf(lines), - offsets.build(), - lengths.build(), - aosp, - version, - help, - stdin, - fixImportsOnly, - sortImports, - removeUnusedImports, - dryRun, - setExitIfChanged, - assumeFilename, - reflowLongStrings, - formatJavadoc); - } + Builder formatJavadoc(boolean formatJavadoc); + + CommandLineOptions build(); } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java index 52a5e05d4..098a263f4 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java @@ -18,8 +18,10 @@ import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableRangeSet; import com.google.common.collect.Range; import com.google.common.collect.RangeSet; +import com.google.common.collect.TreeRangeSet; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.file.Files; @@ -43,6 +45,9 @@ static CommandLineOptions parse(Iterable options) { List expandedOptions = new ArrayList<>(); expandParamsFiles(options, expandedOptions); Iterator it = expandedOptions.iterator(); + // Accumulate the ranges in a mutable builder to merge overlapping ranges, + // which ImmutableRangeSet doesn't support. + RangeSet linesBuilder = TreeRangeSet.create(); while (it.hasNext()) { String option = it.next(); if (!option.startsWith("-")) { @@ -71,7 +76,7 @@ static CommandLineOptions parse(Iterable options) { case "-lines": case "--line": case "-line": - parseRangeSet(optionsBuilder.linesBuilder(), getValue(flag, it, value)); + parseRangeSet(linesBuilder, getValue(flag, it, value)); break; case "--offset": case "-offset": @@ -129,6 +134,7 @@ static CommandLineOptions parse(Iterable options) { throw new IllegalArgumentException("unexpected flag: " + flag); } } + optionsBuilder.lines(ImmutableRangeSet.copyOf(linesBuilder)); return optionsBuilder.build(); } From 4c91240f69bc4982c5c3908087dfccdbcb93e5aa Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 8 Apr 2025 17:40:47 -0700 Subject: [PATCH 345/379] Internal change PiperOrigin-RevId: 745356200 --- .../java/CommandLineOptions.java | 5 ++- .../java/CommandLineOptionsParser.java | 35 ++++++++----------- .../google/googlejavaformat/java/Main.java | 11 +++--- .../java/CommandLineFlagsTest.java | 7 +++- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java index e794a1815..0421c5574 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java @@ -57,7 +57,8 @@ record CommandLineOptions( boolean setExitIfChanged, Optional assumeFilename, boolean reflowLongStrings, - boolean formatJavadoc) { + boolean formatJavadoc, + Optional profile) { /** Returns true if partial formatting was selected. */ boolean isSelection() { @@ -129,6 +130,8 @@ default Builder addLength(Integer length) { Builder formatJavadoc(boolean formatJavadoc); + Builder profile(String profile); + CommandLineOptions build(); } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java index 098a263f4..1128fbf13 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java @@ -14,7 +14,6 @@ package com.google.googlejavaformat.java; -import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; @@ -26,7 +25,6 @@ import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -64,72 +62,67 @@ static CommandLineOptions parse(Iterable options) { flag = option; value = null; } + flag = flag.startsWith("--") ? flag.substring(1) : flag; // NOTE: update usage information in UsageException when new flags are added switch (flag) { case "-i": case "-r": case "-replace": - case "--replace": optionsBuilder.inPlace(true); break; - case "--lines": case "-lines": - case "--line": case "-line": parseRangeSet(linesBuilder, getValue(flag, it, value)); break; - case "--offset": case "-offset": optionsBuilder.addOffset(parseInteger(it, flag, value)); break; - case "--length": case "-length": optionsBuilder.addLength(parseInteger(it, flag, value)); break; - case "--aosp": case "-aosp": case "-a": optionsBuilder.aosp(true); break; - case "--version": case "-version": case "-v": optionsBuilder.version(true); break; - case "--help": case "-help": case "-h": optionsBuilder.help(true); break; - case "--fix-imports-only": + case "-fix-imports-only": optionsBuilder.fixImportsOnly(true); break; - case "--skip-sorting-imports": + case "-skip-sorting-imports": optionsBuilder.sortImports(false); break; - case "--skip-removing-unused-imports": + case "-skip-removing-unused-imports": optionsBuilder.removeUnusedImports(false); break; - case "--skip-reflowing-long-strings": + case "-skip-reflowing-long-strings": optionsBuilder.reflowLongStrings(false); break; - case "--skip-javadoc-formatting": + case "-skip-javadoc-formatting": optionsBuilder.formatJavadoc(false); break; case "-": optionsBuilder.stdin(true); break; case "-n": - case "--dry-run": + case "-dry-run": optionsBuilder.dryRun(true); break; - case "--set-exit-if-changed": + case "-set-exit-if-changed": optionsBuilder.setExitIfChanged(true); break; case "-assume-filename": - case "--assume-filename": optionsBuilder.assumeFilename(getValue(flag, it, value)); break; + case "-profile": + optionsBuilder.profile(getValue(flag, it, value)); + break; default: throw new IllegalArgumentException("unexpected flag: " + flag); } @@ -202,9 +195,9 @@ private static void expandParamsFiles(Iterable args, List expand } else if (arg.startsWith("@@")) { expanded.add(arg.substring(1)); } else { - Path path = Paths.get(arg.substring(1)); + Path path = Path.of(arg.substring(1)); try { - String sequence = new String(Files.readAllBytes(path), UTF_8); + String sequence = Files.readString(path); expandParamsFiles(ARG_SPLITTER.split(sequence), expanded); } catch (IOException e) { throw new UncheckedIOException(path + ": could not read file: " + e.getMessage(), e); @@ -212,4 +205,6 @@ private static void expandParamsFiles(Iterable args, List expand } } } + + private CommandLineOptionsParser() {} } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index f1affa74d..b98d5c298 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -108,14 +108,14 @@ static int main(InputStream in, PrintWriter out, PrintWriter err, String... args */ public int format(String... args) throws UsageException { CommandLineOptions parameters = processArgs(args); + return format(parameters); + } + + int format(CommandLineOptions parameters) { if (parameters.version()) { errWriter.println(versionString()); return 0; } - if (parameters.help()) { - throw new UsageException(); - } - JavaFormatterOptions options = JavaFormatterOptions.builder() .style(parameters.aosp() ? Style.AOSP : Style.GOOGLE) @@ -278,6 +278,9 @@ public static CommandLineOptions processArgs(String... args) throws UsageExcepti if (parameters.dryRun() && parameters.inPlace()) { throw new UsageException("cannot use --dry-run and --in-place at the same time"); } + if (parameters.help()) { + throw new UsageException(); + } return parameters; } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java b/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java index 928ce0078..cde7a17dc 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java @@ -107,7 +107,12 @@ public void numberOfOffsetsMustMatchNumberOfLengths() throws UsageException { public void noFilesToFormatRequiresEitherHelpOrVersion() throws UsageException { Main.processArgs("-version"); - Main.processArgs("-help"); + try { + Main.processArgs("-help"); + fail(); + } catch (UsageException e) { + // expected + } try { Main.processArgs(); From 8cf65c7f7d21992ab9c0292f712405fd45e71eeb Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Wed, 9 Apr 2025 03:54:52 -0700 Subject: [PATCH 346/379] Automated rollback of commit 4c91240f69bc4982c5c3908087dfccdbcb93e5aa. *** Reason for rollback *** Breaks test/protobuf.msan [failure]([] *** Original change description *** Internal change PiperOrigin-RevId: 745520292 --- .../java/CommandLineOptions.java | 5 +-- .../java/CommandLineOptionsParser.java | 35 +++++++++++-------- .../google/googlejavaformat/java/Main.java | 11 +++--- .../java/CommandLineFlagsTest.java | 7 +--- 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java index 0421c5574..e794a1815 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptions.java @@ -57,8 +57,7 @@ record CommandLineOptions( boolean setExitIfChanged, Optional assumeFilename, boolean reflowLongStrings, - boolean formatJavadoc, - Optional profile) { + boolean formatJavadoc) { /** Returns true if partial formatting was selected. */ boolean isSelection() { @@ -130,8 +129,6 @@ default Builder addLength(Integer length) { Builder formatJavadoc(boolean formatJavadoc); - Builder profile(String profile); - CommandLineOptions build(); } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java index 1128fbf13..098a263f4 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java @@ -14,6 +14,7 @@ package com.google.googlejavaformat.java; +import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; @@ -25,6 +26,7 @@ import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -62,67 +64,72 @@ static CommandLineOptions parse(Iterable options) { flag = option; value = null; } - flag = flag.startsWith("--") ? flag.substring(1) : flag; // NOTE: update usage information in UsageException when new flags are added switch (flag) { case "-i": case "-r": case "-replace": + case "--replace": optionsBuilder.inPlace(true); break; + case "--lines": case "-lines": + case "--line": case "-line": parseRangeSet(linesBuilder, getValue(flag, it, value)); break; + case "--offset": case "-offset": optionsBuilder.addOffset(parseInteger(it, flag, value)); break; + case "--length": case "-length": optionsBuilder.addLength(parseInteger(it, flag, value)); break; + case "--aosp": case "-aosp": case "-a": optionsBuilder.aosp(true); break; + case "--version": case "-version": case "-v": optionsBuilder.version(true); break; + case "--help": case "-help": case "-h": optionsBuilder.help(true); break; - case "-fix-imports-only": + case "--fix-imports-only": optionsBuilder.fixImportsOnly(true); break; - case "-skip-sorting-imports": + case "--skip-sorting-imports": optionsBuilder.sortImports(false); break; - case "-skip-removing-unused-imports": + case "--skip-removing-unused-imports": optionsBuilder.removeUnusedImports(false); break; - case "-skip-reflowing-long-strings": + case "--skip-reflowing-long-strings": optionsBuilder.reflowLongStrings(false); break; - case "-skip-javadoc-formatting": + case "--skip-javadoc-formatting": optionsBuilder.formatJavadoc(false); break; case "-": optionsBuilder.stdin(true); break; case "-n": - case "-dry-run": + case "--dry-run": optionsBuilder.dryRun(true); break; - case "-set-exit-if-changed": + case "--set-exit-if-changed": optionsBuilder.setExitIfChanged(true); break; case "-assume-filename": + case "--assume-filename": optionsBuilder.assumeFilename(getValue(flag, it, value)); break; - case "-profile": - optionsBuilder.profile(getValue(flag, it, value)); - break; default: throw new IllegalArgumentException("unexpected flag: " + flag); } @@ -195,9 +202,9 @@ private static void expandParamsFiles(Iterable args, List expand } else if (arg.startsWith("@@")) { expanded.add(arg.substring(1)); } else { - Path path = Path.of(arg.substring(1)); + Path path = Paths.get(arg.substring(1)); try { - String sequence = Files.readString(path); + String sequence = new String(Files.readAllBytes(path), UTF_8); expandParamsFiles(ARG_SPLITTER.split(sequence), expanded); } catch (IOException e) { throw new UncheckedIOException(path + ": could not read file: " + e.getMessage(), e); @@ -205,6 +212,4 @@ private static void expandParamsFiles(Iterable args, List expand } } } - - private CommandLineOptionsParser() {} } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Main.java b/core/src/main/java/com/google/googlejavaformat/java/Main.java index b98d5c298..f1affa74d 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Main.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Main.java @@ -108,14 +108,14 @@ static int main(InputStream in, PrintWriter out, PrintWriter err, String... args */ public int format(String... args) throws UsageException { CommandLineOptions parameters = processArgs(args); - return format(parameters); - } - - int format(CommandLineOptions parameters) { if (parameters.version()) { errWriter.println(versionString()); return 0; } + if (parameters.help()) { + throw new UsageException(); + } + JavaFormatterOptions options = JavaFormatterOptions.builder() .style(parameters.aosp() ? Style.AOSP : Style.GOOGLE) @@ -278,9 +278,6 @@ public static CommandLineOptions processArgs(String... args) throws UsageExcepti if (parameters.dryRun() && parameters.inPlace()) { throw new UsageException("cannot use --dry-run and --in-place at the same time"); } - if (parameters.help()) { - throw new UsageException(); - } return parameters; } } diff --git a/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java b/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java index cde7a17dc..928ce0078 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/CommandLineFlagsTest.java @@ -107,12 +107,7 @@ public void numberOfOffsetsMustMatchNumberOfLengths() throws UsageException { public void noFilesToFormatRequiresEitherHelpOrVersion() throws UsageException { Main.processArgs("-version"); - try { - Main.processArgs("-help"); - fail(); - } catch (UsageException e) { - // expected - } + Main.processArgs("-help"); try { Main.processArgs(); From 6f46e8aa66914a23bcd55092fd826b15a08553ee Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Mon, 14 Apr 2025 09:45:37 -0700 Subject: [PATCH 347/379] Work around a JDK-head failure. The return type here changed from `Queue` to `List`. PiperOrigin-RevId: 747457032 --- .../googlejavaformat/java/JavaInput.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 01c617776..6cf7690c6 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -37,10 +37,12 @@ import com.sun.tools.javac.parser.Tokens.TokenKind; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.JCDiagnostic; import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler; import com.sun.tools.javac.util.Options; import java.io.IOException; +import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; import java.util.Collection; @@ -53,6 +55,7 @@ import javax.tools.JavaFileObject; import javax.tools.JavaFileObject.Kind; import javax.tools.SimpleJavaFileObject; +import org.jspecify.annotations.Nullable; /** {@code JavaInput} extends {@link Input} to represent a Java input document. */ public final class JavaInput extends Input { @@ -364,7 +367,15 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept }); DeferredDiagnosticHandler diagnostics = new DeferredDiagnosticHandler(log); ImmutableList rawToks = JavacTokens.getTokens(text, context, stopTokens); - if (diagnostics.getDiagnostics().stream().anyMatch(d -> d.getKind() == Diagnostic.Kind.ERROR)) { + Collection ds; + try { + @SuppressWarnings("unchecked") + var extraLocalForSuppression = (Collection) GET_DIAGNOSTICS.invoke(diagnostics); + ds = extraLocalForSuppression; + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + if (ds.stream().anyMatch(d -> d.getKind() == Diagnostic.Kind.ERROR)) { return ImmutableList.of(new Tok(0, "", "", 0, 0, true, null)); // EOF } int kN = 0; @@ -471,6 +482,16 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept return ImmutableList.copyOf(toks); } + private static final Method GET_DIAGNOSTICS = getGetDiagnostics(); + + private static @Nullable Method getGetDiagnostics() { + try { + return DeferredDiagnosticHandler.class.getMethod("getDiagnostics"); + } catch (NoSuchMethodException e) { + throw new LinkageError(e.getMessage(), e); + } + } + private static int updateColumn(int columnI, String originalTokText) { Integer last = Iterators.getLast(Newlines.lineOffsetIterator(originalTokText)); if (last > 0) { From 96f114c37c02fcfdfa0d4bc25b6e122d11afc485 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 14 Apr 2025 12:11:28 -0700 Subject: [PATCH 348/379] Prepare for an incompatible change to Log diagnostic handlers DeferredDiagnosticHandler changes from a static to inner class in https://github.com/openjdk/jdk/commit/4890b74c048a1472b87687294c316ecfb324e4ba, see also b/410556169 Follow-up to https://github.com/google/google-java-format/commit/6f46e8aa66914a23bcd55092fd826b15a08553ee PiperOrigin-RevId: 747516421 --- .../googlejavaformat/java/JavaInput.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index 6cf7690c6..c59e74c6c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -42,6 +42,7 @@ import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler; import com.sun.tools.javac.util.Options; import java.io.IOException; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URI; import java.util.ArrayList; @@ -365,7 +366,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept return text; } }); - DeferredDiagnosticHandler diagnostics = new DeferredDiagnosticHandler(log); + DeferredDiagnosticHandler diagnostics = deferredDiagnosticHandler(log); ImmutableList rawToks = JavacTokens.getTokens(text, context, stopTokens); Collection ds; try { @@ -482,6 +483,29 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept return ImmutableList.copyOf(toks); } + private static final Constructor + DEFERRED_DIAGNOSTIC_HANDLER_CONSTRUCTOR = getDeferredDiagnosticHandlerConstructor(); + + // Depending on the JDK version, we might have a static class whose constructor has an explicit + // Log parameter, or an inner class whose constructor has an *implicit* Log parameter. They are + // different at the source level, but look the same to reflection. + + private static Constructor getDeferredDiagnosticHandlerConstructor() { + try { + return DeferredDiagnosticHandler.class.getConstructor(Log.class); + } catch (NoSuchMethodException e) { + throw new LinkageError(e.getMessage(), e); + } + } + + private static DeferredDiagnosticHandler deferredDiagnosticHandler(Log log) { + try { + return DEFERRED_DIAGNOSTIC_HANDLER_CONSTRUCTOR.newInstance(log); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } + private static final Method GET_DIAGNOSTICS = getGetDiagnostics(); private static @Nullable Method getGetDiagnostics() { From 15021075a5bf97c3783c09b6270e273c614704c7 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 6 May 2025 16:30:39 -0700 Subject: [PATCH 349/379] Stop using ubuntu 20.04 See https://github.com/actions/runner-images/issues/11101 --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1db537e39..5fdbf183e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -91,10 +91,10 @@ jobs: # Use "oldest" available ubuntu-* instead of -latest, # see https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories; # due to https://github.com/google/google-java-format/issues/1072. - os: [ubuntu-20.04, ubuntu-22.04-arm, macos-latest, windows-latest] + os: [ubuntu-22.04, ubuntu-22.04-arm, macos-latest, windows-latest] env: # NB: Must keep the keys in this inline JSON below in line with the os: above! - SUFFIX: ${{fromJson('{"ubuntu-20.04":"linux-x86-64", "ubuntu-22.04-arm":"linux-arm64", "macos-latest":"darwin-arm64", "windows-latest":"windows-x86-64"}')[matrix.os]}} + SUFFIX: ${{fromJson('{"ubuntu-22.04":"linux-x86-64", "ubuntu-22.04-arm":"linux-arm64", "macos-latest":"darwin-arm64", "windows-latest":"windows-x86-64"}')[matrix.os]}} EXTENSION: ${{ matrix.os == 'windows-latest' && '.exe' || '' }} steps: - name: "Check out repository" From 7193ce9708181886f4c26dbc16edbf170f4748c0 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Wed, 7 May 2025 09:18:01 -0700 Subject: [PATCH 350/379] Update the IntelliJ plugin to gjf 1.27.0. PiperOrigin-RevId: 755882849 --- idea_plugin/build.gradle.kts | 5 ++--- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 760a8b94c..f2d2c2200 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -18,7 +18,7 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases plugins { - id("org.jetbrains.intellij.platform") version "2.4.0" + id("org.jetbrains.intellij.platform") version "2.5.0" } repositories { @@ -30,7 +30,7 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.26.0" +val googleJavaFormatVersion = "1.27.0" java { sourceCompatibility = JavaVersion.VERSION_17 @@ -81,7 +81,6 @@ dependencies { intellijPlatform { intellijIdeaCommunity("2022.3") bundledPlugin("com.intellij.java") - instrumentationTools() testFramework(TestFrameworkType.Plugin.Java) } implementation("com.google.googlejavaformat:google-java-format:${googleJavaFormatVersion}") diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 28e6d3e35..404f59dbf 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +

        1.27.0.0
        +
        Updated to use google-java-format 1.27.0.
        1.26.0.0
        Updated to use google-java-format 1.26.0.
        1.25.2.0
        From 61eabd62d6a461c27621ebc77240345e40fb60b4 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 7 May 2025 12:49:03 -0700 Subject: [PATCH 351/379] Stop using ubuntu 20.04 See actions/runner-images#11101 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e64353d64..8ce223eba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,7 +80,7 @@ jobs: # Use "oldest" available ubuntu-* instead of -latest, # see https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories; # due to https://github.com/google/google-java-format/issues/1072. - os: [ubuntu-20.04, macos-latest, windows-latest] + os: [ubuntu-22.04, macos-latest, windows-latest] runs-on: ${{ matrix.os }} continue-on-error: true steps: From 4c96ea43a3ff9079f67c273f1f954dcda326d54f Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 9 Jul 2025 13:39:52 -0700 Subject: [PATCH 352/379] Update release.yml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5fdbf183e..1639d1e94 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,7 +36,7 @@ jobs: java-version: 21 distribution: "zulu" cache: "maven" - server-id: sonatype-nexus-staging + server-id: central server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD gpg-private-key: ${{ secrets.GPG_SIGNING_KEY }} From b6ce0fab7ecc51d1447d9b2c3074f3adf8543e3e Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 9 Jul 2025 14:00:06 -0700 Subject: [PATCH 353/379] Migrate to Sonatype Maven Central releases PiperOrigin-RevId: 781199945 --- pom.xml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 46ccad473..10e613678 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,7 @@ 1.0.1 3.6.3 3.2.1 + 0.8.0 @@ -301,14 +302,8 @@ sonatype-nexus-snapshots - Sonatype Nexus Snapshots - https://oss.sonatype.org/content/repositories/snapshots/ + https://central.sonatype.com/repository/maven-snapshots/ - - sonatype-nexus-staging - Nexus Release Repository - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - @@ -316,6 +311,15 @@ sonatype-oss-release + + org.sonatype.central + central-publishing-maven-plugin + ${central-publishing-maven-plugin.version} + true + + central + + org.apache.maven.plugins maven-source-plugin From e895346096766095ea16a65502b3f5a160548c45 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Thu, 10 Jul 2025 06:49:19 -0700 Subject: [PATCH 354/379] Update the IntelliJ plugin to gjf 1.28.0. PiperOrigin-RevId: 781514043 --- idea_plugin/build.gradle.kts | 4 ++-- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index f2d2c2200..459582e42 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -18,7 +18,7 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases plugins { - id("org.jetbrains.intellij.platform") version "2.5.0" + id("org.jetbrains.intellij.platform") version "2.6.0" } repositories { @@ -30,7 +30,7 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.27.0" +val googleJavaFormatVersion = "1.28.0" java { sourceCompatibility = JavaVersion.VERSION_17 diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 404f59dbf..2575a6cf4 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
        1.28.0.0
        +
        Updated to use google-java-format 1.28.0.
        1.27.0.0
        Updated to use google-java-format 1.27.0.
        1.26.0.0
        From bc9a57807705afa45bf09c08427553c8a06201d3 Mon Sep 17 00:00:00 2001 From: Suraj Devatha <42767118+surajdm123@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:17:34 -0700 Subject: [PATCH 355/379] Added JUnit Test Cases for Replacement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Changes This PR adds the missing unit test case for Replacement. **Before:** Screenshot 2025-07-16 at 10 26 05 PM **After:** Screenshot 2025-07-16 at 10 24 41 PM ### Test Plan > mvn -Dtest=ReplacementTest test ``` ... [INFO] Running com.google.googlejavaformat.java.ReplacementTest [INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.068 s - in com.google.googlejavaformat.java.ReplacementTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ ``` ---- > mvn test ``` [INFO] Results: [INFO] [INFO] Tests run: 1533, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 12.168 s [INFO] Finished at: 2025-07-16T22:30:47-07:00 [INFO] ------------------------------------------------------------------------ ``` ### Next Steps - Add more missing test cases to make this codebase more resilient. Fixes #1268 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1268 from surajdm123:add-test 1bad87cbc8f513a475d9917ec0d7615c550c6ddb PiperOrigin-RevId: 784313467 --- .../java/ReplacementTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 core/src/test/java/com/google/googlejavaformat/java/ReplacementTest.java diff --git a/core/src/test/java/com/google/googlejavaformat/java/ReplacementTest.java b/core/src/test/java/com/google/googlejavaformat/java/ReplacementTest.java new file mode 100644 index 000000000..177af9f1f --- /dev/null +++ b/core/src/test/java/com/google/googlejavaformat/java/ReplacementTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2025 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.common.collect.Range; +import com.google.common.testing.EqualsTester; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** {@link Replacement}Test */ +@RunWith(JUnit4.class) +public class ReplacementTest { + + @Test + public void testCreateWithValidInput() { + Replacement replacement = Replacement.create(3, 7, "replacementText"); + assertThat(replacement.getReplaceRange()).isEqualTo(Range.closedOpen(3, 7)); + assertThat(replacement.getReplacementString()).isEqualTo("replacementText"); + } + + @Test + public void invalidReplacementRange() { + assertThrows(IllegalArgumentException.class, () -> Replacement.create(-1, 5, "text")); + assertThrows(IllegalArgumentException.class, () -> Replacement.create(10, 5, "text")); + } + + @Test + public void testEqualsAndHashCode() { + new EqualsTester() + .addEqualityGroup(Replacement.create(0, 4, "abc"), Replacement.create(0, 4, "abc")) + .addEqualityGroup(Replacement.create(1, 4, "abc")) + .addEqualityGroup(Replacement.create(0, 4, "def")) + .testEquals(); + } +} From 13ce22de4b8b45f314d1d1f61845ef2ba182583a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 18 Jul 2025 12:05:33 -0700 Subject: [PATCH 356/379] Update Error Prone version PiperOrigin-RevId: 784658430 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 10e613678..eca5362d7 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 32.1.3-jre 1.4.0 1.0.0 - 2.37.0 + 2.40.0 1.9 1.0.1 3.6.3 From 4943dbab94348fd9ad592e1b608908710b669fbc Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Fri, 19 Sep 2025 03:12:09 -0700 Subject: [PATCH 357/379] Remove a bunch of `assume()`s which are now always true. PiperOrigin-RevId: 808961882 --- .../com/google/googlejavaformat/java/ModifierOrdererTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/test/java/com/google/googlejavaformat/java/ModifierOrdererTest.java b/core/src/test/java/com/google/googlejavaformat/java/ModifierOrdererTest.java index 0f01e9d3f..013d14358 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/ModifierOrdererTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/ModifierOrdererTest.java @@ -17,7 +17,6 @@ package com.google.googlejavaformat.java; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.TruthJUnit.assume; import com.google.common.base.Joiner; import com.google.common.collect.Range; @@ -107,7 +106,6 @@ public void whitespace() throws FormatterException { @Test public void sealedClass() throws FormatterException { - assume().that(Runtime.version().feature()).isAtLeast(16); assertThat(ModifierOrderer.reorderModifiers("non-sealed sealed public").getText()) .isEqualTo("public sealed non-sealed"); } From b3c739399568ac43ca787891a04e03ddcf8f5860 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sat, 20 Sep 2025 20:48:36 -0700 Subject: [PATCH 358/379] Update JDK versions in CI --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ce223eba..37779bd85 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,16 +29,16 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - java: [21, 17] + java: [25, 21] experimental: [false] include: # Only test on MacOS and Windows with a single recent JDK to avoid a # combinatorial explosion of test configurations. - os: macos-latest - java: 21 + java: 25 experimental: false - os: windows-latest - java: 21 + java: 25 experimental: false - os: ubuntu-latest java: EA From f4aaf0ff570c0a76d3697c00375a9768802372e8 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sun, 21 Sep 2025 08:21:20 -0700 Subject: [PATCH 359/379] Upgrade Error Prone dependency https://github.com/google/google-java-format/issues/1281 PiperOrigin-RevId: 809702803 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eca5362d7..f3668d649 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 32.1.3-jre 1.4.0 1.0.0 - 2.40.0 + 2.42.0 1.9 1.0.1 3.6.3 From 7e724223102ca5fa5b38727aeb736f0cd8f8af8c Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 25 Sep 2025 07:51:08 -0700 Subject: [PATCH 360/379] Merge Java21InputAstVisitor into JavaInputAstVisitor In preparation for raising the minimum supported JDK version to JDK 21. PiperOrigin-RevId: 811349632 --- core/pom.xml | 25 ---- .../googlejavaformat/java/Formatter.java | 21 +--- .../java/JavaInputAstVisitor.java | 65 ++++++++++- .../java/java21/Java21InputAstVisitor.java | 107 ------------------ .../META-INF/native-image/reflect-config.json | 9 -- 5 files changed, 60 insertions(+), 167 deletions(-) delete mode 100644 core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java diff --git a/core/pom.xml b/core/pom.xml index 5b6bbb4d7..3b106cf71 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -223,31 +223,6 @@
        - - jdk17 - - [17,21) - - - - - org.apache.maven.plugins - maven-compiler-plugin - - - **/Java21InputAstVisitor.java - - - - - maven-javadoc-plugin - - com.google.googlejavaformat.java.java21 - - - - - native diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index e3b2b3235..5d9ac76ad 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -150,14 +150,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept } OpsBuilder builder = new OpsBuilder(javaInput, javaOutput); // Output the compilation unit. - JavaInputAstVisitor visitor; - if (Runtime.version().feature() >= 21) { - visitor = - createVisitor( - "com.google.googlejavaformat.java.java21.Java21InputAstVisitor", builder, options); - } else { - visitor = new JavaInputAstVisitor(builder, options.indentationMultiplier()); - } + JavaInputAstVisitor visitor = new JavaInputAstVisitor(builder, options.indentationMultiplier()); visitor.scan(unit, null); builder.sync(javaInput.getText().length()); builder.drain(); @@ -167,18 +160,6 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept javaOutput.flush(); } - private static JavaInputAstVisitor createVisitor( - final String className, final OpsBuilder builder, final JavaFormatterOptions options) { - try { - return Class.forName(className) - .asSubclass(JavaInputAstVisitor.class) - .getConstructor(OpsBuilder.class, int.class) - .newInstance(builder, options.indentationMultiplier()); - } catch (ReflectiveOperationException e) { - throw new LinkageError(e.getMessage(), e); - } - } - static boolean errorDiagnostic(Diagnostic input) { if (input.getKind() != Diagnostic.Kind.ERROR) { return false; diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index f21f86a5c..1336ad0e1 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -97,7 +97,10 @@ import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.CompoundAssignmentTree; import com.sun.source.tree.ConditionalExpressionTree; +import com.sun.source.tree.ConstantCaseLabelTree; import com.sun.source.tree.ContinueTree; +import com.sun.source.tree.DeconstructionPatternTree; +import com.sun.source.tree.DefaultCaseLabelTree; import com.sun.source.tree.DirectiveTree; import com.sun.source.tree.DoWhileLoopTree; import com.sun.source.tree.EmptyStatementTree; @@ -125,6 +128,8 @@ import com.sun.source.tree.OpensTree; import com.sun.source.tree.ParameterizedTypeTree; import com.sun.source.tree.ParenthesizedTree; +import com.sun.source.tree.PatternCaseLabelTree; +import com.sun.source.tree.PatternTree; import com.sun.source.tree.PrimitiveTypeTree; import com.sun.source.tree.ProvidesTree; import com.sun.source.tree.RequiresTree; @@ -359,6 +364,12 @@ private boolean inExpression() { @Override public Void scan(Tree tree, Void unused) { + // Pre-visit AST for preview features, since com.sun.source.tree.AnyPattern can't be + // accessed directly without --enable-preview. + if (tree instanceof JCTree.JCAnyPattern) { + visitJcAnyPattern((JCTree.JCAnyPattern) tree); + return null; + } inExpression.addLast(tree instanceof ExpressionTree || inExpression.peekLast()); int previous = builder.depth(); try { @@ -2001,7 +2012,7 @@ public Void visitCase(CaseTree node, Void unused) { builder.close(); } - final ExpressionTree guard = getGuard(node); + final ExpressionTree guard = node.getGuard(); if (guard != null) { builder.breakToFill(" "); token("when"); @@ -2041,10 +2052,6 @@ public Void visitCase(CaseTree node, Void unused) { return null; } - protected ExpressionTree getGuard(final CaseTree node) { - return null; - } - @Override public Void visitSwitch(SwitchTree node, Void unused) { sync(node); @@ -3775,7 +3782,11 @@ protected int declareOne( } protected void variableName(Name name) { - visit(name); + if (name.isEmpty()) { + token("_"); + } else { + visit(name); + } } private void maybeAddDims(Deque> annotations) { @@ -4153,4 +4164,46 @@ public Void visitSwitchExpression(SwitchExpressionTree node, Void aVoid) { visitSwitch(node.getExpression(), node.getCases()); return null; } + + @Override + public Void visitDefaultCaseLabel(DefaultCaseLabelTree node, Void unused) { + token("default"); + return null; + } + + @Override + public Void visitPatternCaseLabel(PatternCaseLabelTree node, Void unused) { + scan(node.getPattern(), null); + return null; + } + + @Override + public Void visitConstantCaseLabel(ConstantCaseLabelTree node, Void aVoid) { + scan(node.getConstantExpression(), null); + return null; + } + + @Override + public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unused) { + scan(node.getDeconstructor(), null); + builder.open(plusFour); + token("("); + builder.breakOp(); + boolean afterFirstToken = false; + for (PatternTree pattern : node.getNestedPatterns()) { + if (afterFirstToken) { + token(","); + builder.breakOp(" "); + } + afterFirstToken = true; + scan(pattern, null); + } + builder.close(); + token(")"); + return null; + } + + private void visitJcAnyPattern(JCTree.JCAnyPattern unused) { + token("_"); + } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java deleted file mode 100644 index 029da8e04..000000000 --- a/core/src/main/java/com/google/googlejavaformat/java/java21/Java21InputAstVisitor.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2023 The google-java-format Authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.googlejavaformat.java.java21; - -import com.google.googlejavaformat.OpsBuilder; -import com.google.googlejavaformat.java.JavaInputAstVisitor; -import com.sun.source.tree.CaseTree; -import com.sun.source.tree.ConstantCaseLabelTree; -import com.sun.source.tree.DeconstructionPatternTree; -import com.sun.source.tree.DefaultCaseLabelTree; -import com.sun.source.tree.ExpressionTree; -import com.sun.source.tree.PatternCaseLabelTree; -import com.sun.source.tree.PatternTree; -import com.sun.source.tree.Tree; -import com.sun.tools.javac.tree.JCTree; -import javax.lang.model.element.Name; - -/** - * Extends {@link JavaInputAstVisitor} with support for AST nodes that were added or modified in - * Java 21. - */ -public class Java21InputAstVisitor extends JavaInputAstVisitor { - - public Java21InputAstVisitor(OpsBuilder builder, int indentMultiplier) { - super(builder, indentMultiplier); - } - - @Override - protected ExpressionTree getGuard(final CaseTree node) { - return node.getGuard(); - } - - @Override - public Void visitDefaultCaseLabel(DefaultCaseLabelTree node, Void unused) { - token("default"); - return null; - } - - @Override - public Void visitPatternCaseLabel(PatternCaseLabelTree node, Void unused) { - scan(node.getPattern(), null); - return null; - } - - @Override - public Void visitConstantCaseLabel(ConstantCaseLabelTree node, Void aVoid) { - scan(node.getConstantExpression(), null); - return null; - } - - @Override - public Void visitDeconstructionPattern(DeconstructionPatternTree node, Void unused) { - scan(node.getDeconstructor(), null); - builder.open(plusFour); - token("("); - builder.breakOp(); - boolean afterFirstToken = false; - for (PatternTree pattern : node.getNestedPatterns()) { - if (afterFirstToken) { - token(","); - builder.breakOp(" "); - } - afterFirstToken = true; - scan(pattern, null); - } - builder.close(); - token(")"); - return null; - } - - @Override - protected void variableName(Name name) { - if (name.isEmpty()) { - token("_"); - } else { - visit(name); - } - } - - @Override - public Void scan(Tree tree, Void unused) { - // Pre-visit AST for preview features, since com.sun.source.tree.AnyPattern can't be - // accessed directly without --enable-preview. - if (tree instanceof JCTree.JCAnyPattern) { - visitJcAnyPattern((JCTree.JCAnyPattern) tree); - return null; - } else { - return super.scan(tree, null); - } - } - - private void visitJcAnyPattern(JCTree.JCAnyPattern unused) { - token("_"); - } -} diff --git a/core/src/main/resources/META-INF/native-image/reflect-config.json b/core/src/main/resources/META-INF/native-image/reflect-config.json index 89577c035..2c6580345 100644 --- a/core/src/main/resources/META-INF/native-image/reflect-config.json +++ b/core/src/main/resources/META-INF/native-image/reflect-config.json @@ -2,14 +2,5 @@ { "name": "com.sun.tools.javac.parser.UnicodeReader", "allDeclaredMethods": true - }, - { - "name": "com.google.googlejavaformat.java.java21.Java21InputAstVisitor", - "methods": [ - { - "name": "", - "parameterTypes": ["com.google.googlejavaformat.OpsBuilder", "int"] - } - ] } ] From 2186b2ea4d461a827825ec122b15aee65217d590 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 25 Sep 2025 11:38:12 -0700 Subject: [PATCH 361/379] Migrate google-java-format to expression switches PiperOrigin-RevId: 811435570 --- .../com/google/googlejavaformat/Newlines.java | 9 +- .../java/CommandLineOptionsParser.java | 102 +++----- .../java/DimensionHelpers.java | 17 +- .../googlejavaformat/java/Formatter.java | 12 +- .../googlejavaformat/java/ImportOrderer.java | 11 +- .../googlejavaformat/java/JavaInput.java | 14 +- .../java/JavaInputAstVisitor.java | 235 +++++++----------- .../java/ModifierOrderer.java | 56 ++--- .../java/SnippetFormatter.java | 75 +++--- .../google/googlejavaformat/java/Trees.java | 9 +- .../java/TypeNameClassifier.java | 53 ++-- .../java/javadoc/JavadocFormatter.java | 107 ++------ .../java/FormatterIntegrationTest.java | 10 +- 13 files changed, 248 insertions(+), 462 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/Newlines.java b/core/src/main/java/com/google/googlejavaformat/Newlines.java index 86335981b..6a1241c36 100644 --- a/core/src/main/java/com/google/googlejavaformat/Newlines.java +++ b/core/src/main/java/com/google/googlejavaformat/Newlines.java @@ -73,15 +73,16 @@ public static String guessLineSeparator(String text) { for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); switch (c) { - case '\r': + case '\r' -> { if (i + 1 < text.length() && text.charAt(i + 1) == '\n') { return "\r\n"; } return "\r"; - case '\n': + } + case '\n' -> { return "\n"; - default: - break; + } + default -> {} } } return "\n"; diff --git a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java index 098a263f4..f5ce703e8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java +++ b/core/src/main/java/com/google/googlejavaformat/java/CommandLineOptionsParser.java @@ -66,72 +66,25 @@ static CommandLineOptions parse(Iterable options) { } // NOTE: update usage information in UsageException when new flags are added switch (flag) { - case "-i": - case "-r": - case "-replace": - case "--replace": - optionsBuilder.inPlace(true); - break; - case "--lines": - case "-lines": - case "--line": - case "-line": - parseRangeSet(linesBuilder, getValue(flag, it, value)); - break; - case "--offset": - case "-offset": - optionsBuilder.addOffset(parseInteger(it, flag, value)); - break; - case "--length": - case "-length": - optionsBuilder.addLength(parseInteger(it, flag, value)); - break; - case "--aosp": - case "-aosp": - case "-a": - optionsBuilder.aosp(true); - break; - case "--version": - case "-version": - case "-v": - optionsBuilder.version(true); - break; - case "--help": - case "-help": - case "-h": - optionsBuilder.help(true); - break; - case "--fix-imports-only": - optionsBuilder.fixImportsOnly(true); - break; - case "--skip-sorting-imports": - optionsBuilder.sortImports(false); - break; - case "--skip-removing-unused-imports": - optionsBuilder.removeUnusedImports(false); - break; - case "--skip-reflowing-long-strings": - optionsBuilder.reflowLongStrings(false); - break; - case "--skip-javadoc-formatting": - optionsBuilder.formatJavadoc(false); - break; - case "-": - optionsBuilder.stdin(true); - break; - case "-n": - case "--dry-run": - optionsBuilder.dryRun(true); - break; - case "--set-exit-if-changed": - optionsBuilder.setExitIfChanged(true); - break; - case "-assume-filename": - case "--assume-filename": - optionsBuilder.assumeFilename(getValue(flag, it, value)); - break; - default: - throw new IllegalArgumentException("unexpected flag: " + flag); + case "-i", "-r", "-replace", "--replace" -> optionsBuilder.inPlace(true); + case "--lines", "-lines", "--line", "-line" -> + parseRangeSet(linesBuilder, getValue(flag, it, value)); + case "--offset", "-offset" -> optionsBuilder.addOffset(parseInteger(it, flag, value)); + case "--length", "-length" -> optionsBuilder.addLength(parseInteger(it, flag, value)); + case "--aosp", "-aosp", "-a" -> optionsBuilder.aosp(true); + case "--version", "-version", "-v" -> optionsBuilder.version(true); + case "--help", "-help", "-h" -> optionsBuilder.help(true); + case "--fix-imports-only" -> optionsBuilder.fixImportsOnly(true); + case "--skip-sorting-imports" -> optionsBuilder.sortImports(false); + case "--skip-removing-unused-imports" -> optionsBuilder.removeUnusedImports(false); + case "--skip-reflowing-long-strings" -> optionsBuilder.reflowLongStrings(false); + case "--skip-javadoc-formatting" -> optionsBuilder.formatJavadoc(false); + case "-" -> optionsBuilder.stdin(true); + case "-n", "--dry-run" -> optionsBuilder.dryRun(true); + case "--set-exit-if-changed" -> optionsBuilder.setExitIfChanged(true); + case "-assume-filename", "--assume-filename" -> + optionsBuilder.assumeFilename(getValue(flag, it, value)); + default -> throw new IllegalArgumentException("unexpected flag: " + flag); } } optionsBuilder.lines(ImmutableRangeSet.copyOf(linesBuilder)); @@ -175,17 +128,18 @@ private static void parseRangeSet(RangeSet result, String ranges) { */ private static Range parseRange(String arg) { List args = COLON_SPLITTER.splitToList(arg); - switch (args.size()) { - case 1: + return switch (args.size()) { + case 1 -> { int line = Integer.parseInt(args.get(0)) - 1; - return Range.closedOpen(line, line + 1); - case 2: + yield Range.closedOpen(line, line + 1); + } + case 2 -> { int line0 = Integer.parseInt(args.get(0)) - 1; int line1 = Integer.parseInt(args.get(1)) - 1; - return Range.closedOpen(line0, line1 + 1); - default: - throw new IllegalArgumentException(arg); - } + yield Range.closedOpen(line0, line1 + 1); + } + default -> throw new IllegalArgumentException(arg); + }; } /** diff --git a/core/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java b/core/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java index 4bd19bee3..3bf4793c3 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java +++ b/core/src/main/java/com/google/googlejavaformat/java/DimensionHelpers.java @@ -106,19 +106,18 @@ private static Iterable> reorderBySourcePosition( * int}. */ private static Tree extractDims(Deque> dims, Tree node) { - switch (node.getKind()) { - case ARRAY_TYPE: - return extractDims(dims, ((ArrayTypeTree) node).getType()); - case ANNOTATED_TYPE: + return switch (node.getKind()) { + case ARRAY_TYPE -> extractDims(dims, ((ArrayTypeTree) node).getType()); + case ANNOTATED_TYPE -> { AnnotatedTypeTree annotatedTypeTree = (AnnotatedTypeTree) node; if (annotatedTypeTree.getUnderlyingType().getKind() != Tree.Kind.ARRAY_TYPE) { - return node; + yield node; } node = extractDims(dims, annotatedTypeTree.getUnderlyingType()); dims.addFirst(ImmutableList.copyOf(annotatedTypeTree.getAnnotations())); - return node; - default: - return node; - } + yield node; + } + default -> node; + }; } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index 5d9ac76ad..c81e69707 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -164,15 +164,9 @@ static boolean errorDiagnostic(Diagnostic input) { if (input.getKind() != Diagnostic.Kind.ERROR) { return false; } - switch (input.getCode()) { - case "compiler.err.invalid.meth.decl.ret.type.req": - // accept constructor-like method declarations that don't match the name of their - // enclosing class - return false; - default: - break; - } - return true; + // accept constructor-like method declarations that don't match the name of their + // enclosing class + return !input.getCode().equals("compiler.err.invalid.meth.decl.ret.type.req"); } /** diff --git a/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java b/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java index dcbaea172..9aebf4641 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java @@ -218,13 +218,10 @@ boolean isAndroid() { /** True if this is a Java import per AOSP style. */ boolean isJava() { - switch (topLevel()) { - case "java": - case "javax": - return true; - default: - return false; - } + return switch (topLevel()) { + case "java", "javax" -> true; + default -> false; + }; } /** diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java index c59e74c6c..cf525e86f 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInput.java @@ -561,20 +561,18 @@ private static ImmutableList buildTokens(List toks) { // TODO(cushon): find a better strategy. if (toks.get(k).isSlashStarComment()) { switch (tok.getText()) { - case "(": - case "<": - case ".": + case "(", "<", "." -> { break OUTER; - default: - break; + } + default -> {} } } if (toks.get(k).isJavadocComment()) { switch (tok.getText()) { - case ";": + case ";" -> { break OUTER; - default: - break; + } + default -> {} } } if (isParamComment(toks.get(k))) { diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 1336ad0e1..8e8ac97cc 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -455,21 +455,11 @@ protected void dropEmptyDeclarations() { @Override public Void visitClass(ClassTree tree, Void unused) { switch (tree.getKind()) { - case ANNOTATION_TYPE: - visitAnnotationType(tree); - break; - case CLASS: - case INTERFACE: - visitClassDeclaration(tree); - break; - case ENUM: - visitEnumDeclaration(tree); - break; - case RECORD: - visitRecordDeclaration(tree); - break; - default: - throw new AssertionError(tree.getKind()); + case ANNOTATION_TYPE -> visitAnnotationType(tree); + case CLASS, INTERFACE -> visitClassDeclaration(tree); + case ENUM -> visitEnumDeclaration(tree); + case RECORD -> visitRecordDeclaration(tree); + default -> throw new AssertionError(tree.getKind()); } return null; } @@ -1031,14 +1021,8 @@ public Void visitMemberReference(MemberReferenceTree node, Void unused) { builder.op("::"); addTypeArguments(node.getTypeArguments(), plusFour); switch (node.getMode()) { - case INVOKE: - visit(node.getName()); - break; - case NEW: - token("new"); - break; - default: - throw new AssertionError(node.getMode()); + case INVOKE -> visit(node.getName()); + case NEW -> token("new"); } builder.close(); return null; @@ -1878,11 +1862,10 @@ private void splitToken(String operatorName) { private boolean ambiguousUnaryOperator(UnaryTree node, String operatorName) { switch (node.getKind()) { - case UNARY_MINUS: - case UNARY_PLUS: - break; - default: + case UNARY_MINUS, UNARY_PLUS -> {} + default -> { return false; + } } JCTree.Tag tag = unaryTag(node.getExpression()); if (tag == null) { @@ -1912,35 +1895,16 @@ && isUnaryMinusLiteral(getSourceForNode(expression, getCurrentPath()))) { public Void visitPrimitiveType(PrimitiveTypeTree node, Void unused) { sync(node); switch (node.getPrimitiveTypeKind()) { - case BOOLEAN: - token("boolean"); - break; - case BYTE: - token("byte"); - break; - case SHORT: - token("short"); - break; - case INT: - token("int"); - break; - case LONG: - token("long"); - break; - case CHAR: - token("char"); - break; - case FLOAT: - token("float"); - break; - case DOUBLE: - token("double"); - break; - case VOID: - token("void"); - break; - default: - throw new AssertionError(node.getPrimitiveTypeKind()); + case BOOLEAN -> token("boolean"); + case BYTE -> token("byte"); + case SHORT -> token("short"); + case INT -> token("int"); + case LONG -> token("long"); + case CHAR -> token("char"); + case FLOAT -> token("float"); + case DOUBLE -> token("double"); + case VOID -> token("void"); + default -> throw new AssertionError(node.getPrimitiveTypeKind()); } return null; } @@ -2021,14 +1985,14 @@ public Void visitCase(CaseTree node, Void unused) { } switch (node.getCaseKind()) { - case STATEMENT: + case STATEMENT -> { token(":"); builder.open(plusTwo); visitStatements(node.getStatements()); builder.close(); builder.close(); - break; - case RULE: + } + case RULE -> { builder.space(); token("-"); token(">"); @@ -2047,7 +2011,7 @@ public Void visitCase(CaseTree node, Void unused) { builder.close(); } builder.guessToken(";"); - break; + } } return null; } @@ -2371,15 +2335,16 @@ private void visitStatement( AllowTrailingBlankLine allowTrailingBlank) { sync(node); switch (node.getKind()) { - case BLOCK: + case BLOCK -> { builder.space(); visitBlock((BlockTree) node, collapseEmptyOrNot, allowLeadingBlank, allowTrailingBlank); - break; - default: + } + default -> { builder.open(plusTwo); builder.breakOp(" "); scan(node, null); builder.close(); + } } } @@ -2535,13 +2500,10 @@ boolean isAnnotation() { } int position() { - switch (getKind()) { - case MODIFIER: - return modifier().getPosition(); - case ANNOTATION: - return getStartPosition(annotation()); - } - throw new AssertionError(); + return switch (getKind()) { + case MODIFIER -> modifier().getPosition(); + case ANNOTATION -> getStartPosition(annotation()); + }; } private static final Comparator COMPARATOR = @@ -2634,16 +2596,14 @@ DeclarationModifiersAndTypeAnnotations splitModifiers( private void formatAnnotationOrModifier(Deque modifiers) { AnnotationOrModifier modifier = modifiers.removeFirst(); switch (modifier.getKind()) { - case MODIFIER: + case MODIFIER -> { token(modifier.modifier().getText()); if (modifier.modifier().getText().equals("non")) { token(modifiers.removeFirst().modifier().getText()); token(modifiers.removeFirst().modifier().getText()); } - break; - case ANNOTATION: - scan(modifier.annotation(), null); - break; + } + case ANNOTATION -> scan(modifier.annotation(), null); } } @@ -2656,26 +2616,25 @@ boolean isTypeAnnotation(AnnotationTree annotationTree) { } private static boolean isModifier(String token) { - switch (token) { - case "public": - case "protected": - case "private": - case "abstract": - case "static": - case "final": - case "transient": - case "volatile": - case "synchronized": - case "native": - case "strictfp": - case "default": - case "sealed": - case "non": - case "-": - return true; - default: - return false; - } + return switch (token) { + case "public", + "protected", + "private", + "abstract", + "static", + "final", + "transient", + "volatile", + "synchronized", + "native", + "strictfp", + "default", + "sealed", + "non", + "-" -> + true; + default -> false; + }; } @Override @@ -3037,21 +2996,19 @@ void visitDot(ExpressionTree node0) { node = getArrayBase(node); } switch (node.getKind()) { - case MEMBER_SELECT: - node = ((MemberSelectTree) node).getExpression(); - break; - case METHOD_INVOCATION: - node = getMethodReceiver((MethodInvocationTree) node); - break; - case IDENTIFIER: + case MEMBER_SELECT -> node = ((MemberSelectTree) node).getExpression(); + case METHOD_INVOCATION -> node = getMethodReceiver((MethodInvocationTree) node); + case IDENTIFIER -> { node = null; break LOOP; - default: + } + default -> { // If the dot chain starts with a primary expression // (e.g. a class instance creation, or a conditional expression) // then remove it from the list and deal with it first. node = stack.removeFirst(); break LOOP; + } } } while (node != null); List items = new ArrayList<>(stack); @@ -3126,12 +3083,8 @@ void visitDot(ExpressionTree node0) { if (prefixes.isEmpty() && items.get(0) instanceof IdentifierTree) { switch (((IdentifierTree) items.get(0)).getName().toString()) { - case "this": - case "super": - prefixes.add(1); - break; - default: - break; + case "this", "super" -> prefixes.add(1); + default -> {} } } @@ -3287,17 +3240,16 @@ private static ImmutableList simpleNames(Deque stack) { boolean isArray = expression.getKind() == ARRAY_ACCESS; expression = getArrayBase(expression); switch (expression.getKind()) { - case MEMBER_SELECT: - simpleNames.add(((MemberSelectTree) expression).getIdentifier().toString()); - break; - case IDENTIFIER: - simpleNames.add(((IdentifierTree) expression).getName().toString()); - break; - case METHOD_INVOCATION: + case MEMBER_SELECT -> + simpleNames.add(((MemberSelectTree) expression).getIdentifier().toString()); + case IDENTIFIER -> simpleNames.add(((IdentifierTree) expression).getName().toString()); + case METHOD_INVOCATION -> { simpleNames.add(getMethodName((MethodInvocationTree) expression).toString()); break OUTER; - default: + } + default -> { break OUTER; + } } if (isArray) { break OUTER; @@ -3309,11 +3261,11 @@ private static ImmutableList simpleNames(Deque stack) { private void dotExpressionUpToArgs(ExpressionTree expression, Optional tyargTag) { expression = getArrayBase(expression); switch (expression.getKind()) { - case MEMBER_SELECT: + case MEMBER_SELECT -> { MemberSelectTree fieldAccess = (MemberSelectTree) expression; visit(fieldAccess.getIdentifier()); - break; - case METHOD_INVOCATION: + } + case METHOD_INVOCATION -> { MethodInvocationTree methodInvocation = (MethodInvocationTree) expression; if (!methodInvocation.getTypeArguments().isEmpty()) { builder.open(plusFour); @@ -3323,13 +3275,9 @@ private void dotExpressionUpToArgs(ExpressionTree expression, Optional builder.close(); } visit(getMethodName(methodInvocation)); - break; - case IDENTIFIER: - visit(((IdentifierTree) expression).getName()); - break; - default: - scan(expression, null); - break; + } + case IDENTIFIER -> visit(((IdentifierTree) expression).getName()); + default -> scan(expression, null); } } @@ -3354,14 +3302,13 @@ private void dotExpressionArgsAndParen( Deque indices = getArrayIndices(expression); expression = getArrayBase(expression); switch (expression.getKind()) { - case METHOD_INVOCATION: + case METHOD_INVOCATION -> { builder.open(tyargIndent); MethodInvocationTree methodInvocation = (MethodInvocationTree) expression; addArguments(methodInvocation.getArguments(), indent); builder.close(); - break; - default: - break; + } + default -> {} } formatArrayIndices(indices); } @@ -3519,14 +3466,9 @@ public void scan(JCTree tree) { return; } switch (tree.getKind()) { - case STRING_LITERAL: - break; - case PLUS: - super.scan(tree); - break; - default: - stringLiteral[0] = false; - break; + case STRING_LITERAL -> {} + case PLUS -> super.scan(tree); + default -> stringLiteral[0] = false; } if (tree.getKind() == STRING_LITERAL) { Object value = ((LiteralTree) tree).getValue(); @@ -3810,7 +3752,7 @@ private void maybeAddDims( boolean lastWasAnnotation = false; while (builder.peekToken().isPresent()) { switch (builder.peekToken().get()) { - case "@": + case "@" -> { if (annotations.isEmpty()) { return; } @@ -3821,8 +3763,8 @@ private void maybeAddDims( builder.breakToFill(" "); visitAnnotations(dimAnnotations, BreakOrNot.NO, BreakOrNot.NO); lastWasAnnotation = true; - break; - case "[": + } + case "[" -> { if (lastWasAnnotation) { builder.breakToFill(" "); } else { @@ -3834,8 +3776,8 @@ private void maybeAddDims( } token("]"); lastWasAnnotation = false; - break; - case ".": + } + case "." -> { if (!builder.peekToken().get().equals(".") || !builder.peekToken(1).get().equals(".")) { return; } @@ -3846,9 +3788,10 @@ private void maybeAddDims( } builder.op("..."); lastWasAnnotation = false; - break; - default: + } + default -> { return; + } } } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java index 1b26f7d69..33ad13178 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/ModifierOrderer.java @@ -207,41 +207,29 @@ private static void addTrivia(StringBuilder replacement, ImmutableList Modifier.PUBLIC; + case PROTECTED -> Modifier.PROTECTED; + case PRIVATE -> Modifier.PRIVATE; + case ABSTRACT -> Modifier.ABSTRACT; + case STATIC -> Modifier.STATIC; + case DEFAULT -> Modifier.DEFAULT; + + case FINAL -> Modifier.FINAL; + case TRANSIENT -> Modifier.TRANSIENT; + case VOLATILE -> Modifier.VOLATILE; + case SYNCHRONIZED -> Modifier.SYNCHRONIZED; + case NATIVE -> Modifier.NATIVE; + case STRICTFP -> Modifier.STRICTFP; + default -> + switch (token.getTok().getText()) { + case "sealed" -> Modifier.SEALED; + default -> null; + }; + }; } /** Applies replacements to the given string. */ diff --git a/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java b/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java index 8d426b65d..4850ad773 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java @@ -163,53 +163,38 @@ private SnippetWrapper snippetWrapper(SnippetKind kind, String source, int initi * Synthesize a dummy class around the code snippet provided by Eclipse. The dummy class is * correctly formatted -- the blocks use correct indentation, etc. */ - switch (kind) { - case COMPILATION_UNIT: - { - SnippetWrapper wrapper = new SnippetWrapper(); - for (int i = 1; i <= initialIndent; i++) { - wrapper.append("class Dummy {\n").append(createIndentationString(i)); - } - wrapper.appendSource(source); - wrapper.closeBraces(initialIndent); - return wrapper; + return switch (kind) { + case COMPILATION_UNIT, CLASS_BODY_DECLARATIONS -> { + SnippetWrapper wrapper = new SnippetWrapper(); + for (int i = 1; i <= initialIndent; i++) { + wrapper.append("class Dummy {\n").append(createIndentationString(i)); } - case CLASS_BODY_DECLARATIONS: - { - SnippetWrapper wrapper = new SnippetWrapper(); - for (int i = 1; i <= initialIndent; i++) { - wrapper.append("class Dummy {\n").append(createIndentationString(i)); - } - wrapper.appendSource(source); - wrapper.closeBraces(initialIndent); - return wrapper; - } - case STATEMENTS: - { - SnippetWrapper wrapper = new SnippetWrapper(); - wrapper.append("class Dummy {\n").append(createIndentationString(1)); - for (int i = 2; i <= initialIndent; i++) { - wrapper.append("{\n").append(createIndentationString(i)); - } - wrapper.appendSource(source); - wrapper.closeBraces(initialIndent); - return wrapper; + wrapper.appendSource(source); + wrapper.closeBraces(initialIndent); + yield wrapper; + } + case STATEMENTS -> { + SnippetWrapper wrapper = new SnippetWrapper(); + wrapper.append("class Dummy {\n").append(createIndentationString(1)); + for (int i = 2; i <= initialIndent; i++) { + wrapper.append("{\n").append(createIndentationString(i)); } - case EXPRESSION: - { - SnippetWrapper wrapper = new SnippetWrapper(); - wrapper.append("class Dummy {\n").append(createIndentationString(1)); - for (int i = 2; i <= initialIndent; i++) { - wrapper.append("{\n").append(createIndentationString(i)); - } - wrapper.append("Object o = "); - wrapper.appendSource(source); - wrapper.append(";"); - wrapper.closeBraces(initialIndent); - return wrapper; + wrapper.appendSource(source); + wrapper.closeBraces(initialIndent); + yield wrapper; + } + case EXPRESSION -> { + SnippetWrapper wrapper = new SnippetWrapper(); + wrapper.append("class Dummy {\n").append(createIndentationString(1)); + for (int i = 2; i <= initialIndent; i++) { + wrapper.append("{\n").append(createIndentationString(i)); } - default: - throw new IllegalArgumentException("Unknown snippet kind: " + kind); - } + wrapper.append("Object o = "); + wrapper.appendSource(source); + wrapper.append(";"); + wrapper.closeBraces(initialIndent); + yield wrapper; + } + }; } } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Trees.java b/core/src/main/java/com/google/googlejavaformat/java/Trees.java index 397dacae6..ded219644 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Trees.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Trees.java @@ -99,13 +99,10 @@ static int precedence(ExpressionTree expression) { static ClassTree getEnclosingTypeDeclaration(TreePath path) { for (; path != null; path = path.getParentPath()) { switch (path.getLeaf().getKind()) { - case CLASS: - case ENUM: - case INTERFACE: - case ANNOTATED_TYPE: + case CLASS, ENUM, INTERFACE, ANNOTATED_TYPE -> { return (ClassTree) path.getLeaf(); - default: - break; + } + default -> {} } } throw new AssertionError(); diff --git a/core/src/main/java/com/google/googlejavaformat/java/TypeNameClassifier.java b/core/src/main/java/com/google/googlejavaformat/java/TypeNameClassifier.java index 21fae5f03..83c09b3ee 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/TypeNameClassifier.java +++ b/core/src/main/java/com/google/googlejavaformat/java/TypeNameClassifier.java @@ -30,20 +30,17 @@ private enum TyParseState { START(false) { @Override public TyParseState next(JavaCaseFormat n) { - switch (n) { - case UPPERCASE: - // if we see an UpperCamel later, assume this was a class - // e.g. com.google.FOO.Bar - return TyParseState.AMBIGUOUS; - case LOWER_CAMEL: - return TyParseState.REJECT; - case LOWERCASE: - // could be a package - return TyParseState.START; - case UPPER_CAMEL: - return TyParseState.TYPE; - } - throw new AssertionError(); + return switch (n) { + case UPPERCASE -> + // if we see an UpperCamel later, assume this was a class + // e.g. com.google.FOO.Bar + TyParseState.AMBIGUOUS; + case LOWER_CAMEL -> TyParseState.REJECT; + case LOWERCASE -> + // could be a package + TyParseState.START; + case UPPER_CAMEL -> TyParseState.TYPE; + }; } }, @@ -51,15 +48,10 @@ public TyParseState next(JavaCaseFormat n) { TYPE(true) { @Override public TyParseState next(JavaCaseFormat n) { - switch (n) { - case UPPERCASE: - case LOWER_CAMEL: - case LOWERCASE: - return TyParseState.FIRST_STATIC_MEMBER; - case UPPER_CAMEL: - return TyParseState.TYPE; - } - throw new AssertionError(); + return switch (n) { + case UPPERCASE, LOWER_CAMEL, LOWERCASE -> TyParseState.FIRST_STATIC_MEMBER; + case UPPER_CAMEL -> TyParseState.TYPE; + }; } }, @@ -83,16 +75,11 @@ public TyParseState next(JavaCaseFormat n) { AMBIGUOUS(false) { @Override public TyParseState next(JavaCaseFormat n) { - switch (n) { - case UPPERCASE: - return AMBIGUOUS; - case LOWER_CAMEL: - case LOWERCASE: - return TyParseState.REJECT; - case UPPER_CAMEL: - return TyParseState.TYPE; - } - throw new AssertionError(); + return switch (n) { + case UPPERCASE -> AMBIGUOUS; + case LOWER_CAMEL, LOWERCASE -> TyParseState.REJECT; + case UPPER_CAMEL -> TyParseState.TYPE; + }; } }; diff --git a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java index 4d45c9874..bb9f70040 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/javadoc/JavadocFormatter.java @@ -57,88 +57,35 @@ private static String render(List input, int blockIndent) { JavadocWriter output = new JavadocWriter(blockIndent); for (Token token : input) { switch (token.getType()) { - case BEGIN_JAVADOC: - output.writeBeginJavadoc(); - break; - case END_JAVADOC: + case BEGIN_JAVADOC -> output.writeBeginJavadoc(); + case END_JAVADOC -> { output.writeEndJavadoc(); return output.toString(); - case FOOTER_JAVADOC_TAG_START: - output.writeFooterJavadocTagStart(token); - break; - case SNIPPET_BEGIN: - output.writeSnippetBegin(token); - break; - case SNIPPET_END: - output.writeSnippetEnd(token); - break; - case LIST_OPEN_TAG: - output.writeListOpen(token); - break; - case LIST_CLOSE_TAG: - output.writeListClose(token); - break; - case LIST_ITEM_OPEN_TAG: - output.writeListItemOpen(token); - break; - case HEADER_OPEN_TAG: - output.writeHeaderOpen(token); - break; - case HEADER_CLOSE_TAG: - output.writeHeaderClose(token); - break; - case PARAGRAPH_OPEN_TAG: - output.writeParagraphOpen(standardizePToken(token)); - break; - case BLOCKQUOTE_OPEN_TAG: - case BLOCKQUOTE_CLOSE_TAG: - output.writeBlockquoteOpenOrClose(token); - break; - case PRE_OPEN_TAG: - output.writePreOpen(token); - break; - case PRE_CLOSE_TAG: - output.writePreClose(token); - break; - case CODE_OPEN_TAG: - output.writeCodeOpen(token); - break; - case CODE_CLOSE_TAG: - output.writeCodeClose(token); - break; - case TABLE_OPEN_TAG: - output.writeTableOpen(token); - break; - case TABLE_CLOSE_TAG: - output.writeTableClose(token); - break; - case MOE_BEGIN_STRIP_COMMENT: - output.requestMoeBeginStripComment(token); - break; - case MOE_END_STRIP_COMMENT: - output.writeMoeEndStripComment(token); - break; - case HTML_COMMENT: - output.writeHtmlComment(token); - break; - case BR_TAG: - output.writeBr(standardizeBrToken(token)); - break; - case WHITESPACE: - output.requestWhitespace(); - break; - case FORCED_NEWLINE: - output.writeLineBreakNoAutoIndent(); - break; - case LITERAL: - output.writeLiteral(token); - break; - case PARAGRAPH_CLOSE_TAG: - case LIST_ITEM_CLOSE_TAG: - case OPTIONAL_LINE_BREAK: - break; - default: - throw new AssertionError(token.getType()); + } + case FOOTER_JAVADOC_TAG_START -> output.writeFooterJavadocTagStart(token); + case SNIPPET_BEGIN -> output.writeSnippetBegin(token); + case SNIPPET_END -> output.writeSnippetEnd(token); + case LIST_OPEN_TAG -> output.writeListOpen(token); + case LIST_CLOSE_TAG -> output.writeListClose(token); + case LIST_ITEM_OPEN_TAG -> output.writeListItemOpen(token); + case HEADER_OPEN_TAG -> output.writeHeaderOpen(token); + case HEADER_CLOSE_TAG -> output.writeHeaderClose(token); + case PARAGRAPH_OPEN_TAG -> output.writeParagraphOpen(standardizePToken(token)); + case BLOCKQUOTE_OPEN_TAG, BLOCKQUOTE_CLOSE_TAG -> output.writeBlockquoteOpenOrClose(token); + case PRE_OPEN_TAG -> output.writePreOpen(token); + case PRE_CLOSE_TAG -> output.writePreClose(token); + case CODE_OPEN_TAG -> output.writeCodeOpen(token); + case CODE_CLOSE_TAG -> output.writeCodeClose(token); + case TABLE_OPEN_TAG -> output.writeTableOpen(token); + case TABLE_CLOSE_TAG -> output.writeTableClose(token); + case MOE_BEGIN_STRIP_COMMENT -> output.requestMoeBeginStripComment(token); + case MOE_END_STRIP_COMMENT -> output.writeMoeEndStripComment(token); + case HTML_COMMENT -> output.writeHtmlComment(token); + case BR_TAG -> output.writeBr(standardizeBrToken(token)); + case WHITESPACE -> output.requestWhitespace(); + case FORCED_NEWLINE -> output.writeLineBreakNoAutoIndent(); + case LITERAL -> output.writeLiteral(token); + case PARAGRAPH_CLOSE_TAG, LIST_ITEM_CLOSE_TAG, OPTIONAL_LINE_BREAK -> {} } } throw new AssertionError(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 6a73da185..8e863a28d 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -81,13 +81,9 @@ public static Iterable data() throws IOException { contents = CharStreams.toString(new InputStreamReader(stream, UTF_8)); } switch (extension) { - case "input": - inputs.put(baseName, contents); - break; - case "output": - outputs.put(baseName, contents); - break; - default: // fall out + case "input" -> inputs.put(baseName, contents); + case "output" -> outputs.put(baseName, contents); + default -> {} } } } From c2709510562e304e6d7f69d7aa844292e11cc989 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Wed, 1 Oct 2025 07:41:38 -0700 Subject: [PATCH 362/379] docs: Update README with a bit more details about available flags Fixes #1285. @cushon Fixes #1288 COPYBARA_INTEGRATE_REVIEW=https://github.com/google/google-java-format/pull/1288 from vorburger:patch-8 65730127f1386179ebdc20154bafdbfd6df2eb59 PiperOrigin-RevId: 813749351 --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index ab55679ab..1539f7564 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,15 @@ The formatter can act on whole files, on limited lines (`--lines`), on specific offsets (`--offset`), passing through to standard-out (default) or altered in-place (`--replace`). +Option `--help` will print full usage details; including built-in documentation +about other flags, such as `--aosp`, `--fix-imports-only`, +`--skip-sorting-imports`, `--skip-removing-unused-import`, +`--skip-reflowing-long-strings`, `--skip-javadoc-formatting`, or the `--dry-run` +and `--set-exit-if-changed`. + +Using `@` reads options and filenames from a file, instead of +arguments. + To reformat changed lines in a specific patch, use [`google-java-format-diff.py`](https://github.com/google/google-java-format/blob/master/scripts/google-java-format-diff.py). From d2c676e7a3367209e243aca77e8440488820ea5b Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Fri, 3 Oct 2025 11:20:32 -0700 Subject: [PATCH 363/379] Update the IntelliJ plugin to gjf 1.29.0. Since this requires Java 21, set the minimum supported version to 2024.3 (which ships with Java 21). PiperOrigin-RevId: 814763806 --- idea_plugin/build.gradle.kts | 56 ++++++++----------- .../src/main/resources/META-INF/plugin.xml | 3 + 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 459582e42..1710154f4 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -17,24 +17,20 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases -plugins { - id("org.jetbrains.intellij.platform") version "2.6.0" -} +plugins { id("org.jetbrains.intellij.platform") version "2.9.0" } repositories { mavenCentral() - intellijPlatform { - defaultRepositories() - } + intellijPlatform { defaultRepositories() } } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.28.0" +val googleJavaFormatVersion = "1.29.0" java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } intellijPlatform { @@ -42,7 +38,7 @@ intellijPlatform { name = "google-java-format" version = "${googleJavaFormatVersion}.0" ideaVersion { - sinceBuild = "223" + sinceBuild = "243" untilBuild = provider { null } } } @@ -54,32 +50,28 @@ intellijPlatform { } var gjfRequiredJvmArgs = - listOf( - "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", - "--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", - ) + listOf( + "--add-exports", + "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", + "--add-exports", + "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", + "--add-exports", + "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", + "--add-exports", + "jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", + "--add-exports", + "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", + "--add-exports", + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", + ) -tasks { - runIde { - jvmArgumentProviders += CommandLineArgumentProvider { - gjfRequiredJvmArgs - } - } -} +tasks { runIde { jvmArgumentProviders += CommandLineArgumentProvider { gjfRequiredJvmArgs } } } -tasks { - withType().configureEach { - jvmArgs(gjfRequiredJvmArgs) - } -} +tasks { withType().configureEach { jvmArgs(gjfRequiredJvmArgs) } } dependencies { intellijPlatform { - intellijIdeaCommunity("2022.3") + intellijIdeaCommunity("2024.3") bundledPlugin("com.intellij.java") testFramework(TestFrameworkType.Plugin.Java) } @@ -87,5 +79,5 @@ dependencies { // https://mvnrepository.com/artifact/junit/junit testImplementation("junit:junit:4.13.2") // https://mvnrepository.com/artifact/com.google.truth/truth - testImplementation("com.google.truth:truth:1.4.4") + testImplementation("com.google.truth:truth:1.4.5") } diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 2575a6cf4..3ddb285a6 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,9 @@ ]]> +
        1.29.0.0
        +
        Updated to use google-java-format 1.29.0.
        +
        Minimum supported IntelliJ version is now 2024.3.
        1.28.0.0
        Updated to use google-java-format 1.28.0.
        1.27.0.0
        From 00a908b0d59ddb395d832bd7d1f3c0ad085c31fe Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Sat, 4 Oct 2025 06:55:26 -0700 Subject: [PATCH 364/379] Remove uses of deprecated plugin APIs. PiperOrigin-RevId: 815077151 --- idea_plugin/build.gradle.kts | 11 +++- .../intellij/InitialConfigurationNotifier.kt | 65 +++++++++++++++++++ .../InitialConfigurationStartupActivity.java | 60 ----------------- .../intellij/JreConfigurationChecker.java | 23 ++++--- .../src/main/resources/META-INF/plugin.xml | 4 +- 5 files changed, 91 insertions(+), 72 deletions(-) create mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationNotifier.kt delete mode 100644 idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 1710154f4..645d96de1 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -17,7 +17,10 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases -plugins { id("org.jetbrains.intellij.platform") version "2.9.0" } +plugins { + id("org.jetbrains.intellij.platform") version "2.9.0" + kotlin("jvm") version "2.2.0" +} repositories { mavenCentral() @@ -27,16 +30,19 @@ repositories { // https://github.com/google/google-java-format/releases val googleJavaFormatVersion = "1.29.0" +val pluginPatchVersion = "1" java { sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 } +kotlin { jvmToolchain(21) } + intellijPlatform { pluginConfiguration { name = "google-java-format" - version = "${googleJavaFormatVersion}.0" + version = "${googleJavaFormatVersion}.${pluginPatchVersion}" ideaVersion { sinceBuild = "243" untilBuild = provider { null } @@ -80,4 +86,5 @@ dependencies { testImplementation("junit:junit:4.13.2") // https://mvnrepository.com/artifact/com.google.truth/truth testImplementation("com.google.truth:truth:1.4.5") + implementation(kotlin("stdlib-jdk8")) } diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationNotifier.kt b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationNotifier.kt new file mode 100644 index 000000000..d5d4c83da --- /dev/null +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationNotifier.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2025 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.googlejavaformat.intellij + +import com.intellij.notification.Notification +import com.intellij.notification.NotificationAction +import com.intellij.notification.NotificationGroupManager +import com.intellij.notification.NotificationType +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.project.Project +import com.intellij.openapi.startup.ProjectActivity + +private class InitialConfigurationNotifier : ProjectActivity { + + companion object { + const val NOTIFICATION_TITLE: String = "Enable google-java-format" + } + + override suspend fun execute(project: Project) { + val settings = GoogleJavaFormatSettings.getInstance(project) + + if (settings.isUninitialized) { + settings.isEnabled = false + displayNewUserNotification(project, settings) + } else if (settings.isEnabled) { + JreConfigurationChecker.checkJreConfiguration(project) + } + } + + private fun displayNewUserNotification(project: Project?, settings: GoogleJavaFormatSettings) { + val groupManager = NotificationGroupManager.getInstance() + val group = groupManager.getNotificationGroup(NOTIFICATION_TITLE) + val notification = + Notification( + group.displayId, + NOTIFICATION_TITLE, + "The google-java-format plugin is disabled by default.", + NotificationType.INFORMATION + ) + notification.addAction( + object : NotificationAction("Enable for this project") { + override fun actionPerformed( + anActionEvent: AnActionEvent, notification: Notification + ) { + settings.isEnabled = true + notification.expire() + } + }) + notification.notify(project) + } +} diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java deleted file mode 100644 index 95e13d325..000000000 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/InitialConfigurationStartupActivity.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.googlejavaformat.intellij; - -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationGroup; -import com.intellij.notification.NotificationGroupManager; -import com.intellij.notification.NotificationType; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.startup.StartupActivity; -import org.jetbrains.annotations.NotNull; - -final class InitialConfigurationStartupActivity implements StartupActivity.Background { - - private static final String NOTIFICATION_TITLE = "Enable google-java-format"; - - @Override - public void runActivity(@NotNull Project project) { - GoogleJavaFormatSettings settings = GoogleJavaFormatSettings.getInstance(project); - - if (settings.isUninitialized()) { - settings.setEnabled(false); - displayNewUserNotification(project, settings); - } else if (settings.isEnabled()) { - JreConfigurationChecker.checkJreConfiguration(project); - } - } - - private void displayNewUserNotification(Project project, GoogleJavaFormatSettings settings) { - NotificationGroupManager groupManager = NotificationGroupManager.getInstance(); - NotificationGroup group = groupManager.getNotificationGroup(NOTIFICATION_TITLE); - Notification notification = - new Notification( - group.getDisplayId(), - NOTIFICATION_TITLE, - "The google-java-format plugin is disabled by default. " - + "Enable for this project.", - NotificationType.INFORMATION); - notification.setListener( - (n, e) -> { - settings.setEnabled(true); - n.expire(); - }); - notification.notify(project); - } -} diff --git a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java index 5084b6a39..0bc3572e8 100644 --- a/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java +++ b/idea_plugin/src/main/java/com/google/googlejavaformat/intellij/JreConfigurationChecker.java @@ -17,12 +17,15 @@ package com.google.googlejavaformat.intellij; import com.google.common.base.Suppliers; -import com.intellij.ide.ui.IdeUiService; +import com.intellij.ide.BrowserUtil; import com.intellij.notification.Notification; +import com.intellij.notification.NotificationAction; import com.intellij.notification.NotificationType; +import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import java.util.function.Supplier; +import org.jetbrains.annotations.NotNull; class JreConfigurationChecker { @@ -89,15 +92,17 @@ private void displayConfigurationErrorNotification() { new Notification( "Configure JRE for google-java-format", "Configure the JRE for google-java-format", - "The google-java-format plugin needs additional configuration before it can be used. " - + "Follow the instructions here.", + "The google-java-format plugin needs additional configuration before it can be used.", NotificationType.INFORMATION); - notification.setListener( - (n, e) -> { - IdeUiService.getInstance() - .browse( - "https://github.com/google/google-java-format/blob/master/README.md#intellij-jre-config"); - n.expire(); + notification.addAction( + new NotificationAction("Follow the instructions here") { + @Override + public void actionPerformed( + @NotNull AnActionEvent anActionEvent, @NotNull Notification notification) { + BrowserUtil.browse( + "https://github.com/google/google-java-format/blob/master/README.md#intellij-jre-config"); + notification.expire(); + } }); notification.notify(project); } diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 3ddb285a6..1d69a056d 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
        1.29.0.1
        +
        Remove uses of deprecated IntelliJ plugin APIs.
        1.29.0.0
        Updated to use google-java-format 1.29.0.
        Minimum supported IntelliJ version is now 2024.3.
        @@ -113,7 +115,7 @@ - + Date: Wed, 8 Oct 2025 07:54:47 -0700 Subject: [PATCH 365/379] Initial support for `import module` in google-java-format https://github.com/google/google-java-format/issues/1213 PiperOrigin-RevId: 816705772 --- .../googlejavaformat/java/ImportOrderer.java | 49 +++++++++++++------ .../java/JavaInputAstVisitor.java | 26 ++++++++++ .../java/RemoveUnusedImports.java | 39 ++++++++++++++- .../java/FormatterIntegrationTest.java | 1 + .../java/ImportOrdererTest.java | 17 +++++++ .../java/RemoveUnusedImportsTest.java | 22 +++++++-- 6 files changed, 134 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java b/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java index 9aebf4641..375a3289b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java +++ b/core/src/main/java/com/google/googlejavaformat/java/ImportOrderer.java @@ -122,18 +122,24 @@ private String reorderImports() throws FormatterException { /** * A {@link Comparator} that orders {@link Import}s by Google Style, defined at * https://google.github.io/styleguide/javaguide.html#s3.3.3-import-ordering-and-spacing. + * + *

        Module imports are not allowed by Google Style, so we make an arbitrary choice about where + * to include them if they are present. */ private static final Comparator GOOGLE_IMPORT_COMPARATOR = - Comparator.comparing(Import::isStatic, trueFirst()).thenComparing(Import::imported); + Comparator.comparing(Import::importType).thenComparing(Import::imported); /** * A {@link Comparator} that orders {@link Import}s by AOSP Style, defined at * https://source.android.com/setup/contribute/code-style#order-import-statements and implemented * in IntelliJ at * https://android.googlesource.com/platform/development/+/master/ide/intellij/codestyles/AndroidStyle.xml. + * + *

        Module imports are not mentioned by Android Style, so we make an arbitrary choice about + * where to include them if they are present. */ private static final Comparator AOSP_IMPORT_COMPARATOR = - Comparator.comparing(Import::isStatic, trueFirst()) + Comparator.comparing(Import::importType) .thenComparing(Import::isAndroid, trueFirst()) .thenComparing(Import::isThirdParty, trueFirst()) .thenComparing(Import::isJava, trueFirst()) @@ -144,7 +150,7 @@ private String reorderImports() throws FormatterException { * Import}s based on Google style. */ private static boolean shouldInsertBlankLineGoogle(Import prev, Import curr) { - return prev.isStatic() && !curr.isStatic(); + return !prev.importType().equals(curr.importType()); } /** @@ -152,7 +158,7 @@ private static boolean shouldInsertBlankLineGoogle(Import prev, Import curr) { * Import}s based on AOSP style. */ private static boolean shouldInsertBlankLineAosp(Import prev, Import curr) { - if (prev.isStatic() && !curr.isStatic()) { + if (!prev.importType().equals(curr.importType())) { return true; } // insert blank line between "com.android" from "com.anythingelse" @@ -183,16 +189,22 @@ private ImportOrderer(String text, ImmutableList toks, Style style) { } } + enum ImportType { + STATIC, + MODULE, + NORMAL + } + /** An import statement. */ class Import { private final String imported; - private final boolean isStatic; private final String trailing; + private final ImportType importType; - Import(String imported, String trailing, boolean isStatic) { + Import(String imported, String trailing, ImportType importType) { this.imported = imported; this.trailing = trailing; - this.isStatic = isStatic; + this.importType = importType; } /** The name being imported, for example {@code java.util.List}. */ @@ -200,9 +212,9 @@ String imported() { return imported; } - /** True if this is {@code import static}. */ - boolean isStatic() { - return isStatic; + /** Returns the {@link ImportType}. */ + ImportType importType() { + return importType; } /** The top-level package of the import. */ @@ -245,8 +257,10 @@ public boolean isThirdParty() { public String toString() { StringBuilder sb = new StringBuilder(); sb.append("import "); - if (isStatic()) { - sb.append("static "); + switch (importType) { + case STATIC -> sb.append("static "); + case MODULE -> sb.append("module "); + case NORMAL -> {} } sb.append(imported()).append(';'); if (trailing().trim().isEmpty()) { @@ -301,8 +315,13 @@ private ImportsAndIndex scanImports(int i) throws FormatterException { if (isSpaceToken(i)) { i++; } - boolean isStatic = tokenAt(i).equals("static"); - if (isStatic) { + ImportType importType = + switch (tokenAt(i)) { + case "static" -> ImportType.STATIC; + case "module" -> ImportType.MODULE; + default -> ImportType.NORMAL; + }; + if (!importType.equals(ImportType.NORMAL)) { i++; if (isSpaceToken(i)) { i++; @@ -347,7 +366,7 @@ private ImportsAndIndex scanImports(int i) throws FormatterException { // Extra semicolons are not allowed by the JLS but are accepted by javac. i++; } - imports.add(new Import(importedName, trailing.toString(), isStatic)); + imports.add(new Import(importedName, trailing.toString(), importType)); // Remember the position just after the import we just saw, before skipping blank lines. // If the next thing after the blank lines is not another import then we don't want to // include those blank lines in the text to be replaced. diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 8e8ac97cc..a2a32e79c 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -157,6 +157,7 @@ import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.TreeInfo; import com.sun.tools.javac.tree.TreeScanner; +import java.lang.reflect.Method; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -1220,6 +1221,10 @@ public Void visitImport(ImportTree node, Void unused) { sync(node); token("import"); builder.space(); + if (isModuleImport(node)) { + token("module"); + builder.space(); + } if (node.isStatic()) { token("static"); builder.space(); @@ -1231,6 +1236,27 @@ public Void visitImport(ImportTree node, Void unused) { return null; } + private static final @Nullable Method IS_MODULE_METHOD = getIsModuleMethod(); + + private static @Nullable Method getIsModuleMethod() { + try { + return ImportTree.class.getMethod("isModule"); + } catch (NoSuchMethodException ignored) { + return null; + } + } + + private static boolean isModuleImport(ImportTree importTree) { + if (IS_MODULE_METHOD == null) { + return false; + } + try { + return (boolean) IS_MODULE_METHOD.invoke(importTree); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } + private void checkForTypeAnnotation(ImportTree node) { Name simpleName = getSimpleName(node); Collection wellKnownAnnotations = TYPE_ANNOTATIONS.get(simpleName.toString()); diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index 8c3cae319..4035ce319 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -16,6 +16,7 @@ package com.google.googlejavaformat.java; +import static com.google.common.base.Preconditions.checkArgument; import static java.lang.Math.max; import static java.nio.charset.StandardCharsets.UTF_8; @@ -67,6 +68,7 @@ import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import javax.tools.StandardLocation; +import org.jspecify.annotations.Nullable; /** * Removes unused imports from a source file. Imports that are only used in javadoc are also @@ -274,6 +276,9 @@ private static RangeMap buildReplacements( Multimap> usedInJavadoc) { RangeMap replacements = TreeRangeMap.create(); for (JCTree importTree : unit.getImports()) { + if (isModuleImport(importTree)) { + continue; + } String simpleName = getSimpleName(importTree); if (!isUnused(unit, usedNames, usedInJavadoc, importTree, simpleName)) { continue; @@ -322,10 +327,42 @@ private static boolean isUnused( return true; } + private static final Method GET_QUALIFIED_IDENTIFIER_METHOD = getQualifiedIdentifierMethod(); + + private static @Nullable Method getQualifiedIdentifierMethod() { + try { + return JCImport.class.getMethod("getQualifiedIdentifier"); + } catch (NoSuchMethodException e) { + return null; + } + } + private static JCFieldAccess getQualifiedIdentifier(JCTree importTree) { + checkArgument(!isModuleImport(importTree)); // Use reflection because the return type is JCTree in some versions and JCFieldAccess in others try { - return (JCFieldAccess) JCImport.class.getMethod("getQualifiedIdentifier").invoke(importTree); + return (JCFieldAccess) GET_QUALIFIED_IDENTIFIER_METHOD.invoke(importTree); + } catch (ReflectiveOperationException e) { + throw new LinkageError(e.getMessage(), e); + } + } + + private static final @Nullable Method IS_MODULE_METHOD = getIsModuleMethod(); + + private static @Nullable Method getIsModuleMethod() { + try { + return ImportTree.class.getMethod("isModule"); + } catch (NoSuchMethodException ignored) { + return null; + } + } + + private static boolean isModuleImport(JCTree importTree) { + if (IS_MODULE_METHOD == null) { + return false; + } + try { + return (boolean) IS_MODULE_METHOD.invoke(importTree); } catch (ReflectiveOperationException e) { throw new LinkageError(e.getMessage(), e); } diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index 8e863a28d..a406487f3 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -59,6 +59,7 @@ public class FormatterIntegrationTest { "I981", "I1020", "I1037") + .putAll(25, "ModuleImport") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java b/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java index 0b9dab26f..6772b42be 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/ImportOrdererTest.java @@ -820,6 +820,23 @@ public static Collection parameters() { "", "public class Blim {}", }, + }, + { + { + "import module java.base;", // + "import static java.lang.Math.min;", + "import java.util.List;", + "class Test {}", + }, + { + "import static java.lang.Math.min;", // + "", + "import module java.base;", + "", + "import java.util.List;", + "", + "class Test {}", + }, } }; ImmutableList.Builder builder = ImmutableList.builder(); diff --git a/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsTest.java b/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsTest.java index 675bc8884..d8b63ef3e 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/RemoveUnusedImportsTest.java @@ -17,7 +17,6 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.googlejavaformat.java.RemoveUnusedImports.removeUnusedImports; -import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import java.util.Collection; import org.junit.Test; @@ -255,14 +254,29 @@ public static Collection parameters() { "interface Test { private static void foo() {} }", }, }, + { + { + "import module java.base;", // + "import java.lang.Foo;", + "interface Test { private static void foo() {} }", + }, + { + "import module java.base;", // + "interface Test { private static void foo() {} }", + }, + }, }; ImmutableList.Builder builder = ImmutableList.builder(); for (String[][] inputAndOutput : inputsOutputs) { assertThat(inputAndOutput).hasLength(2); - String[] input = inputAndOutput[0]; - String[] output = inputAndOutput[1]; + String input = String.join("\n", inputAndOutput[0]) + "\n"; + String output = String.join("\n", inputAndOutput[1]) + "\n"; + if (input.contains("import module") && Runtime.version().feature() < 25) { + // TODO: cushon - remove this once the minimum supported JDK updates past 25 + continue; + } String[] parameters = { - Joiner.on('\n').join(input) + '\n', Joiner.on('\n').join(output) + '\n', + input, output, }; builder.add(parameters); } From 3aab70cd04716a9534ff5a10f5016f66b70a3281 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Fri, 17 Oct 2025 15:13:37 -0700 Subject: [PATCH 366/379] Update the IntelliJ plugin to gjf 1.30.0. PiperOrigin-RevId: 820845143 --- idea_plugin/build.gradle.kts | 13 ++++++++++--- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 645d96de1..fe8fb6938 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -19,7 +19,11 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases plugins { id("org.jetbrains.intellij.platform") version "2.9.0" - kotlin("jvm") version "2.2.0" + // See https://plugins.jetbrains.com/docs/intellij/using-kotlin.html#bundled-stdlib-versions + // This version of Kotlin will crash if your Gradle daemon is running under Java 25 (even if that + // isn't the JDK you're using to compile). So make sure to update JAVA_HOME and then + // `./gradlew --stop` + kotlin("jvm") version "2.0.21" } repositories { @@ -29,10 +33,13 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.29.0" -val pluginPatchVersion = "1" +val googleJavaFormatVersion = "1.30.0" +val pluginPatchVersion = "0" java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 } diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 1d69a056d..5262ac12e 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +

        1.30.0.0
        +
        Updated to use google-java-format 1.30.0.
        1.29.0.1
        Remove uses of deprecated IntelliJ plugin APIs.
        1.29.0.0
        From 7cc1956a2d35e2582cba0c00ba00144ebb77f1d7 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Mon, 20 Oct 2025 05:52:17 -0700 Subject: [PATCH 367/379] Add support for 2024.2 IDE versions, which were mistakenly excluded. PiperOrigin-RevId: 821611232 --- idea_plugin/build.gradle.kts | 4 ++-- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index fe8fb6938..20f98c3f3 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -34,7 +34,7 @@ repositories { // https://github.com/google/google-java-format/releases val googleJavaFormatVersion = "1.30.0" -val pluginPatchVersion = "0" +val pluginPatchVersion = "1" java { toolchain { @@ -51,7 +51,7 @@ intellijPlatform { name = "google-java-format" version = "${googleJavaFormatVersion}.${pluginPatchVersion}" ideaVersion { - sinceBuild = "243" + sinceBuild = "242" untilBuild = provider { null } } } diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 5262ac12e..39311a7da 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
        1.30.0.1
        +
        Add support for 2024.2 IDE versions, which were mistakenly excluded.
        1.30.0.0
        Updated to use google-java-format 1.30.0.
        1.29.0.1
        From 8c3026869ba3c7281f29d29636e1e3bb36b62c9e Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Fri, 24 Oct 2025 09:14:10 -0700 Subject: [PATCH 368/379] Add SnippetFormatter(JavaFormatterOptions) constructor Needed to add support for AOSP formatting in the Eclipse plugin. PiperOrigin-RevId: 823555023 --- README.md | 30 +++++++++++++++++-- .../java/SnippetFormatter.java | 10 ++++++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1539f7564..a5c400122 100644 --- a/README.md +++ b/README.md @@ -88,9 +88,33 @@ Drop it into the Eclipse [drop-ins folder](http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fp2_dropins_format.html) to activate the plugin. -The plugin adds a `google-java-format` formatter implementation that can be -configured in `Window > Preferences > Java > Code Style > Formatter > Formatter -Implementation`. +The plugin adds two formatter implementations: + +* `google-java-format`: using 2 spaces indent +* `aosp-java-format`: using 4 spaces indent + +These that can be selected in "Window" > "Preferences" > "Java" > "Code Style" > +"Formatter" > "Formatter Implementation". + +#### Eclipse JRE Config + +The plugin uses some internal classes that aren't available without extra +configuration. To use the plugin, you will need to edit the +[`eclipse.ini`](https://wiki.eclipse.org/Eclipse.ini) file. + +Open the `eclipse.ini` file in any editor and paste in these lines towards the +end (but anywhere after `-vmargs` will do): + +``` +--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +``` + +Once you've done that, restart the IDE. ### Third-party integrations diff --git a/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java b/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java index 4850ad773..60fd77ea8 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/SnippetFormatter.java @@ -60,9 +60,17 @@ public void closeBraces(int initialIndent) { } private static final int INDENTATION_SIZE = 2; - private final Formatter formatter = new Formatter(); + private final Formatter formatter; private static final CharMatcher NOT_WHITESPACE = CharMatcher.whitespace().negate(); + public SnippetFormatter() { + this(JavaFormatterOptions.defaultOptions()); + } + + public SnippetFormatter(JavaFormatterOptions formatterOptions) { + formatter = new Formatter(formatterOptions); + } + public String createIndentationString(int indentationLevel) { Preconditions.checkArgument( indentationLevel >= 0, From b723942aba4804856f55274fcb98d68afe2ff940 Mon Sep 17 00:00:00 2001 From: Michael Plump Date: Mon, 27 Oct 2025 08:11:46 -0700 Subject: [PATCH 369/379] Update the IntelliJ plugin to gjf 1.31.0. PiperOrigin-RevId: 824524915 --- idea_plugin/build.gradle.kts | 6 +++--- idea_plugin/src/main/resources/META-INF/plugin.xml | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/idea_plugin/build.gradle.kts b/idea_plugin/build.gradle.kts index 20f98c3f3..c529963f5 100644 --- a/idea_plugin/build.gradle.kts +++ b/idea_plugin/build.gradle.kts @@ -18,7 +18,7 @@ import org.jetbrains.intellij.platform.gradle.TestFrameworkType // https://github.com/JetBrains/intellij-platform-gradle-plugin/releases plugins { - id("org.jetbrains.intellij.platform") version "2.9.0" + id("org.jetbrains.intellij.platform") version "2.10.2" // See https://plugins.jetbrains.com/docs/intellij/using-kotlin.html#bundled-stdlib-versions // This version of Kotlin will crash if your Gradle daemon is running under Java 25 (even if that // isn't the JDK you're using to compile). So make sure to update JAVA_HOME and then @@ -33,8 +33,8 @@ repositories { } // https://github.com/google/google-java-format/releases -val googleJavaFormatVersion = "1.30.0" -val pluginPatchVersion = "1" +val googleJavaFormatVersion = "1.31.0" +val pluginPatchVersion = "0" java { toolchain { diff --git a/idea_plugin/src/main/resources/META-INF/plugin.xml b/idea_plugin/src/main/resources/META-INF/plugin.xml index 39311a7da..11d7d4877 100644 --- a/idea_plugin/src/main/resources/META-INF/plugin.xml +++ b/idea_plugin/src/main/resources/META-INF/plugin.xml @@ -35,6 +35,8 @@ ]]> +
        1.31.0.0
        +
        Updated to use google-java-format 1.31.0.
        1.30.0.1
        Add support for 2024.2 IDE versions, which were mistakenly excluded.
        1.30.0.0
        From 60a00f20dd6a2f754774617aa803d06ad26a5ac4 Mon Sep 17 00:00:00 2001 From: google-java-format Team Date: Mon, 27 Oct 2025 09:28:32 -0700 Subject: [PATCH 370/379] Add support for AOSP formatting in the Eclipse plugin PiperOrigin-RevId: 824551471 --- eclipse_plugin/META-INF/MANIFEST.MF | 2 +- eclipse_plugin/plugin.xml | 5 + eclipse_plugin/pom.xml | 2 +- .../java/AospJavaFormatter.java | 22 +++ .../java/GoogleJavaFormatter.java | 130 +-------------- .../java/JavaFormatterBase.java | 151 ++++++++++++++++++ 6 files changed, 183 insertions(+), 129 deletions(-) create mode 100644 eclipse_plugin/src/com/google/googlejavaformat/java/AospJavaFormatter.java create mode 100644 eclipse_plugin/src/com/google/googlejavaformat/java/JavaFormatterBase.java diff --git a/eclipse_plugin/META-INF/MANIFEST.MF b/eclipse_plugin/META-INF/MANIFEST.MF index 913245393..4170ad643 100644 --- a/eclipse_plugin/META-INF/MANIFEST.MF +++ b/eclipse_plugin/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: google-java-format Bundle-SymbolicName: google-java-format-eclipse-plugin;singleton:=true Bundle-Vendor: Google -Bundle-Version: 1.13.0 +Bundle-Version: 1.31.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Require-Bundle: org.eclipse.jdt.core;bundle-version="3.10.0", org.eclipse.jface, diff --git a/eclipse_plugin/plugin.xml b/eclipse_plugin/plugin.xml index 1fdfb6e41..e40b59aea 100644 --- a/eclipse_plugin/plugin.xml +++ b/eclipse_plugin/plugin.xml @@ -24,5 +24,10 @@ id="com.google.googlejavaformat.java.GoogleJavaFormatter" name="google-java-format"> + + diff --git a/eclipse_plugin/pom.xml b/eclipse_plugin/pom.xml index b2c6e368a..a5d8c23ae 100644 --- a/eclipse_plugin/pom.xml +++ b/eclipse_plugin/pom.xml @@ -22,7 +22,7 @@ com.google.googlejavaformat google-java-format-eclipse-plugin eclipse-plugin - 1.13.0 + 1.31.0 Google Java Format Plugin for Eclipse 4.5+ diff --git a/eclipse_plugin/src/com/google/googlejavaformat/java/AospJavaFormatter.java b/eclipse_plugin/src/com/google/googlejavaformat/java/AospJavaFormatter.java new file mode 100644 index 000000000..ac501fcb6 --- /dev/null +++ b/eclipse_plugin/src/com/google/googlejavaformat/java/AospJavaFormatter.java @@ -0,0 +1,22 @@ +/* + * Copyright 2025 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java; + +/** Runs the Google Java formatter on the given code. */ +public class AospJavaFormatter extends JavaFormatterBase { + public AospJavaFormatter() { + super(JavaFormatterOptions.builder().style(JavaFormatterOptions.Style.AOSP).build()); + } +} diff --git a/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java b/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java index 68ff908c5..5402b5f8b 100644 --- a/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java +++ b/eclipse_plugin/src/com/google/googlejavaformat/java/GoogleJavaFormatter.java @@ -14,133 +14,9 @@ package com.google.googlejavaformat.java; -import com.google.common.base.Preconditions; -import com.google.common.collect.Range; -import com.google.googlejavaformat.java.SnippetFormatter.SnippetKind; -import java.util.ArrayList; -import java.util.List; -import org.eclipse.jdt.core.dom.ASTParser; -import org.eclipse.jdt.core.formatter.CodeFormatter; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.Region; -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.text.edits.ReplaceEdit; -import org.eclipse.text.edits.TextEdit; - /** Runs the Google Java formatter on the given code. */ -public class GoogleJavaFormatter extends CodeFormatter { - - private static final int INDENTATION_SIZE = 2; - - @Override - public TextEdit format( - int kind, String source, int offset, int length, int indentationLevel, String lineSeparator) { - IRegion[] regions = new IRegion[] {new Region(offset, length)}; - return formatInternal(kind, source, regions, indentationLevel); - } - - @Override - public TextEdit format( - int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) { - return formatInternal(kind, source, regions, indentationLevel); - } - - @Override - public String createIndentationString(int indentationLevel) { - Preconditions.checkArgument( - indentationLevel >= 0, - "Indentation level cannot be less than zero. Given: %s", - indentationLevel); - int spaces = indentationLevel * INDENTATION_SIZE; - StringBuilder buf = new StringBuilder(spaces); - for (int i = 0; i < spaces; i++) { - buf.append(' '); - } - return buf.toString(); - } - - /** Runs the Google Java formatter on the given source, with only the given ranges specified. */ - private TextEdit formatInternal(int kind, String source, IRegion[] regions, int initialIndent) { - try { - boolean includeComments = - (kind & CodeFormatter.F_INCLUDE_COMMENTS) == CodeFormatter.F_INCLUDE_COMMENTS; - kind &= ~CodeFormatter.F_INCLUDE_COMMENTS; - SnippetKind snippetKind; - switch (kind) { - case ASTParser.K_EXPRESSION: - snippetKind = SnippetKind.EXPRESSION; - break; - case ASTParser.K_STATEMENTS: - snippetKind = SnippetKind.STATEMENTS; - break; - case ASTParser.K_CLASS_BODY_DECLARATIONS: - snippetKind = SnippetKind.CLASS_BODY_DECLARATIONS; - break; - case ASTParser.K_COMPILATION_UNIT: - snippetKind = SnippetKind.COMPILATION_UNIT; - break; - default: - throw new IllegalArgumentException(String.format("Unknown snippet kind: %d", kind)); - } - List replacements = - new SnippetFormatter() - .format( - snippetKind, source, rangesFromRegions(regions), initialIndent, includeComments); - if (idempotent(source, regions, replacements)) { - // Do not create edits if there's no diff. - return null; - } - // Convert replacements to text edits. - return editFromReplacements(replacements); - } catch (IllegalArgumentException | FormatterException exception) { - // Do not format on errors. - return null; - } - } - - private List> rangesFromRegions(IRegion[] regions) { - List> ranges = new ArrayList<>(); - for (IRegion region : regions) { - ranges.add(Range.closedOpen(region.getOffset(), region.getOffset() + region.getLength())); - } - return ranges; - } - - /** - * @return {@code true} if input and output texts are equal, else {@code false}. - */ - private boolean idempotent(String source, IRegion[] regions, List replacements) { - // This implementation only checks for single replacement. - if (replacements.size() == 1) { - Replacement replacement = replacements.get(0); - String output = replacement.getReplacementString(); - // Entire source case: input = output, nothing changed. - if (output.equals(source)) { - return true; - } - // Single region and single replacement case: if they are equal, nothing changed. - if (regions.length == 1) { - Range range = replacement.getReplaceRange(); - String snippet = source.substring(range.lowerEndpoint(), range.upperEndpoint()); - if (output.equals(snippet)) { - return true; - } - } - } - return false; - } - - private TextEdit editFromReplacements(List replacements) { - // Split the replacements that cross line boundaries. - TextEdit edit = new MultiTextEdit(); - for (Replacement replacement : replacements) { - Range replaceRange = replacement.getReplaceRange(); - edit.addChild( - new ReplaceEdit( - replaceRange.lowerEndpoint(), - replaceRange.upperEndpoint() - replaceRange.lowerEndpoint(), - replacement.getReplacementString())); - } - return edit; +public class GoogleJavaFormatter extends JavaFormatterBase { + public GoogleJavaFormatter() { + super(JavaFormatterOptions.defaultOptions()); } } diff --git a/eclipse_plugin/src/com/google/googlejavaformat/java/JavaFormatterBase.java b/eclipse_plugin/src/com/google/googlejavaformat/java/JavaFormatterBase.java new file mode 100644 index 000000000..abeb17297 --- /dev/null +++ b/eclipse_plugin/src/com/google/googlejavaformat/java/JavaFormatterBase.java @@ -0,0 +1,151 @@ +/* + * Copyright 2025 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.googlejavaformat.java; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Range; +import com.google.googlejavaformat.java.SnippetFormatter.SnippetKind; +import java.util.ArrayList; +import java.util.List; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.formatter.CodeFormatter; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Region; +import org.eclipse.text.edits.MultiTextEdit; +import org.eclipse.text.edits.ReplaceEdit; +import org.eclipse.text.edits.TextEdit; + +/** Runs the Google Java formatter on the given code. */ +public class JavaFormatterBase extends CodeFormatter { + + private static final int INDENTATION_SIZE = 2; + private final JavaFormatterOptions formatterOptions; + + JavaFormatterBase(JavaFormatterOptions formatterOptions) { + this.formatterOptions = formatterOptions; + } + + @Override + public TextEdit format( + int kind, String source, int offset, int length, int indentationLevel, String lineSeparator) { + IRegion[] regions = new IRegion[] {new Region(offset, length)}; + return formatInternal(kind, source, regions, indentationLevel); + } + + @Override + public TextEdit format( + int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) { + return formatInternal(kind, source, regions, indentationLevel); + } + + @Override + public String createIndentationString(int indentationLevel) { + Preconditions.checkArgument( + indentationLevel >= 0, + "Indentation level cannot be less than zero. Given: %s", + indentationLevel); + int spaces = indentationLevel * INDENTATION_SIZE; + StringBuilder buf = new StringBuilder(spaces); + for (int i = 0; i < spaces; i++) { + buf.append(' '); + } + return buf.toString(); + } + + /** Runs the Google Java formatter on the given source, with only the given ranges specified. */ + private TextEdit formatInternal(int kind, String source, IRegion[] regions, int initialIndent) { + try { + boolean includeComments = + (kind & CodeFormatter.F_INCLUDE_COMMENTS) == CodeFormatter.F_INCLUDE_COMMENTS; + kind &= ~CodeFormatter.F_INCLUDE_COMMENTS; + SnippetKind snippetKind; + switch (kind) { + case ASTParser.K_EXPRESSION: + snippetKind = SnippetKind.EXPRESSION; + break; + case ASTParser.K_STATEMENTS: + snippetKind = SnippetKind.STATEMENTS; + break; + case ASTParser.K_CLASS_BODY_DECLARATIONS: + snippetKind = SnippetKind.CLASS_BODY_DECLARATIONS; + break; + case ASTParser.K_COMPILATION_UNIT: + snippetKind = SnippetKind.COMPILATION_UNIT; + break; + default: + throw new IllegalArgumentException(String.format("Unknown snippet kind: %d", kind)); + } + List replacements = + new SnippetFormatter(formatterOptions) + .format( + snippetKind, source, rangesFromRegions(regions), initialIndent, includeComments); + if (idempotent(source, regions, replacements)) { + // Do not create edits if there's no diff. + return null; + } + // Convert replacements to text edits. + return editFromReplacements(replacements); + } catch (IllegalArgumentException | FormatterException exception) { + // Do not format on errors. + return null; + } + } + + private List> rangesFromRegions(IRegion[] regions) { + List> ranges = new ArrayList<>(); + for (IRegion region : regions) { + ranges.add(Range.closedOpen(region.getOffset(), region.getOffset() + region.getLength())); + } + return ranges; + } + + /** + * @return {@code true} if input and output texts are equal, else {@code false}. + */ + private boolean idempotent(String source, IRegion[] regions, List replacements) { + // This implementation only checks for single replacement. + if (replacements.size() == 1) { + Replacement replacement = replacements.get(0); + String output = replacement.getReplacementString(); + // Entire source case: input = output, nothing changed. + if (output.equals(source)) { + return true; + } + // Single region and single replacement case: if they are equal, nothing changed. + if (regions.length == 1) { + Range range = replacement.getReplaceRange(); + String snippet = source.substring(range.lowerEndpoint(), range.upperEndpoint()); + if (output.equals(snippet)) { + return true; + } + } + } + return false; + } + + private TextEdit editFromReplacements(List replacements) { + // Split the replacements that cross line boundaries. + TextEdit edit = new MultiTextEdit(); + for (Replacement replacement : replacements) { + Range replaceRange = replacement.getReplaceRange(); + edit.addChild( + new ReplaceEdit( + replaceRange.lowerEndpoint(), + replaceRange.upperEndpoint() - replaceRange.lowerEndpoint(), + replacement.getReplacementString())); + } + return edit; + } +} From 052881ad1ed8bbe1eb160b7ba1d3eed24ecc1a5d Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 28 Oct 2025 20:22:52 +0100 Subject: [PATCH 371/379] Update CI GraalVM Java version to 25 #1257 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37779bd85..735cccaf7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,7 +93,7 @@ jobs: - name: "Set up GraalVM ${{ matrix.java }}" uses: graalvm/setup-graalvm@v1 with: - java-version: "21" + java-version: "25" distribution: "graalvm-community" github-token: ${{ secrets.GITHUB_TOKEN }} native-image-job-reports: "true" From d1d1f4dd647b253e4436858f48c62d881eec8c9b Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 28 Oct 2025 20:28:36 +0100 Subject: [PATCH 372/379] Update Java version in release workflow to 25 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1639d1e94..43dd0ed29 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -102,7 +102,7 @@ jobs: - name: "Set up GraalVM" uses: graalvm/setup-graalvm@v1 with: - java-version: "21" + java-version: "25" distribution: "graalvm-community" github-token: ${{ secrets.GITHUB_TOKEN }} native-image-job-reports: "true" From eb43facd4d83aa289d2ccfeff0a3929be30e683b Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 1 Dec 2025 00:57:00 -0800 Subject: [PATCH 373/379] Create a FormattingFiler factory that disables formatting during header compilation PiperOrigin-RevId: 838646724 --- .../java/filer/FormattingFiler.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java index 2f2e33cbe..f5cc7fd09 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java +++ b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java @@ -20,6 +20,7 @@ import java.io.IOException; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; +import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; import javax.tools.FileObject; import javax.tools.JavaFileManager; @@ -38,8 +39,25 @@ public final class FormattingFiler implements Filer { private final Messager messager; /** + * Create a new {@link FormattingFiler}. + * + * @param processingEnv the processing environment + */ + public static Filer create(ProcessingEnvironment processingEnv) { + Filer delegate = processingEnv.getFiler(); + if (processingEnv.getOptions().containsKey("experimental_turbine_hjar")) { + return delegate; + } + return new FormattingFiler(delegate, processingEnv.getMessager()); + } + + /** + * Create a new {@link FormattingFiler}. + * * @param delegate filer to decorate + * @deprecated prefer {@link #create(ProcessingEnvironment)} */ + @Deprecated public FormattingFiler(Filer delegate) { this(delegate, null); } @@ -50,7 +68,9 @@ public FormattingFiler(Filer delegate) { * * @param delegate filer to decorate * @param messager to log warnings to + * @deprecated prefer {@link #create(ProcessingEnvironment)} */ + @Deprecated public FormattingFiler(Filer delegate, @Nullable Messager messager) { this.delegate = checkNotNull(delegate); this.messager = messager; From 8e8db81719e9f5b7efae279136f975f8a9846f4a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 1 Dec 2025 09:33:42 -0800 Subject: [PATCH 374/379] Update Error Prone version PiperOrigin-RevId: 838811354 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f3668d649..46306c196 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ 32.1.3-jre 1.4.0 1.0.0 - 2.42.0 + 2.45.0 1.9 1.0.1 3.6.3 From 343d9aa7276b2c681d0be4239ae38d6730b2395a Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 3 Dec 2025 06:59:03 -0800 Subject: [PATCH 375/379] Consolidate end position handling in google-java-format PiperOrigin-RevId: 839739629 --- .../java/RemoveUnusedImports.java | 3 ++- .../googlejavaformat/java/StringWrapper.java | 22 +++++++------------ .../google/googlejavaformat/java/Trees.java | 10 +++++++-- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index 4035ce319..a1c722b7e 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -17,6 +17,7 @@ package com.google.googlejavaformat.java; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.googlejavaformat.java.Trees.getEndPosition; import static java.lang.Math.max; import static java.nio.charset.StandardCharsets.UTF_8; @@ -284,7 +285,7 @@ private static RangeMap buildReplacements( continue; } // delete the import - int endPosition = importTree.getEndPosition(unit.endPositions); + int endPosition = getEndPosition(importTree, unit); endPosition = max(CharMatcher.isNot(' ').indexIn(contents, endPosition), endPosition); String sep = Newlines.guessLineSeparator(contents); if (endPosition + sep.length() < contents.length() diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index f1014e52f..9d917cc4a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -16,6 +16,8 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.Iterables.getLast; +import static com.google.googlejavaformat.java.Trees.getEndPosition; +import static com.google.googlejavaformat.java.Trees.getStartPosition; import static java.lang.Math.min; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.stream.Collectors.joining; @@ -171,7 +173,7 @@ public Void visitLiteral(LiteralTree literalTree, Void aVoid) { && ((MemberSelectTree) parent).getExpression().equals(literalTree)) { return null; } - int endPosition = getEndPosition(unit, literalTree); + int endPosition = getEndPosition(literalTree, unit); int lineEnd = endPosition; while (Newlines.hasNewlineAt(input, lineEnd) == -1) { lineEnd++; @@ -188,7 +190,7 @@ private void indentTextBlocks( TreeRangeMap replacements, List textBlocks) { for (Tree tree : textBlocks) { int startPosition = lineMap.getStartPosition(lineMap.getLineNumber(getStartPosition(tree))); - int endPosition = getEndPosition(unit, tree); + int endPosition = getEndPosition(tree, unit); String text = input.substring(startPosition, endPosition); int leadingWhitespace = CharMatcher.whitespace().negate().indexIn(text); @@ -254,7 +256,7 @@ private void wrapLongStrings( // Handling leaving trailing non-string tokens at the end of the literal, // e.g. the trailing `);` in `foo("...");`. - int end = getEndPosition(unit, getLast(flat)); + int end = getEndPosition(getLast(flat), unit); int lineEnd = end; while (Newlines.hasNewlineAt(input, lineEnd) == -1) { lineEnd++; @@ -264,7 +266,7 @@ private void wrapLongStrings( // Get the original source text of the string literals, excluding `"` and `+`. ImmutableList components = stringComponents(input, unit, flat); replacements.put( - Range.closedOpen(getStartPosition(flat.get(0)), getEndPosition(unit, getLast(flat))), + Range.closedOpen(getStartPosition(flat.get(0)), getEndPosition(getLast(flat), unit)), reflow(separator, columnLimit, startColumn, trailing, components, first.get())); } } @@ -280,7 +282,7 @@ private static ImmutableList stringComponents( StringBuilder piece = new StringBuilder(); for (Tree tree : flat) { // adjust for leading and trailing double quotes - String text = input.substring(getStartPosition(tree) + 1, getEndPosition(unit, tree) - 1); + String text = input.substring(getStartPosition(tree) + 1, getEndPosition(tree, unit) - 1); int start = 0; for (int idx = 0; idx < text.length(); idx++) { if (CharMatcher.whitespace().matches(text.charAt(idx))) { @@ -453,20 +455,12 @@ && noComments(input, unit, flat.get(endIdx - 1), flat.get(endIdx))) { private static boolean noComments( String input, JCTree.JCCompilationUnit unit, Tree one, Tree two) { return STRING_CONCAT_DELIMITER.matchesAllOf( - input.subSequence(getEndPosition(unit, one), getStartPosition(two))); + input.subSequence(getEndPosition(one, unit), getStartPosition(two))); } public static final CharMatcher STRING_CONCAT_DELIMITER = CharMatcher.whitespace().or(CharMatcher.anyOf("\"+")); - private static int getEndPosition(JCTree.JCCompilationUnit unit, Tree tree) { - return ((JCTree) tree).getEndPosition(unit.endPositions); - } - - private static int getStartPosition(Tree tree) { - return ((JCTree) tree).getStartPosition(); - } - /** * Returns true if any lines in the given Java source exceed the column limit, or contain a {@code * """} that could indicate a text block. diff --git a/core/src/main/java/com/google/googlejavaformat/java/Trees.java b/core/src/main/java/com/google/googlejavaformat/java/Trees.java index ded219644..a16ce17c0 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Trees.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Trees.java @@ -15,6 +15,7 @@ package com.google.googlejavaformat.java; import com.sun.source.tree.ClassTree; +import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.CompoundAssignmentTree; import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.IdentifierTree; @@ -24,6 +25,7 @@ import com.sun.source.tree.Tree; import com.sun.source.util.TreePath; import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.Pretty; import com.sun.tools.javac.tree.TreeInfo; import java.io.IOError; @@ -44,8 +46,12 @@ static int getStartPosition(Tree expression) { /** Returns the source end position of the node. */ static int getEndPosition(Tree expression, TreePath path) { - return ((JCTree) expression) - .getEndPosition(((JCTree.JCCompilationUnit) path.getCompilationUnit()).endPositions); + return getEndPosition(expression, path.getCompilationUnit()); + } + + /** Returns the source end position of the node. */ + public static int getEndPosition(Tree tree, CompilationUnitTree unit) { + return ((JCTree) tree).getEndPosition(((JCCompilationUnit) unit).endPositions); } /** Returns the source text for the node. */ From f5f92bf22df67151d719dbcbfe9fdf39c0d7e014 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Sat, 6 Dec 2025 08:31:39 -0800 Subject: [PATCH 376/379] Internal change PiperOrigin-RevId: 841130473 --- .../google/googlejavaformat/java/filer/FormattingFiler.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java index f5cc7fd09..e8da9fac9 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java +++ b/core/src/main/java/com/google/googlejavaformat/java/filer/FormattingFiler.java @@ -58,7 +58,8 @@ public static Filer create(ProcessingEnvironment processingEnv) { * @deprecated prefer {@link #create(ProcessingEnvironment)} */ @Deprecated - public FormattingFiler(Filer delegate) { + public + FormattingFiler(Filer delegate) { this(delegate, null); } @@ -71,7 +72,8 @@ public FormattingFiler(Filer delegate) { * @deprecated prefer {@link #create(ProcessingEnvironment)} */ @Deprecated - public FormattingFiler(Filer delegate, @Nullable Messager messager) { + public + FormattingFiler(Filer delegate, @Nullable Messager messager) { this.delegate = checkNotNull(delegate); this.messager = messager; } From 4b4d087a686e5c5b1993278216f61870f58761f6 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 12 Dec 2025 07:59:49 -0800 Subject: [PATCH 377/379] Consolidate uses of javac's parser in google-java-format PiperOrigin-RevId: 843691248 --- .../googlejavaformat/java/Formatter.java | 50 ++------------ .../java/FormatterException.java | 8 ++- .../java/RemoveUnusedImports.java | 52 ++------------ .../googlejavaformat/java/StringWrapper.java | 45 ++---------- .../google/googlejavaformat/java/Trees.java | 68 +++++++++++++++++++ 5 files changed, 87 insertions(+), 136 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java index c81e69707..ff87eaab7 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Formatter.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Formatter.java @@ -14,10 +14,8 @@ package com.google.googlejavaformat.java; -import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import com.google.common.collect.Range; import com.google.common.collect.RangeSet; @@ -31,25 +29,14 @@ import com.google.googlejavaformat.Newlines; import com.google.googlejavaformat.Op; import com.google.googlejavaformat.OpsBuilder; -import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.parser.JavacParser; -import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Log; -import com.sun.tools.javac.util.Options; -import java.io.IOError; import java.io.IOException; -import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.tools.Diagnostic; -import javax.tools.DiagnosticCollector; -import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; -import javax.tools.SimpleJavaFileObject; -import javax.tools.StandardLocation; /** * This is google-java-format, a new Java formatter that follows the Google Java Style Guide quite @@ -112,40 +99,13 @@ public Formatter(JavaFormatterOptions options) { static void format(final JavaInput javaInput, JavaOutput javaOutput, JavaFormatterOptions options) throws FormatterException { Context context = new Context(); - DiagnosticCollector diagnostics = new DiagnosticCollector<>(); - context.put(DiagnosticListener.class, diagnostics); - Options.instance(context).put("allowStringFolding", "false"); - Options.instance(context).put("--enable-preview", "true"); - JCCompilationUnit unit; - JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8); - try { - fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of()); - } catch (IOException e) { - // impossible - throw new IOError(e); - } - SimpleJavaFileObject source = - new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) { - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { - return javaInput.getText(); - } - }; - Log.instance(context).useSource(source); - ParserFactory parserFactory = ParserFactory.instance(context); - JavacParser parser = - parserFactory.newParser( - javaInput.getText(), - /* keepDocComments= */ true, - /* keepEndPos= */ true, - /* keepLineMap= */ true); - unit = parser.parseCompilationUnit(); - unit.sourcefile = source; + List> errorDiagnostics = new ArrayList<>(); + JCCompilationUnit unit = + Trees.parse( + context, errorDiagnostics, /* allowStringFolding= */ false, javaInput.getText()); javaInput.setCompilationUnit(unit); - Iterable> errorDiagnostics = - Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic); - if (!Iterables.isEmpty(errorDiagnostics)) { + if (!errorDiagnostics.isEmpty()) { throw FormatterException.fromJavacDiagnostics(errorDiagnostics); } OpsBuilder builder = new OpsBuilder(javaInput, javaOutput); diff --git a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java index 5ca939bbb..7fe67073a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java +++ b/core/src/main/java/com/google/googlejavaformat/java/FormatterException.java @@ -14,12 +14,12 @@ package com.google.googlejavaformat.java; +import static com.google.common.collect.ImmutableList.toImmutableList; import static java.util.Locale.ENGLISH; import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import com.google.googlejavaformat.FormatterDiagnostic; import java.util.List; import java.util.regex.Pattern; @@ -49,9 +49,11 @@ public List diagnostics() { } public static FormatterException fromJavacDiagnostics( - Iterable> diagnostics) { + List> diagnostics) { return new FormatterException( - Iterables.transform(diagnostics, FormatterException::toFormatterDiagnostic)); + diagnostics.stream() + .map(FormatterException::toFormatterDiagnostic) + .collect(toImmutableList())); } private static FormatterDiagnostic toFormatterDiagnostic(Diagnostic input) { diff --git a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java index a1c722b7e..18745a809 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java +++ b/core/src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java @@ -19,12 +19,9 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.googlejavaformat.java.Trees.getEndPosition; import static java.lang.Math.max; -import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.CharMatcher; import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; import com.google.common.collect.Range; import com.google.common.collect.RangeMap; @@ -43,9 +40,6 @@ import com.sun.source.util.TreePathScanner; import com.sun.source.util.TreeScanner; import com.sun.tools.javac.api.JavacTrees; -import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.parser.JavacParser; -import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.tree.DCTree; import com.sun.tools.javac.tree.DCTree.DCReference; import com.sun.tools.javac.tree.JCTree; @@ -53,22 +47,14 @@ import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCImport; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Log; -import com.sun.tools.javac.util.Options; -import java.io.IOError; -import java.io.IOException; import java.lang.reflect.Method; -import java.net.URI; +import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.tools.Diagnostic; -import javax.tools.DiagnosticCollector; -import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; -import javax.tools.SimpleJavaFileObject; -import javax.tools.StandardLocation; import org.jspecify.annotations.Nullable; /** @@ -231,38 +217,10 @@ public static String removeUnusedImports(final String contents) throws Formatter private static JCCompilationUnit parse(Context context, String javaInput) throws FormatterException { - DiagnosticCollector diagnostics = new DiagnosticCollector<>(); - context.put(DiagnosticListener.class, diagnostics); - Options.instance(context).put("--enable-preview", "true"); - Options.instance(context).put("allowStringFolding", "false"); - JCCompilationUnit unit; - JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8); - try { - fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of()); - } catch (IOException e) { - // impossible - throw new IOError(e); - } - SimpleJavaFileObject source = - new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) { - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { - return javaInput; - } - }; - Log.instance(context).useSource(source); - ParserFactory parserFactory = ParserFactory.instance(context); - JavacParser parser = - parserFactory.newParser( - javaInput, - /* keepDocComments= */ true, - /* keepEndPos= */ true, - /* keepLineMap= */ true); - unit = parser.parseCompilationUnit(); - unit.sourcefile = source; - Iterable> errorDiagnostics = - Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic); - if (!Iterables.isEmpty(errorDiagnostics)) { + List> errorDiagnostics = new ArrayList<>(); + JCTree.JCCompilationUnit unit = + Trees.parse(context, errorDiagnostics, /* allowStringFolding= */ false, javaInput); + if (!errorDiagnostics.isEmpty()) { // error handling is done during formatting throw FormatterException.fromJavacDiagnostics(errorDiagnostics); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java index 9d917cc4a..22110ad8a 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java +++ b/core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java @@ -19,14 +19,12 @@ import static com.google.googlejavaformat.java.Trees.getEndPosition; import static com.google.googlejavaformat.java.Trees.getStartPosition; import static java.lang.Math.min; -import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.stream.Collectors.joining; import com.google.common.base.CharMatcher; import com.google.common.base.Strings; import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import com.google.common.collect.Range; import com.google.common.collect.TreeRangeMap; import com.google.googlejavaformat.Newlines; @@ -37,17 +35,9 @@ import com.sun.source.tree.Tree.Kind; import com.sun.source.util.TreePath; import com.sun.source.util.TreePathScanner; -import com.sun.tools.javac.file.JavacFileManager; -import com.sun.tools.javac.parser.JavacParser; -import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.Log; -import com.sun.tools.javac.util.Options; import com.sun.tools.javac.util.Position; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.net.URI; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; @@ -56,11 +46,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import javax.tools.Diagnostic; -import javax.tools.DiagnosticCollector; -import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; -import javax.tools.SimpleJavaFileObject; -import javax.tools.StandardLocation; /** Wraps string literals that exceed the column limit. */ public final class StringWrapper { @@ -480,34 +466,11 @@ private static boolean needWrapping(int columnLimit, String input) { /** Parses the given Java source. */ private static JCTree.JCCompilationUnit parse(String source, boolean allowStringFolding) throws FormatterException { - DiagnosticCollector diagnostics = new DiagnosticCollector<>(); + List> errorDiagnostics = new ArrayList<>(); Context context = new Context(); - context.put(DiagnosticListener.class, diagnostics); - Options.instance(context).put("--enable-preview", "true"); - Options.instance(context).put("allowStringFolding", Boolean.toString(allowStringFolding)); - JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8); - try { - fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of()); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - SimpleJavaFileObject sjfo = - new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) { - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) { - return source; - } - }; - Log.instance(context).useSource(sjfo); - ParserFactory parserFactory = ParserFactory.instance(context); - JavacParser parser = - parserFactory.newParser( - source, /* keepDocComments= */ true, /* keepEndPos= */ true, /* keepLineMap= */ true); - JCTree.JCCompilationUnit unit = parser.parseCompilationUnit(); - unit.sourcefile = sjfo; - Iterable> errorDiagnostics = - Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic); - if (!Iterables.isEmpty(errorDiagnostics)) { + JCTree.JCCompilationUnit unit = + Trees.parse(context, errorDiagnostics, allowStringFolding, source); + if (!errorDiagnostics.isEmpty()) { // error handling is done during formatting throw FormatterException.fromJavacDiagnostics(errorDiagnostics); } diff --git a/core/src/main/java/com/google/googlejavaformat/java/Trees.java b/core/src/main/java/com/google/googlejavaformat/java/Trees.java index a16ce17c0..6b053771b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/Trees.java +++ b/core/src/main/java/com/google/googlejavaformat/java/Trees.java @@ -14,6 +14,11 @@ package com.google.googlejavaformat.java; +import static com.google.googlejavaformat.java.Trees.getEndPosition; +import static com.google.googlejavaformat.java.Trees.getStartPosition; +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.common.collect.ImmutableList; import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.CompoundAssignmentTree; @@ -24,13 +29,26 @@ import com.sun.source.tree.ParenthesizedTree; import com.sun.source.tree.Tree; import com.sun.source.util.TreePath; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.parser.JavacParser; +import com.sun.tools.javac.parser.ParserFactory; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.Pretty; import com.sun.tools.javac.tree.TreeInfo; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Options; import java.io.IOError; import java.io.IOException; +import java.net.URI; +import java.util.List; import javax.lang.model.element.Name; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticListener; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardLocation; /** Utilities for working with {@link Tree}s. */ class Trees { @@ -118,4 +136,54 @@ static ClassTree getEnclosingTypeDeclaration(TreePath path) { static ExpressionTree skipParen(ExpressionTree node) { return ((ParenthesizedTree) node).getExpression(); } + + static JCCompilationUnit parse( + Context context, + List> errorDiagnostics, + boolean allowStringFolding, + String javaInput) { + DiagnosticListener diagnostics = + diagnostic -> { + if (errorDiagnostic(diagnostic)) { + errorDiagnostics.add(diagnostic); + } + }; + context.put(DiagnosticListener.class, diagnostics); + Options.instance(context).put("--enable-preview", "true"); + Options.instance(context).put("allowStringFolding", Boolean.toString(allowStringFolding)); + JavacFileManager fileManager = new JavacFileManager(context, /* register= */ true, UTF_8); + try { + fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of()); + } catch (IOException e) { + // impossible + throw new IOError(e); + } + SimpleJavaFileObject source = + new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) { + @Override + public String getCharContent(boolean ignoreEncodingErrors) { + return javaInput; + } + }; + Log.instance(context).useSource(source); + ParserFactory parserFactory = ParserFactory.instance(context); + JavacParser parser = + parserFactory.newParser( + javaInput, + /* keepDocComments= */ true, + /* keepEndPos= */ true, + /* keepLineMap= */ true); + JCCompilationUnit unit = parser.parseCompilationUnit(); + unit.sourcefile = source; + return unit; + } + + private static boolean errorDiagnostic(Diagnostic input) { + if (input.getKind() != Diagnostic.Kind.ERROR) { + return false; + } + // accept constructor-like method declarations that don't match the name of their + // enclosing class + return !input.getCode().equals("compiler.err.invalid.meth.decl.ret.type.req"); + } } From 737b0032b3a18eb6e458271ea440098c166f6c2d Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 19 Jan 2026 23:38:25 -0800 Subject: [PATCH 378/379] Support Instance Main Methods in google-java-format https://github.com/google/google-java-format/issues/1216 PiperOrigin-RevId: 858436442 --- .../googlejavaformat/java/JavaInputAstVisitor.java | 13 +++++++++++++ .../java/FormatterIntegrationTest.java | 2 +- .../java/testdata/InstanceMain.input | 5 +++++ .../java/testdata/InstanceMain.output | 5 +++++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/InstanceMain.input create mode 100644 core/src/test/resources/com/google/googlejavaformat/java/testdata/InstanceMain.output diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index a2a32e79c..2f0373ec6 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -453,8 +453,15 @@ protected void dropEmptyDeclarations() { } } + // Replace with Flags.IMPLICIT_CLASS once JDK 25 is the minimum supported version + private static final int IMPLICIT_CLASS = 1 << 19; + @Override public Void visitClass(ClassTree tree, Void unused) { + if ((TreeInfo.flags((JCTree) tree) & IMPLICIT_CLASS) == IMPLICIT_CLASS) { + visitImplicitClass(tree); + return null; + } switch (tree.getKind()) { case ANNOTATION_TYPE -> visitAnnotationType(tree); case CLASS, INTERFACE -> visitClassDeclaration(tree); @@ -465,6 +472,12 @@ public Void visitClass(ClassTree tree, Void unused) { return null; } + private void visitImplicitClass(ClassTree node) { + builder.open(minusTwo); + addBodyDeclarations(node.getMembers(), BracesOrNot.NO, FirstDeclarationsOrNot.YES); + builder.close(); + } + public void visitAnnotationType(ClassTree node) { sync(node); builder.open(ZERO); diff --git a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java index a406487f3..7b3c3e889 100644 --- a/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java +++ b/core/src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java @@ -59,7 +59,7 @@ public class FormatterIntegrationTest { "I981", "I1020", "I1037") - .putAll(25, "ModuleImport") + .putAll(25, "ModuleImport", "InstanceMain") .build(); @Parameters(name = "{index}: {0}") diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/InstanceMain.input b/core/src/test/resources/com/google/googlejavaformat/java/testdata/InstanceMain.input new file mode 100644 index 000000000..5967d6c66 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/InstanceMain.input @@ -0,0 +1,5 @@ +String greeting = "Hello, World!"; + +void main() { + System.out.println(greeting); +} diff --git a/core/src/test/resources/com/google/googlejavaformat/java/testdata/InstanceMain.output b/core/src/test/resources/com/google/googlejavaformat/java/testdata/InstanceMain.output new file mode 100644 index 000000000..6f152da61 --- /dev/null +++ b/core/src/test/resources/com/google/googlejavaformat/java/testdata/InstanceMain.output @@ -0,0 +1,5 @@ +String greeting = "Hello, World!"; + +void main() { + System.out.println(greeting); +} From 62edae4f12bd44e9ddd0e453438e774adf9e91b7 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 27 Jan 2026 07:21:34 -0800 Subject: [PATCH 379/379] Remove workaround for https://bugs.openjdk.org/browse/JDK-8027682 The bug was fixed in JDK 21, and google-java-format no longer supports earlier versions The corresponding tests were removed in https://github.com/google/google-java-format/commit/18f835849551f81d60d582300a0a3c585b5774b4 PiperOrigin-RevId: 861709714 --- .../google/googlejavaformat/java/JavaInputAstVisitor.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java index 2f0373ec6..66cb9d31b 100644 --- a/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java +++ b/core/src/main/java/com/google/googlejavaformat/java/JavaInputAstVisitor.java @@ -410,11 +410,6 @@ public Void visitCompilationUnit(CompilationUnitTree node, Void unused) { } dropEmptyDeclarations(); for (Tree type : node.getTypeDecls()) { - if (type.getKind() == Tree.Kind.IMPORT) { - // javac treats extra semicolons in the import list as type declarations - // TODO(cushon): remove this if https://bugs.openjdk.java.net/browse/JDK-8027682 is fixed - continue; - } if (afterFirstToken) { builder.blankLineWanted(BlankLineWanted.YES); } @@ -1244,8 +1239,6 @@ public Void visitImport(ImportTree node, Void unused) { } visitName(node.getQualifiedIdentifier()); token(";"); - // TODO(cushon): remove this if https://bugs.openjdk.java.net/browse/JDK-8027682 is fixed - dropEmptyDeclarations(); return null; }