Skip to content

Commit

Permalink
Support google-java-format's skip-reflowing-long-strings option (#929)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg authored Sep 4, 2021
2 parents 169f9b5 + 2b4dd07 commit a7e93c8
Show file tree
Hide file tree
Showing 27 changed files with 194 additions and 31 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This document is intended for Spotless developers.
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* Added support for `google-java-format`'s `skip-reflowing-long-strings` option ([#929](https://github.com/diffplug/spotless/pull/929))

## [2.15.3] - 2021-08-20
### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.diffplug.spotless.JarState;
import com.diffplug.spotless.LineEnding;
import com.diffplug.spotless.Provisioner;
import com.diffplug.spotless.ThrowingEx.BiFunction;
import com.diffplug.spotless.ThrowingEx.Function;

/** Wraps up <a href="https://github.com/google/google-java-format">google-java-format</a> as a FormatterStep. */
Expand All @@ -35,6 +36,7 @@ public class GoogleJavaFormatStep {
private GoogleJavaFormatStep() {}

private static final String DEFAULT_STYLE = "GOOGLE";
private static final boolean DEFAULT_REFLOW_LONG_STRINGS = false;
static final String NAME = "google-java-format";
static final String MAVEN_COORDINATE = "com.google.googlejavaformat:google-java-format:";
static final String FORMATTER_CLASS = "com.google.googlejavaformat.java.Formatter";
Expand All @@ -56,6 +58,9 @@ private GoogleJavaFormatStep() {}
private static final String IMPORT_ORDERER_CLASS = "com.google.googlejavaformat.java.ImportOrderer";
private static final String IMPORT_ORDERER_METHOD = "reorderImports";

private static final String STRING_WRAPPER_CLASS = "com.google.googlejavaformat.java.StringWrapper";
private static final String STRING_WRAPPER_METHOD = "wrap";

/** Creates a step which formats everything - code, import order, and unused imports. */
public static FormatterStep create(Provisioner provisioner) {
return create(defaultVersion(), provisioner);
Expand All @@ -68,11 +73,16 @@ public static FormatterStep create(String version, Provisioner provisioner) {

/** Creates a step which formats everything - code, import order, and unused imports. */
public static FormatterStep create(String version, String style, Provisioner provisioner) {
return create(version, style, provisioner, DEFAULT_REFLOW_LONG_STRINGS);
}

/** Creates a step which formats everything - code, import order, and unused imports - and optionally reflows long strings. */
public static FormatterStep create(String version, String style, Provisioner provisioner, boolean reflowLongStrings) {
Objects.requireNonNull(version, "version");
Objects.requireNonNull(style, "style");
Objects.requireNonNull(provisioner, "provisioner");
return FormatterStep.createLazy(NAME,
() -> new State(NAME, version, style, provisioner),
() -> new State(NAME, version, style, provisioner, reflowLongStrings),
State::createFormat);
}

Expand Down Expand Up @@ -106,6 +116,10 @@ public static String defaultStyle() {
return DEFAULT_STYLE;
}

public static boolean defaultReflowLongStrings() {
return DEFAULT_REFLOW_LONG_STRINGS;
}

static final class State implements Serializable {
private static final long serialVersionUID = 1L;

Expand All @@ -114,16 +128,22 @@ static final class State implements Serializable {
final String stepName;
final String version;
final String style;
final boolean reflowLongStrings;

State(String stepName, String version, Provisioner provisioner) throws IOException {
this(stepName, version, DEFAULT_STYLE, provisioner);
}

State(String stepName, String version, String style, Provisioner provisioner) throws IOException {
this(stepName, version, style, provisioner, DEFAULT_REFLOW_LONG_STRINGS);
}

State(String stepName, String version, String style, Provisioner provisioner, boolean reflowLongStrings) throws IOException {
this.jarState = JarState.from(MAVEN_COORDINATE + version, provisioner);
this.stepName = stepName;
this.version = version;
this.style = style;
this.reflowLongStrings = reflowLongStrings;
}

@SuppressWarnings({"unchecked", "rawtypes"})
Expand Down Expand Up @@ -153,11 +173,14 @@ FormatterFunc createFormat() throws Exception {
Class<?> importOrdererClass = classLoader.loadClass(IMPORT_ORDERER_CLASS);
Method importOrdererMethod = importOrdererClass.getMethod(IMPORT_ORDERER_METHOD, String.class);

BiFunction<String, Object, String> reflowLongStrings = this.reflowLongStrings ? constructReflowLongStringsFunction(classLoader, formatterClazz) : (s, f) -> s;

return suggestJre11(input -> {
String formatted = (String) formatterMethod.invoke(formatter, input);
String removedUnused = removeUnused.apply(formatted);
String sortedImports = (String) importOrdererMethod.invoke(null, removedUnused);
return fixWindowsBug(sortedImports, version);
String reflowedLongStrings = reflowLongStrings.apply(sortedImports, formatter);
return fixWindowsBug(reflowedLongStrings, version);
});
}

Expand Down Expand Up @@ -191,6 +214,20 @@ private static Function<String, String> constructRemoveUnusedFunction(ClassLoade
}
return removeUnused;
}

private static BiFunction<String, Object, String> constructReflowLongStringsFunction(ClassLoader classLoader, Class<?> formatterClazz) throws NoSuchMethodException {
Class<?> stringWrapperClass;
try {
stringWrapperClass = classLoader.loadClass(STRING_WRAPPER_CLASS);
} catch (ClassNotFoundException e) {
// google-java-format 1.7 or lower, which happen to be LATEST_VERSION_JRE_8, so rely on suggestJre11 for the error
return (s, f) -> {
throw e;
};
}
Method stringWrapperMethod = stringWrapperClass.getMethod(STRING_WRAPPER_METHOD, String.class, formatterClazz);
return (s, f) -> (String) stringWrapperMethod.invoke(null, s, f);
}
}

private static final boolean IS_WINDOWS = LineEnding.PLATFORM_NATIVE.str().equals("\r\n");
Expand Down
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).

## [Unreleased]
### Added
* Added support for `google-java-format`'s `skip-reflowing-long-strings` option ([#929](https://github.com/diffplug/spotless/pull/929))

## [5.14.3] - 2021-08-20
### Changed
Expand Down
6 changes: 3 additions & 3 deletions plugin-gradle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ spotless {
// don't need to set target, it is inferred from java
// apply a specific flavor of google-java-format
googleJavaFormat('1.8').aosp()
googleJavaFormat('1.8').aosp().reflowLongStrings()
// make sure every file has the following copyright header.
// optionally, Spotless can set copyright years by digging
// through git history (see "license" section below)
Expand Down Expand Up @@ -176,9 +176,9 @@ spotless {
spotless {
java {
googleJavaFormat()
// optional: you can specify a specific version and/or switch to AOSP style
// optional: you can specify a specific version and/or switch to AOSP style and/or reflow long strings (requires at least 1.8)
//
googleJavaFormat('1.7').aosp()
googleJavaFormat('1.8').aosp().reflowLongStrings()
```

### eclipse jdt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,26 +90,39 @@ public GoogleJavaFormatConfig googleJavaFormat(String version) {
public class GoogleJavaFormatConfig {
final String version;
String style;
boolean reflowLongStrings;

GoogleJavaFormatConfig(String version) {
this.version = Objects.requireNonNull(version);
this.style = GoogleJavaFormatStep.defaultStyle();
addStep(createStep());
}

public void style(String style) {
public GoogleJavaFormatConfig style(String style) {
this.style = Objects.requireNonNull(style);
replaceStep(createStep());
return this;
}

public void aosp() {
style("AOSP");
public GoogleJavaFormatConfig aosp() {
return style("AOSP");
}

public GoogleJavaFormatConfig reflowLongStrings() {
return reflowLongStrings(true);
}

public GoogleJavaFormatConfig reflowLongStrings(boolean reflowLongStrings) {
this.reflowLongStrings = reflowLongStrings;
replaceStep(createStep());
return this;
}

private FormatterStep createStep() {
return GoogleJavaFormatStep.create(version,
style,
provisioner());
provisioner(),
reflowLongStrings);
}
}

Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* Added support for `google-java-format`'s `skip-reflowing-long-strings` option ([#929](https://github.com/diffplug/spotless/pull/929))

## [2.12.3] - 2021-08-20
### Changed
Expand Down
8 changes: 5 additions & 3 deletions plugin-maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ To use it in your pom, just [add the Spotless dependency](https://search.maven.o
<java>
<!-- no need to specify files, inferred automatically, but you can if you want -->

<!-- apply a specific flavor of google-java-format -->
<!-- apply a specific flavor of google-java-format and reflow long strings -->
<googleJavaFormat>
<version>1.8</version>
<style>AOSP</style>
<reflowLongStrings>true</reflowLongStrings>
</googleJavaFormat>

<!-- make sure every file has the following copyright header.
Expand Down Expand Up @@ -201,8 +202,9 @@ any other maven phase (i.e. compile) then it can be configured as below;

```xml
<googleJavaFormat>
<version>1.7</version> <!-- optional -->
<style>GOOGLE</style> <!-- or AOSP (optional) -->
<version>1.8</version> <!-- optional -->
<style>GOOGLE</style> <!-- or AOSP (optional) -->
<reflowLongStrings>true</reflowLongStrings> <!-- optional (requires at least 1.8) -->
</googleJavaFormat>
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 DiffPlug
* Copyright 2016-2021 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -29,10 +29,14 @@ public class GoogleJavaFormat implements FormatterStepFactory {
@Parameter
private String style;

@Parameter
private Boolean reflowLongStrings;

@Override
public FormatterStep newFormatterStep(FormatterStepConfig config) {
String version = this.version != null ? this.version : GoogleJavaFormatStep.defaultVersion();
String style = this.style != null ? this.style : GoogleJavaFormatStep.defaultStyle();
return GoogleJavaFormatStep.create(version, style, config.getProvisioner());
boolean reflowLongStrings = this.reflowLongStrings != null ? this.reflowLongStrings : GoogleJavaFormatStep.defaultReflowLongStrings();
return GoogleJavaFormatStep.create(version, style, config.getProvisioner(), reflowLongStrings);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 DiffPlug
* Copyright 2016-2021 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@

import org.junit.Test;

import com.diffplug.spotless.JreVersion;
import com.diffplug.spotless.maven.MavenIntegrationHarness;

public class GoogleJavaFormatTest extends MavenIntegrationHarness {
Expand All @@ -41,6 +42,18 @@ public void specificVersionSpecificStyle() throws Exception {
runTest("java/googlejavaformat/JavaCodeFormattedAOSP.test");
}

@Test
public void specificVersionReflowLongStrings() throws Exception {
JreVersion.assume11OrGreater();
writePomWithJavaSteps(
"<googleJavaFormat>",
" <version>1.8</version>",
" <reflowLongStrings>true</reflowLongStrings>",
"</googleJavaFormat>");

runTest("java/googlejavaformat/JavaCodeFormattedReflowLongStrings.test");
}

private void runTest(String targetResource) throws Exception {
String path = "src/main/java/test.java";
setFile(path).toResource("java/googlejavaformat/JavaCodeUnformatted.test");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import mylib.UsedB;

public class Java {
public static void main(String[] args) {
System.out.println("hello");
System.out.println(
"A very very very very very very very very very very very very very very very very very very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import mylib.UsedB;

public class Java {
public static void main(String[] args) {
System.out.println("hello");
System.out.println(
"A very very very very very very very very very very very very very very very very very very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import mylib.UsedB;

public class Java {
public static void main(String[] args) {
System.out.println("hello");
System.out.println(
"A very very very very very very very very very very very very very very very very very very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import mylib.UsedA;
import mylib.UsedB;

public class Java {
public static void main(String[] args) {
System.out.println(
"A very very very very very very very very very very very very very very very very very"
+ " very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import mylib.UsedA;

public class Java {
public static void main(String[] args) {
System.out.println("hello");
System.out.println("A very very very very very very very very very very very very very very very very very very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import mylib.UsedB;

public class Java {
public static void main(String[] args) {
System.out.println("hello");
System.out.println(
"A very very very very very very very very very very very very very very very very very very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import mylib.UsedB;

public class Java {
public static void main(String[] args) {
System.out.println("hello");
System.out.println(
"A very very very very very very very very very very very very very very very very very very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Some license stuff.
* Very official.
*/

import mylib.UsedA;
import mylib.UsedB;

public class Java {
public static void main(String[] args) {
System.out.println(
"A very very very very very very very very very very very very very very very very very"
+ " very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import mylib.UsedB;

public class Java {
public static void main(String[] args) {
System.out.println("hello");
System.out.println(
"A very very very very very very very very very very very very very very very very very very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import mylib.UsedB;

public class Java {
public static void main(String[] args) {
System.out.println("hello");
System.out.println(
"A very very very very very very very very very very very very very very very very very very very very very long string that goes beyond the 100-character line length.");
UsedB.someMethod();
UsedA.someMethod();
}
Expand Down
Loading

0 comments on commit a7e93c8

Please sign in to comment.