diff --git a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/PalantirJavaFormatPlugin.java b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/PalantirJavaFormatPlugin.java index 16fcb55cf..523dd14d5 100644 --- a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/PalantirJavaFormatPlugin.java +++ b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/PalantirJavaFormatPlugin.java @@ -18,6 +18,7 @@ import com.palantir.javaformat.bootstrap.NativeImageFormatterService; import com.palantir.javaformat.java.FormatterService; +import com.palantir.javaformat.java.JavaFormatterOptions; import java.io.File; import java.io.IOException; import org.gradle.api.DefaultTask; @@ -84,7 +85,7 @@ public final void formatDiff() throws IOException, InterruptedException { FormatDiff.formatDiff( getProject().getProjectDir().toPath(), new NativeImageFormatterService( - getNativeImage().get().getAsFile().toPath())); + getNativeImage().get().getAsFile().toPath(), JavaFormatterOptions.defaultOptions())); } else { log.info("Using the Java-based formatter"); JavaFormatExtension extension = diff --git a/gradle-palantir-java-format/src/test/groovy/com/palantir/javaformat/gradle/FormatDiffTest.groovy b/gradle-palantir-java-format/src/test/groovy/com/palantir/javaformat/gradle/FormatDiffTest.groovy index 26454b82c..1d7e2eedc 100644 --- a/gradle-palantir-java-format/src/test/groovy/com/palantir/javaformat/gradle/FormatDiffTest.groovy +++ b/gradle-palantir-java-format/src/test/groovy/com/palantir/javaformat/gradle/FormatDiffTest.groovy @@ -19,6 +19,7 @@ package com.palantir.javaformat.gradle; import com.google.common.base.Splitter import com.palantir.javaformat.bootstrap.BootstrappingFormatterService import com.palantir.javaformat.java.FormatterService +import com.palantir.javaformat.java.JavaFormatterOptions import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource @@ -107,11 +108,12 @@ class FormatDiffTest { } private static Stream getFormatters() { + JavaFormatterOptions options = JavaFormatterOptions.builder().build(); return Stream.of( new BootstrappingFormatterService( - javaBinPath(), Runtime.version().feature(), getClasspath()), + javaBinPath(), Runtime.version().feature(), getClasspath(), options), new NativeImageFormatterService( - Path.of(NATIVE_IMAGE_FILE.text))); + Path.of(NATIVE_IMAGE_FILE.text), options)); } private static getClasspath() { 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 9ae0e9bee..204cda12f 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 @@ -33,6 +33,7 @@ import com.palantir.javaformat.bootstrap.BootstrappingFormatterService; import com.palantir.javaformat.bootstrap.NativeImageFormatterService; import com.palantir.javaformat.java.FormatterService; +import com.palantir.javaformat.java.JavaFormatterOptions; import java.io.IOException; import java.io.UncheckedIOException; import java.net.MalformedURLException; @@ -73,14 +74,18 @@ Optional get(Project project, PalantirJavaFormatSettings setti getSdkVersion(project), settings.getImplementationClassPath(), settings.getNativeImageClassPath(), - settings.injectedVersionIsOutdated())); + settings.injectedVersionIsOutdated(), + settings.isSkipReflowingLongStrings())); } @SuppressWarnings("for-rollout:Slf4jLogsafeArgs") private static Optional createFormatter(FormatterCacheKey cacheKey) { + JavaFormatterOptions options = JavaFormatterOptions.builder() + .skipReflowingLongStrings(cacheKey.skipReflowingLongStrings) + .build(); if (cacheKey.nativeImageClassPath.isPresent()) { log.info("Using the native formatter with classpath: {}", cacheKey.nativeImageClassPath.get()); - return Optional.of(new NativeImageFormatterService(Path.of(cacheKey.nativeImageClassPath.get()))); + return Optional.of(new NativeImageFormatterService(Path.of(cacheKey.nativeImageClassPath.get()), options)); } if (cacheKey.jdkMajorVersion.isEmpty()) { return Optional.empty(); @@ -96,7 +101,8 @@ private static Optional createFormatter(FormatterCacheKey cach 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 @@ -225,18 +231,21 @@ private static final class FormatterCacheKey { private final Optional> implementationClassPath; private final Optional nativeImageClassPath; private final boolean useBundledImplementation; + private final boolean skipReflowingLongStrings; FormatterCacheKey( Project project, OptionalInt jdkMajorVersion, Optional> implementationClassPath, Optional nativeImageClassPath, - boolean useBundledImplementation) { + boolean useBundledImplementation, + boolean skipReflowingLongStrings) { this.project = project; this.jdkMajorVersion = jdkMajorVersion; this.implementationClassPath = implementationClassPath; this.nativeImageClassPath = nativeImageClassPath; this.useBundledImplementation = useBundledImplementation; + this.skipReflowingLongStrings = skipReflowingLongStrings; } @Override @@ -250,6 +259,7 @@ public boolean equals(Object o) { FormatterCacheKey that = (FormatterCacheKey) o; return Objects.equals(jdkMajorVersion, that.jdkMajorVersion) && useBundledImplementation == that.useBundledImplementation + && skipReflowingLongStrings == that.skipReflowingLongStrings && Objects.equals(project, that.project) && Objects.equals(implementationClassPath, that.implementationClassPath) && Objects.equals(nativeImageClassPath, that.nativeImageClassPath); @@ -258,7 +268,12 @@ public boolean equals(Object o) { @Override public int hashCode() { return Objects.hash( - project, jdkMajorVersion, implementationClassPath, nativeImageClassPath, useBundledImplementation); + project, + jdkMajorVersion, + implementationClassPath, + nativeImageClassPath, + useBundledImplementation, + skipReflowingLongStrings); } } } 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 7511bb8d9..5b3e1fdb5 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 @@
- + @@ -16,14 +16,17 @@ - + - + - + + + + - + @@ -31,45 +34,45 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -77,12 +80,17 @@ - + + + + + + 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 cab5c6d69..aa1e1ed7d 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 @@ -36,6 +36,7 @@ class PalantirJavaFormatConfigurable extends BaseConfigurable implements Searcha private final Project project; private JPanel panel; private JCheckBox enable; + private JCheckBox skipReflowingLongStrings; @SuppressWarnings("for-rollout:RawTypes") private JComboBox styleComboBox; @@ -84,6 +85,7 @@ public void apply() throws ConfigurationException { PalantirJavaFormatSettings settings = PalantirJavaFormatSettings.getInstance(project); settings.setEnabled(enable.isSelected() ? EnabledState.ENABLED : getDisabledState()); settings.setStyle(((UiFormatterStyle) styleComboBox.getSelectedItem()).convert()); + settings.setSkipReflowingLongStrings(skipReflowingLongStrings.isSelected()); } private EnabledState getDisabledState() { @@ -98,6 +100,7 @@ public void reset() { PalantirJavaFormatSettings settings = PalantirJavaFormatSettings.getInstance(project); enable.setSelected(settings.isEnabled()); styleComboBox.setSelectedItem(UiFormatterStyle.convert(settings.getStyle())); + skipReflowingLongStrings.setSelected(settings.isSkipReflowingLongStrings()); pluginVersion.setText(settings.getImplementationVersion().orElse("unknown")); formatterVersion.setText(getFormatterVersionText(settings)); isUsingNativeImage.setText(isUsingNativeImage(settings)); @@ -107,7 +110,8 @@ public void reset() { public boolean isModified() { PalantirJavaFormatSettings settings = PalantirJavaFormatSettings.getInstance(project); return enable.isSelected() != settings.isEnabled() - || !styleComboBox.getSelectedItem().equals(UiFormatterStyle.convert(settings.getStyle())); + || !styleComboBox.getSelectedItem().equals(UiFormatterStyle.convert(settings.getStyle())) + || skipReflowingLongStrings.isSelected() != settings.isSkipReflowingLongStrings(); } @Override 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 80635bac5..f60fe7a47 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 @@ -82,6 +82,14 @@ void setStyle(JavaFormatterOptions.Style style) { state.style = style; } + boolean isSkipReflowingLongStrings() { + return state.skipReflowingLongStrings; + } + + void setSkipReflowingLongStrings(boolean skipReflowingLongStrings) { + state.skipReflowingLongStrings = skipReflowingLongStrings; + } + /** * The paths to jars that provide an alternative implementation of the formatter. If set, this implementation will * be used instead of the bundled version. @@ -147,6 +155,7 @@ static class State { private Optional nativeImageClassPath = Optional.empty(); public JavaFormatterOptions.Style style = JavaFormatterOptions.Style.PALANTIR; + public boolean skipReflowingLongStrings = false; public void setImplementationClassPath(@Nullable List value) { implementationClassPath = Optional.ofNullable(value) diff --git a/idea-plugin/src/test/java/com/palantir/javaformat/intellij/PalantirJavaFormatFormattingServiceTest.java b/idea-plugin/src/test/java/com/palantir/javaformat/intellij/PalantirJavaFormatFormattingServiceTest.java index bdab25130..81eb9bd11 100644 --- a/idea-plugin/src/test/java/com/palantir/javaformat/intellij/PalantirJavaFormatFormattingServiceTest.java +++ b/idea-plugin/src/test/java/com/palantir/javaformat/intellij/PalantirJavaFormatFormattingServiceTest.java @@ -97,6 +97,15 @@ public void defaultFormatSettings() throws Exception { assertThat(delegatingFormatter.wasInvoked()).isTrue(); } + @Test + public void skipReflowingLongStringsSettingPersists() throws Exception { + settings.setSkipReflowingLongStrings(true); + assertThat(settings.isSkipReflowingLongStrings()).isTrue(); + + settings.setSkipReflowingLongStrings(false); + assertThat(settings.isSkipReflowingLongStrings()).isFalse(); + } + protected Project getProject() { return fixture.getProject(); } diff --git a/idea-plugin/src/test/java/com/palantir/javaformat/intellij/PalantirJavaFormatSettingsTest.java b/idea-plugin/src/test/java/com/palantir/javaformat/intellij/PalantirJavaFormatSettingsTest.java new file mode 100644 index 000000000..3e563980e --- /dev/null +++ b/idea-plugin/src/test/java/com/palantir/javaformat/intellij/PalantirJavaFormatSettingsTest.java @@ -0,0 +1,57 @@ +/* + * (c) Copyright 2024 Palantir Technologies 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.palantir.javaformat.intellij; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.palantir.javaformat.intellij.PalantirJavaFormatSettings.State; +import org.junit.jupiter.api.Test; + +public final class PalantirJavaFormatSettingsTest { + + @Test + void skipReflowingLongStrings_defaultIsFalse() { + State state = new State(); + assertThat(state.skipReflowingLongStrings).isFalse(); + } + + @Test + void skipReflowingLongStrings_canBeSetToTrue() { + State state = new State(); + state.skipReflowingLongStrings = true; + assertThat(state.skipReflowingLongStrings).isTrue(); + } + + @Test + void skipReflowingLongStrings_canBeSetToFalse() { + State state = new State(); + state.skipReflowingLongStrings = true; + state.skipReflowingLongStrings = false; + assertThat(state.skipReflowingLongStrings).isFalse(); + } + + @Test + void skipReflowingLongStrings_persistsAcrossStateInstances() { + State state1 = new State(); + state1.skipReflowingLongStrings = true; + + State state2 = new State(); + state2.skipReflowingLongStrings = state1.skipReflowingLongStrings; + + assertThat(state2.skipReflowingLongStrings).isTrue(); + } +} 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 92d734449..f71e1e617 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 @@ -25,6 +25,7 @@ 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.io.UncheckedIOException; @@ -44,11 +45,32 @@ public final class BootstrappingFormatterService implements FormatterService { private final Path jdkPath; private final Integer jdkMajorVersion; private final List implementationClassPath; - + private final JavaFormatterOptions formatterOptions; + + /** + * Creates a BootstrappingFormatterService with default formatter options. + * Provided for backward compatibility with code that does not pass JavaFormatterOptions. + * + * @deprecated Use {@link #BootstrappingFormatterService(Path, Integer, List, JavaFormatterOptions)} instead + */ + @Deprecated public BootstrappingFormatterService(Path jdkPath, Integer jdkMajorVersion, List implementationClassPath) { + this( + jdkPath, + jdkMajorVersion, + implementationClassPath, + JavaFormatterOptions.builder().build()); + } + + public BootstrappingFormatterService( + Path jdkPath, + Integer jdkMajorVersion, + List implementationClassPath, + JavaFormatterOptions formatterOptions) { this.jdkPath = jdkPath; this.jdkMajorVersion = jdkMajorVersion; this.implementationClassPath = implementationClassPath; + this.formatterOptions = formatterOptions; } @Override @@ -85,6 +107,7 @@ private ImmutableList getFormatReplacementsInternal(String input, C .withJvmArgsForVersion(jdkMajorVersion) .implementationClasspath(implementationClassPath) .outputReplacements(true) + .skipReflowingLongStrings(formatterOptions.skipReflowingLongStrings()) .characterRanges(ranges.stream().map(RangeUtils::toStringRange).collect(Collectors.toList())) .build(); @@ -103,6 +126,7 @@ private String runFormatterCommand(String input) throws IOException { .withJvmArgsForVersion(jdkMajorVersion) .implementationClasspath(implementationClassPath) .outputReplacements(false) + .skipReflowingLongStrings(formatterOptions.skipReflowingLongStrings()) .build(); return FormatterCommandRunner.runWithStdin(command.toArgs(), input, Optional.ofNullable(jdkPath.getParent())) .orElse(input); @@ -114,6 +138,8 @@ interface FormatterCliArgs { boolean outputReplacements(); + boolean skipReflowingLongStrings(); + Path jdkPath(); List implementationClasspath(); @@ -137,6 +163,9 @@ default List toArgs() { if (outputReplacements()) { args.add("--output-replacements"); } + if (skipReflowingLongStrings()) { + args.add("--skip-reflowing-long-strings"); + } return args // Use palantir style diff --git a/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/NativeImageFormatterService.java b/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/NativeImageFormatterService.java index 583dc41cd..ff2b88f6c 100644 --- a/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/NativeImageFormatterService.java +++ b/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/NativeImageFormatterService.java @@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Range; import com.palantir.javaformat.java.FormatterService; +import com.palantir.javaformat.java.JavaFormatterOptions; import com.palantir.javaformat.java.Replacement; import java.io.IOException; import java.io.UncheckedIOException; @@ -38,9 +39,22 @@ public class NativeImageFormatterService implements FormatterService { private static final ObjectMapper MAPPER = JsonMapper.builder().addModule(new GuavaModule()).build(); private final Path nativeImagePath; - + private final JavaFormatterOptions formatterOptions; + + /** + * Creates a NativeImageFormatterService with default formatter options. + * Provided for backward compatibility with code that does not pass JavaFormatterOptions. + * + * @deprecated Use {@link #NativeImageFormatterService(Path, JavaFormatterOptions)} instead + */ + @Deprecated public NativeImageFormatterService(Path nativeImagePath) { + this(nativeImagePath, JavaFormatterOptions.builder().build()); + } + + public NativeImageFormatterService(Path nativeImagePath, JavaFormatterOptions formatterOptions) { this.nativeImagePath = nativeImagePath; + this.formatterOptions = formatterOptions; } @Override @@ -50,6 +64,7 @@ public ImmutableList getFormatReplacements(String input, Collection FormatterNativeImageArgs command = FormatterNativeImageArgs.builder() .nativeImagePath(nativeImagePath) .outputReplacements(true) + .skipReflowingLongStrings(formatterOptions.skipReflowingLongStrings()) .characterRanges( ranges.stream().map(RangeUtils::toStringRange).collect(Collectors.toList())) .build(); @@ -88,6 +103,7 @@ private String runFormatterCommand(String input) throws IOException { FormatterNativeImageArgs command = FormatterNativeImageArgs.builder() .nativeImagePath(nativeImagePath) .outputReplacements(false) + .skipReflowingLongStrings(formatterOptions.skipReflowingLongStrings()) .build(); return FormatterCommandRunner.runWithStdin( command.toArgs(), input, Optional.ofNullable(nativeImagePath.getParent())) @@ -101,6 +117,8 @@ interface FormatterNativeImageArgs { boolean outputReplacements(); + boolean skipReflowingLongStrings(); + Path nativeImagePath(); default List toArgs() { @@ -113,6 +131,9 @@ default List toArgs() { if (outputReplacements()) { args.add("--output-replacements"); } + if (skipReflowingLongStrings()) { + args.add("--skip-reflowing-long-strings"); + } return args // Use palantir style diff --git a/palantir-java-format-jdk-bootstrap/src/test/java/com/palantir/javaformat/bootstrap/FormatterServicesTest.java b/palantir-java-format-jdk-bootstrap/src/test/java/com/palantir/javaformat/bootstrap/FormatterServicesTest.java index c85ebbf8a..67b323159 100644 --- a/palantir-java-format-jdk-bootstrap/src/test/java/com/palantir/javaformat/bootstrap/FormatterServicesTest.java +++ b/palantir-java-format-jdk-bootstrap/src/test/java/com/palantir/javaformat/bootstrap/FormatterServicesTest.java @@ -25,6 +25,7 @@ import com.palantir.javaformat.Utils; 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.net.URI; import java.nio.file.Files; @@ -98,11 +99,14 @@ public void main( String aaaa ) { } private static Stream getFormatters() { + JavaFormatterOptions options = + JavaFormatterOptions.builder().skipReflowingLongStrings(false).build(); + return Stream.of( new BootstrappingFormatterService( - javaBinPath(), Runtime.version().feature(), getClasspath()), + javaBinPath(), Runtime.version().feature(), getClasspath(), options), new NativeImageFormatterService( - Path.of(System.getenv("NATIVE_IMAGE_CLASSPATH").toString()))); + Path.of(System.getenv("NATIVE_IMAGE_CLASSPATH").toString()), options)); } private String getTestResourceContent(String resourceName) { 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..cd5384879 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 @@ -59,9 +59,12 @@ public int maxLineLength() { private final boolean formatJavadoc; - private JavaFormatterOptions(Style style, boolean formatJavadoc) { + private final boolean skipReflowingLongStrings; + + private JavaFormatterOptions(Style style, boolean formatJavadoc, boolean skipReflowingLongStrings) { this.style = style; this.formatJavadoc = formatJavadoc; + this.skipReflowingLongStrings = skipReflowingLongStrings; } /** Returns the multiplier for the unit of indent. */ @@ -77,6 +80,10 @@ public boolean formatJavadoc() { return formatJavadoc; } + public boolean skipReflowingLongStrings() { + return skipReflowingLongStrings; + } + /** Returns the code style. */ public Style style() { return style; @@ -99,6 +106,8 @@ public static final class Builder { private boolean formatJavadoc = false; + private boolean skipReflowingLongStrings = false; + private Builder() {} public Builder style(Style style) { @@ -111,8 +120,13 @@ public Builder formatJavadoc(boolean formatJavadoc) { return this; } + public Builder skipReflowingLongStrings(boolean skipReflowingLongStrings) { + this.skipReflowingLongStrings = skipReflowingLongStrings; + return this; + } + public JavaFormatterOptions build() { - return new JavaFormatterOptions(style, formatJavadoc); + return new JavaFormatterOptions(style, formatJavadoc, skipReflowingLongStrings); } } }