diff --git a/changelog/@unreleased/pr-986.v2.yml b/changelog/@unreleased/pr-986.v2.yml new file mode 100644 index 000000000..7e7241c25 --- /dev/null +++ b/changelog/@unreleased/pr-986.v2.yml @@ -0,0 +1,5 @@ +type: feature +fix: + description: Add option to IDEA plugin (and CLI) to format JavaDoc + links: + - https://github.com/palantir/palantir-java-format/pull/986 diff --git a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/FormatterProvider.java b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/FormatterProvider.java index dd1228461..f1b39fe2e 100644 --- a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/FormatterProvider.java +++ b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/FormatterProvider.java @@ -19,6 +19,7 @@ import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.LoadingCache; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Functions; import com.google.common.base.Preconditions; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManager; @@ -32,6 +33,7 @@ import com.intellij.openapi.util.SystemInfo; import com.palantir.javaformat.bootstrap.BootstrappingFormatterService; import com.palantir.javaformat.java.FormatterService; +import com.palantir.javaformat.java.JavaFormatterOptions; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; @@ -64,7 +66,9 @@ Optional get(Project project, PalantirJavaFormatSettings setti project, getSdkVersion(project), settings.getImplementationClassPath(), - settings.injectedVersionIsOutdated())); + settings.injectedVersionIsOutdated(), + settings.getStyle(), + settings.isFormatJavadoc())); } private static Optional createFormatter(FormatterCacheKey cacheKey) { @@ -76,20 +80,28 @@ private static Optional createFormatter(FormatterCacheKey cach List implementationClasspath = getImplementationUrls(cacheKey.implementationClassPath, cacheKey.useBundledImplementation); + JavaFormatterOptions options = JavaFormatterOptions.builder() + .formatJavadoc(cacheKey.formatJavadoc) + .style(cacheKey.style != null ? cacheKey.style : JavaFormatterOptions.Style.PALANTIR) + .build(); + // When running with JDK 15+ or using newer language features, we use the bootstrapping formatter which injects // required "--add-exports" args. if (useBootstrappingFormatter( jdkMajorVersion, ApplicationInfo.getInstance().getBuild())) { Path jdkPath = getJdkPath(cacheKey.project); log.info("Using bootstrapping formatter with jdk version {} and path: {}", jdkMajorVersion, jdkPath); - return Optional.of(new BootstrappingFormatterService(jdkPath, jdkMajorVersion, implementationClasspath)); + return Optional.of( + new BootstrappingFormatterService(jdkPath, jdkMajorVersion, implementationClasspath, options)); } // Use "in-process" formatter service log.info("Using in-process formatter for jdk version {}", jdkMajorVersion); URL[] implementationUrls = toUrlsUnchecked(implementationClasspath); ClassLoader classLoader = new URLClassLoader(implementationUrls, FormatterService.class.getClassLoader()); - return ServiceLoader.load(FormatterService.class, classLoader).findFirst(); + return ServiceLoader.load(FormatterService.class, classLoader) + .findFirst() + .map(f -> f.withOptions(Functions.constant(options))); } /** @@ -199,16 +211,22 @@ private static final class FormatterCacheKey { private final OptionalInt jdkMajorVersion; private final Optional> implementationClassPath; private final boolean useBundledImplementation; + private final boolean formatJavadoc; + private final JavaFormatterOptions.Style style; FormatterCacheKey( Project project, OptionalInt jdkMajorVersion, Optional> implementationClassPath, - boolean useBundledImplementation) { + boolean useBundledImplementation, + JavaFormatterOptions.Style style, + boolean formatJavadoc) { this.project = project; this.jdkMajorVersion = jdkMajorVersion; this.implementationClassPath = implementationClassPath; this.useBundledImplementation = useBundledImplementation; + this.style = style; + this.formatJavadoc = formatJavadoc; } @Override @@ -223,12 +241,15 @@ public boolean equals(Object o) { return Objects.equals(jdkMajorVersion, that.jdkMajorVersion) && useBundledImplementation == that.useBundledImplementation && Objects.equals(project, that.project) - && Objects.equals(implementationClassPath, that.implementationClassPath); + && Objects.equals(implementationClassPath, that.implementationClassPath) + && Objects.equals(style, that.style) + && Objects.equals(formatJavadoc, that.formatJavadoc); } @Override public int hashCode() { - return Objects.hash(project, jdkMajorVersion, implementationClassPath, useBundledImplementation); + return Objects.hash( + project, jdkMajorVersion, implementationClassPath, useBundledImplementation, style, formatJavadoc); } } } diff --git a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/InitialConfigurationStartupActivity.java b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/InitialConfigurationStartupActivity.java index 941d1603f..2916a67fe 100644 --- a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/InitialConfigurationStartupActivity.java +++ b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/InitialConfigurationStartupActivity.java @@ -26,6 +26,7 @@ public void runActivity(@NotNull Project project) { PalantirJavaFormatSettings settings = PalantirJavaFormatSettings.getInstance(project); if (settings.isUninitialized()) { settings.setEnabled(false); + settings.setFormatJavadoc(false); } } } diff --git a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatConfigurable.form b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatConfigurable.form index 9f05f8bb5..22951dafc 100644 --- a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatConfigurable.form +++ b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatConfigurable.form @@ -1,6 +1,6 @@
- + @@ -8,22 +8,23 @@ - + - + - + + - + - + @@ -31,13 +32,13 @@ - + - + @@ -45,7 +46,7 @@ - + @@ -53,7 +54,7 @@ - + @@ -61,12 +62,20 @@ - + + + + + + + + + diff --git a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatConfigurable.java b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatConfigurable.java index 40e289cc7..983a3a533 100644 --- a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatConfigurable.java +++ b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatConfigurable.java @@ -40,6 +40,7 @@ class PalantirJavaFormatConfigurable extends BaseConfigurable implements Searcha private final Project project; private JPanel panel; private JCheckBox enable; + private JCheckBox formatJavadoc; private JComboBox styleComboBox; private JLabel formatterVersion; private JLabel pluginVersion; @@ -82,6 +83,7 @@ public JComponent createComponent() { public void apply() throws ConfigurationException { PalantirJavaFormatSettings settings = PalantirJavaFormatSettings.getInstance(project); settings.setEnabled(enable.isSelected() ? EnabledState.ENABLED : getDisabledState()); + settings.setFormatJavadoc(formatJavadoc.isSelected()); settings.setStyle(((UiFormatterStyle) styleComboBox.getSelectedItem()).convert()); } @@ -96,6 +98,7 @@ private EnabledState getDisabledState() { public void reset() { PalantirJavaFormatSettings settings = PalantirJavaFormatSettings.getInstance(project); enable.setSelected(settings.isEnabled()); + formatJavadoc.setSelected(settings.isFormatJavadoc()); styleComboBox.setSelectedItem(UiFormatterStyle.convert(settings.getStyle())); pluginVersion.setText(settings.getImplementationVersion().orElse("unknown")); formatterVersion.setText(getFormatterVersionText(settings)); @@ -105,6 +108,7 @@ public void reset() { public boolean isModified() { PalantirJavaFormatSettings settings = PalantirJavaFormatSettings.getInstance(project); return enable.isSelected() != settings.isEnabled() + || formatJavadoc.isSelected() != settings.isFormatJavadoc() || !styleComboBox.getSelectedItem().equals(UiFormatterStyle.convert(settings.getStyle())); } @@ -155,11 +159,29 @@ private void createUIComponents() { null, 0, false)); + formatJavadoc = new JCheckBox(); + formatJavadoc.setText("Format JavaDoc"); + panel.add( + formatJavadoc, + new GridConstraints( + 1, + 0, + 1, + 2, + GridConstraints.ANCHOR_WEST, + GridConstraints.FILL_NONE, + GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, + GridConstraints.SIZEPOLICY_FIXED, + null, + null, + null, + 0, + false)); final Spacer spacer1 = new Spacer(); panel.add( spacer1, new GridConstraints( - 4, + 5, 0, 1, 2, @@ -177,7 +199,7 @@ private void createUIComponents() { panel.add( label1, new GridConstraints( - 1, + 2, 0, 1, 1, @@ -193,7 +215,7 @@ private void createUIComponents() { panel.add( styleComboBox, new GridConstraints( - 1, + 2, 1, 1, 1, @@ -211,7 +233,7 @@ private void createUIComponents() { panel.add( label2, new GridConstraints( - 3, + 4, 0, 1, 1, @@ -229,7 +251,7 @@ private void createUIComponents() { panel.add( formatterVersion, new GridConstraints( - 3, + 4, 1, 1, 1, @@ -247,7 +269,7 @@ private void createUIComponents() { panel.add( label3, new GridConstraints( - 2, + 3, 0, 1, 1, @@ -265,7 +287,7 @@ private void createUIComponents() { panel.add( pluginVersion, new GridConstraints( - 2, + 3, 1, 1, 1, diff --git a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatSettings.java b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatSettings.java index 4898ab596..4bf0956e4 100644 --- a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatSettings.java +++ b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/PalantirJavaFormatSettings.java @@ -68,6 +68,14 @@ void setEnabled(EnabledState enabled) { state.enabled = enabled; } + boolean isFormatJavadoc() { + return state.formatJavadoc; + } + + void setFormatJavadoc(boolean formatJavadoc) { + state.formatJavadoc = formatJavadoc; + } + boolean isUninitialized() { return state.enabled.equals(EnabledState.UNKNOWN); } @@ -137,6 +145,7 @@ static class State { private EnabledState enabled = EnabledState.UNKNOWN; private Optional> implementationClassPath = Optional.empty(); + private boolean formatJavadoc = false; public JavaFormatterOptions.Style style = JavaFormatterOptions.Style.PALANTIR; public void setImplementationClassPath(@Nullable List value) { @@ -172,11 +181,21 @@ public String getEnabled() { } } + public boolean isFormatJavadoc() { + return formatJavadoc; + } + + public void setFormatJavadoc(boolean formatJavadoc) { + this.formatJavadoc = formatJavadoc; + } + @Override public String toString() { return "PalantirJavaFormatSettings{" + "enabled=" + enabled + + ", formatJavadoc=" + + formatJavadoc + ", formatterPath=" + implementationClassPath + ", style=" diff --git a/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterService.java b/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterService.java index 5c88f5876..2de85f8e7 100644 --- a/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterService.java +++ b/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterService.java @@ -26,12 +26,15 @@ import com.google.common.collect.Range; import com.palantir.javaformat.java.FormatterException; import com.palantir.javaformat.java.FormatterService; +import com.palantir.javaformat.java.JavaFormatterOptions; import com.palantir.javaformat.java.Replacement; import java.io.IOException; import java.nio.file.Path; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import org.immutables.value.Value; @@ -45,10 +48,24 @@ public final class BootstrappingFormatterService implements FormatterService { private final Integer jdkMajorVersion; private final List implementationClassPath; + private final JavaFormatterOptions options; + public BootstrappingFormatterService(Path jdkPath, Integer jdkMajorVersion, List implementationClassPath) { + this( + jdkPath, + jdkMajorVersion, + implementationClassPath, + JavaFormatterOptions.builder() + .style(JavaFormatterOptions.Style.PALANTIR) + .build()); + } + + public BootstrappingFormatterService( + Path jdkPath, Integer jdkMajorVersion, List implementationClassPath, JavaFormatterOptions options) { this.jdkPath = jdkPath; this.jdkMajorVersion = jdkMajorVersion; this.implementationClassPath = implementationClassPath; + this.options = Objects.requireNonNull(options, "Formatter options are required"); } @Override @@ -78,6 +95,13 @@ public String fixImports(String input) throws FormatterException { } } + @Override + public FormatterService withOptions( + Function optionsTransformer) { + JavaFormatterOptions newOptions = optionsTransformer.apply(options); + return new BootstrappingFormatterService(jdkPath, jdkMajorVersion, implementationClassPath, newOptions); + } + private ImmutableList getFormatReplacementsInternal(String input, Collection> ranges) throws IOException { FormatterCliArgs command = FormatterCliArgs.builder() @@ -85,6 +109,8 @@ private ImmutableList getFormatReplacementsInternal(String input, C .withJvmArgsForVersion(jdkMajorVersion) .implementationClasspath(implementationClassPath) .outputReplacements(true) + .formatJavadoc(options.formatJavadoc()) + .style(options.style()) .characterRanges(ranges.stream() .map(BootstrappingFormatterService::toStringRange) .collect(Collectors.toList())) @@ -103,6 +129,8 @@ private String runFormatterCommand(String input) throws IOException { .withJvmArgsForVersion(jdkMajorVersion) .implementationClasspath(implementationClassPath) .outputReplacements(false) + .formatJavadoc(options.formatJavadoc()) + .style(options.style()) .build(); return FormatterCommandRunner.runWithStdin(command.toArgs(), input).orElse(input); } @@ -129,6 +157,10 @@ interface FormatterCliArgs { boolean outputReplacements(); + boolean formatJavadoc(); + + JavaFormatterOptions.Style style(); + default List toArgs() { ImmutableList.Builder args = ImmutableList.builder() .add(jdkPath().toAbsolutePath().toString()) @@ -146,10 +178,16 @@ default List toArgs() { if (outputReplacements()) { args.add("--output-replacements"); } + if (formatJavadoc()) { + args.add("--format-javadoc"); + } + if (style() == JavaFormatterOptions.Style.AOSP) { + args.add("--aosp"); + } else if (style() == JavaFormatterOptions.Style.PALANTIR) { + args.add("--palantir"); + } return args - // Use palantir style - .add("--palantir") // Trailing "-" enables formatting stdin -> stdout .add("-") .build(); diff --git a/palantir-java-format-jdk-bootstrap/src/test/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterServiceTest.java b/palantir-java-format-jdk-bootstrap/src/test/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterServiceTest.java index 3986adeca..9d4f86b3b 100644 --- a/palantir-java-format-jdk-bootstrap/src/test/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterServiceTest.java +++ b/palantir-java-format-jdk-bootstrap/src/test/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterServiceTest.java @@ -22,6 +22,7 @@ import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; +import com.palantir.javaformat.java.FormatterException; import com.palantir.javaformat.java.Replacement; import java.net.URI; import java.nio.file.Files; @@ -45,6 +46,18 @@ void can_format_file_with_replacement() { assertThat(replacements.get(0).getReplacementString()).isEqualTo(expectedOutput); } + @Test + void can_format_file_with_format_javadoc() throws FormatterException { + String input = getTestResourceContent("formatJavadoc.input"); + String expectedOutput = getTestResourceContent("formatJavadoc.output"); + + String actualOutput = getFormatter() + .withOptions(o -> o.toBuilder().formatJavadoc(true).build()) + .formatSourceReflowStringsAndFixImports(input); + + assertThat(actualOutput).isEqualTo(expectedOutput); + } + @Test void can_format_full_file() { String input = getTestResourceContent("format.input"); diff --git a/palantir-java-format-jdk-bootstrap/src/test/resources/formatJavadoc.input b/palantir-java-format-jdk-bootstrap/src/test/resources/formatJavadoc.input new file mode 100644 index 000000000..8ead172ba --- /dev/null +++ b/palantir-java-format-jdk-bootstrap/src/test/resources/formatJavadoc.input @@ -0,0 +1,16 @@ +package com.google.googlejavaformat.java.test; + +/** + * Some long doc comment bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla + *
  • item1
  • item2
  • item3
+ */ +class B { + int x; private int y; public int z; + + void f() { + while (true != false) { + if (false == true) + break; + } + } +} diff --git a/palantir-java-format-jdk-bootstrap/src/test/resources/formatJavadoc.output b/palantir-java-format-jdk-bootstrap/src/test/resources/formatJavadoc.output new file mode 100644 index 000000000..b209289d3 --- /dev/null +++ b/palantir-java-format-jdk-bootstrap/src/test/resources/formatJavadoc.output @@ -0,0 +1,23 @@ +package com.google.googlejavaformat.java.test; + +/** + * Some long doc comment bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla + * bla bla bla bla bla bla bla bla bla bla bla bla + * + *
    + *
  • item1 + *
  • item2 + *
  • item3 + *
+ */ +class B { + int x; + private int y; + public int z; + + void f() { + while (true != false) { + if (false == true) break; + } + } +} diff --git a/palantir-java-format-spi/src/main/java/com/palantir/javaformat/java/FormatterService.java b/palantir-java-format-spi/src/main/java/com/palantir/javaformat/java/FormatterService.java index 51ef1c419..2a46fb59f 100644 --- a/palantir-java-format-spi/src/main/java/com/palantir/javaformat/java/FormatterService.java +++ b/palantir-java-format-spi/src/main/java/com/palantir/javaformat/java/FormatterService.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; import java.util.Collection; +import java.util.function.Function; /** * A stable facade for palantir-java-format. The implementation must be ServiceLoaded, to ensure its classpath remains @@ -47,6 +48,24 @@ ImmutableList getFormatReplacements(String input, Collection + * Note: The default implementation exists for backwards compatibility and simply returns + * this instance. + * @param optionsTransformer An operator that is given the current set of options and returns the new set of + * options. You can either ignore the given options and build a new set of options from scratch, or use + * {@link JavaFormatterOptions.Builder#from(JavaFormatterOptions) JavaFormatterOptions.Builder.from()} to modify + * only some options. + * @return A formatter service that formats code with the given options. + */ + default FormatterService withOptions( + Function optionsTransformer) { + return this; + } + /** * Fixes imports (eg. ordering, spacing, and removal of unused import statements). * diff --git a/palantir-java-format-spi/src/main/java/com/palantir/javaformat/java/JavaFormatterOptions.java b/palantir-java-format-spi/src/main/java/com/palantir/javaformat/java/JavaFormatterOptions.java index e7be557be..6ec2a3cb8 100644 --- a/palantir-java-format-spi/src/main/java/com/palantir/javaformat/java/JavaFormatterOptions.java +++ b/palantir-java-format-spi/src/main/java/com/palantir/javaformat/java/JavaFormatterOptions.java @@ -92,6 +92,15 @@ public static Builder builder() { return new Builder(); } + /** + * Creates a new builder derived from the settings of this instance. + * @return Returns a builder for {@link JavaFormatterOptions} with the defaults + * taken from these options. + */ + public Builder toBuilder() { + return Builder.from(this); + } + /** A builder for {@link JavaFormatterOptions}. */ public static final class Builder { // default is still GOOGLE just because lots of hand-rolled tests rely on this behaviour @@ -114,5 +123,17 @@ public Builder formatJavadoc(boolean formatJavadoc) { public JavaFormatterOptions build() { return new JavaFormatterOptions(style, formatJavadoc); } + + /** + * Creates a new builder with the defaults taken from the given options. + * @param options Options to use the default for the new builder. + * @return A new builder with the given defaults. + */ + public static Builder from(JavaFormatterOptions options) { + Builder builder = new Builder(); + builder.formatJavadoc = options.formatJavadoc; + builder.style = options.style; + return builder; + } } } diff --git a/palantir-java-format/src/main/java/com/palantir/javaformat/java/CommandLineOptions.java b/palantir-java-format/src/main/java/com/palantir/javaformat/java/CommandLineOptions.java index 81defda5d..a3059e65d 100644 --- a/palantir-java-format/src/main/java/com/palantir/javaformat/java/CommandLineOptions.java +++ b/palantir-java-format/src/main/java/com/palantir/javaformat/java/CommandLineOptions.java @@ -40,6 +40,7 @@ final class CommandLineOptions { private final boolean fixImportsOnly; private final boolean sortImports; private final boolean removeUnusedImports; + private final boolean formatJavadoc; private final boolean dryRun; private final boolean setExitIfChanged; private final Optional assumeFilename; @@ -61,6 +62,7 @@ final class CommandLineOptions { boolean fixImportsOnly, boolean sortImports, boolean removeUnusedImports, + boolean formatJavadoc, boolean dryRun, boolean setExitIfChanged, Optional assumeFilename, @@ -80,6 +82,7 @@ final class CommandLineOptions { this.fixImportsOnly = fixImportsOnly; this.sortImports = sortImports; this.removeUnusedImports = removeUnusedImports; + this.formatJavadoc = formatJavadoc; this.dryRun = dryRun; this.setExitIfChanged = setExitIfChanged; this.assumeFilename = assumeFilename; @@ -157,6 +160,11 @@ boolean removeUnusedImports() { return removeUnusedImports; } + /** Format JavaDoc comments as well */ + boolean formatJavadoc() { + return formatJavadoc; + } + /** Print the paths of the files whose contents would change if the formatter were run normally. */ boolean dryRun() { return dryRun; @@ -205,6 +213,7 @@ static final class Builder { private boolean fixImportsOnly = false; private boolean sortImports = true; private boolean removeUnusedImports = true; + private boolean formatJavadoc = false; private boolean dryRun = false; private boolean setExitIfChanged = false; private Optional assumeFilename = Optional.empty(); @@ -280,6 +289,11 @@ Builder removeUnusedImports(boolean removeUnusedImports) { return this; } + Builder formatJavadoc(boolean formatJavadoc) { + this.formatJavadoc = formatJavadoc; + return this; + } + Builder dryRun(boolean dryRun) { this.dryRun = dryRun; return this; @@ -322,6 +336,7 @@ CommandLineOptions build() { fixImportsOnly, sortImports, removeUnusedImports, + formatJavadoc, dryRun, setExitIfChanged, assumeFilename, diff --git a/palantir-java-format/src/main/java/com/palantir/javaformat/java/CommandLineOptionsParser.java b/palantir-java-format/src/main/java/com/palantir/javaformat/java/CommandLineOptionsParser.java index b06f99529..da9297926 100644 --- a/palantir-java-format/src/main/java/com/palantir/javaformat/java/CommandLineOptionsParser.java +++ b/palantir-java-format/src/main/java/com/palantir/javaformat/java/CommandLineOptionsParser.java @@ -116,6 +116,10 @@ static CommandLineOptions parse(Iterable options) { case "--skip-removing-unused-imports": optionsBuilder.removeUnusedImports(false); break; + case "-format-javadoc": + case "--format-javadoc": + optionsBuilder.formatJavadoc(true); + break; case "--skip-reflowing-long-strings": optionsBuilder.reflowLongStrings(false); break; diff --git a/palantir-java-format/src/main/java/com/palantir/javaformat/java/FormatterServiceImpl.java b/palantir-java-format/src/main/java/com/palantir/javaformat/java/FormatterServiceImpl.java index fb4660882..8aa63aa1a 100644 --- a/palantir-java-format/src/main/java/com/palantir/javaformat/java/FormatterServiceImpl.java +++ b/palantir-java-format/src/main/java/com/palantir/javaformat/java/FormatterServiceImpl.java @@ -20,16 +20,21 @@ import com.google.common.collect.Range; import com.palantir.javaformat.java.JavaFormatterOptions.Style; import java.util.Collection; +import java.util.function.Function; @AutoService(FormatterService.class) public final class FormatterServiceImpl implements FormatterService { private final Formatter formatter; + private final JavaFormatterOptions options; public FormatterServiceImpl() { - JavaFormatterOptions options = - JavaFormatterOptions.builder().style(Style.PALANTIR).build(); + this(JavaFormatterOptions.builder().style(Style.PALANTIR).build()); + } + + private FormatterServiceImpl(JavaFormatterOptions options) { formatter = Formatter.createFormatter(options); + this.options = options; } @Override @@ -43,6 +48,13 @@ public String formatSourceReflowStringsAndFixImports(String input) throws Format return formatter.formatSourceAndFixImports(input); } + @Override + public FormatterService withOptions( + Function optionsTransformer) { + JavaFormatterOptions newOptions = optionsTransformer.apply(options); + return new FormatterServiceImpl(newOptions); + } + @Override public String fixImports(String input) throws FormatterException { return formatter.fixImports(input); diff --git a/palantir-java-format/src/main/java/com/palantir/javaformat/java/Main.java b/palantir-java-format/src/main/java/com/palantir/javaformat/java/Main.java index ab74242d0..c776b6313 100644 --- a/palantir-java-format/src/main/java/com/palantir/javaformat/java/Main.java +++ b/palantir-java-format/src/main/java/com/palantir/javaformat/java/Main.java @@ -98,6 +98,7 @@ public int format(String... args) throws UsageException { // TODO(someone): update this to always use Style.PALANTIR JavaFormatterOptions options = JavaFormatterOptions.builder() .style(parameters.aosp() ? Style.AOSP : parameters.palantirStyle() ? Style.PALANTIR : Style.GOOGLE) + .formatJavadoc(parameters.formatJavadoc()) .build(); if (parameters.stdin()) { diff --git a/palantir-java-format/src/main/java/com/palantir/javaformat/java/UsageException.java b/palantir-java-format/src/main/java/com/palantir/javaformat/java/UsageException.java index 960f7a131..eb9c525d0 100644 --- a/palantir-java-format/src/main/java/com/palantir/javaformat/java/UsageException.java +++ b/palantir-java-format/src/main/java/com/palantir/javaformat/java/UsageException.java @@ -51,6 +51,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.", + " . --format-javadoc", + " Also format JavaDoc comments.", " --dry-run, -n", " Prints the paths of the files whose contents would change if the formatter were run" + " normally.", " --set-exit-if-changed", diff --git a/palantir-java-format/src/test/java/com/palantir/javaformat/java/CommandLineOptionsParserTest.java b/palantir-java-format/src/test/java/com/palantir/javaformat/java/CommandLineOptionsParserTest.java index 37fc33140..8a12afd6c 100644 --- a/palantir-java-format/src/test/java/com/palantir/javaformat/java/CommandLineOptionsParserTest.java +++ b/palantir-java-format/src/test/java/com/palantir/javaformat/java/CommandLineOptionsParserTest.java @@ -15,7 +15,6 @@ package com.palantir.javaformat.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.assertj.core.api.Assertions.fail; @@ -135,6 +134,15 @@ public void skipRemovingUnusedImports() { .isFalse(); } + @Test + public void formatJavadoc() { + assertThat(CommandLineOptionsParser.parse(Arrays.asList()).formatJavadoc()) + .isFalse(); + assertThat(CommandLineOptionsParser.parse(Arrays.asList("--format-javadoc")) + .formatJavadoc()) + .isTrue(); + } + @Test public void dryRun() { assertThat(CommandLineOptionsParser.parse(Arrays.asList("--dry-run")).dryRun()) diff --git a/palantir-java-format/src/test/java/com/palantir/javaformat/java/MainTest.java b/palantir-java-format/src/test/java/com/palantir/javaformat/java/MainTest.java index f97717ca3..b85bc6871 100644 --- a/palantir-java-format/src/test/java/com/palantir/javaformat/java/MainTest.java +++ b/palantir-java-format/src/test/java/com/palantir/javaformat/java/MainTest.java @@ -119,7 +119,7 @@ public void testMain() throws Exception { // end to end javadoc formatting test @Test - public void javadoc() throws Exception { + public void javadocFormattingDisabled() throws Exception { String[] input = { "/**", " * graph", @@ -163,6 +163,49 @@ public void javadoc() throws Exception { assertThat(out.toString()).isEqualTo(joiner.join(expected)); } + @Test + public void javadocFormattingEnabled() 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) {}", + "}", + }; + String[] expected = { + "/**", + " * 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("--format-javadoc", "-")).isEqualTo(0); + assertThat(out.toString()).isEqualTo(joiner.join(expected)); + } + // end to end import fixing test @Test public void imports() throws Exception {