Skip to content

Commit 156d71e

Browse files
committed
merge upstream v1.13.0
2 parents aa151c3 + 8be9250 commit 156d71e

11 files changed

Lines changed: 176 additions & 48 deletions

File tree

README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
and run it with:
1414

1515
```
16-
java -jar /path/to/google-java-format-1.11.1-all.jar <options> [files...]
16+
java -jar /path/to/google-java-format-1.12.0-all.jar <options> [files...]
1717
```
1818

1919
The formatter can act on whole files, on limited lines (`--lines`), on specific
@@ -39,7 +39,7 @@ java \
3939
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
4040
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
4141
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
42-
-jar google-java-format-1.11.1-all.jar <options> [files...]
42+
-jar google-java-format-1.12.0-all.jar <options> [files...]
4343
```
4444

4545
### as a library
@@ -54,15 +54,14 @@ configuration.
5454
<dependency>
5555
<groupId>io.opil</groupId>
5656
<artifactId>google-java-format</artifactId>
57-
<version>1.11.1</version>
58-
</dependency>
57+
<version>1.12.0</version>
5958
```
6059

6160
#### Gradle
6261

6362
```groovy
6463
dependencies {
65-
implementation 'io.opil:google-java-format:1.11.1'
64+
implementation 'io.opil:google-java-format:1.12.0'
6665
}
6766
```
6867

@@ -86,7 +85,7 @@ Your starting point should be the instance methods of
8685
## Building from source
8786

8887
```
89-
mvn install
88+
gradle build
9089
```
9190

9291
## License

scripts/google-java-format-diff.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import subprocess
3434
import io
3535
import sys
36-
from distutils.spawn import find_executable
36+
from shutil import which
3737

3838
def main():
3939
parser = argparse.ArgumentParser(description=
@@ -105,7 +105,7 @@ def main():
105105
elif args.google_java_format_jar:
106106
base_command = ['java', '-jar', args.google_java_format_jar]
107107
else:
108-
binary = find_executable('google-java-format') or '/usr/bin/google-java-format'
108+
binary = which('google-java-format') or '/usr/bin/google-java-format'
109109
base_command = [binary]
110110

111111
# Reformat files containing changes in place.
@@ -134,11 +134,11 @@ def main():
134134
if not args.i:
135135
with open(filename) as f:
136136
code = f.readlines()
137-
formatted_code = io.StringIO(stdout).readlines()
137+
formatted_code = io.StringIO(stdout.decode('utf-8')).readlines()
138138
diff = difflib.unified_diff(code, formatted_code,
139139
filename, filename,
140140
'(before formatting)', '(after formatting)')
141-
diff_string = string.join(diff, '')
141+
diff_string = ''.join(diff)
142142
if len(diff_string) > 0:
143143
sys.stdout.write(diff_string)
144144

src/main/java/com/google/googlejavaformat/java/RemoveUnusedImports.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.googlejavaformat.Newlines;
3333
import com.sun.source.doctree.DocCommentTree;
3434
import com.sun.source.doctree.ReferenceTree;
35+
import com.sun.source.tree.CaseTree;
3536
import com.sun.source.tree.IdentifierTree;
3637
import com.sun.source.tree.ImportTree;
3738
import com.sun.source.tree.Tree;
@@ -55,8 +56,10 @@
5556
import com.sun.tools.javac.util.Options;
5657
import java.io.IOError;
5758
import java.io.IOException;
59+
import java.lang.reflect.Method;
5860
import java.net.URI;
5961
import java.util.LinkedHashSet;
62+
import java.util.List;
6063
import java.util.Map;
6164
import java.util.Set;
6265
import javax.tools.Diagnostic;
@@ -115,6 +118,31 @@ public Void visitIdentifier(IdentifierTree tree, Void unused) {
115118
return null;
116119
}
117120

121+
// TODO(cushon): remove this override when pattern matching in switch is no longer a preview
122+
// feature, and TreePathScanner visits CaseTree#getLabels instead of CaseTree#getExpressions
123+
@SuppressWarnings("unchecked") // reflection
124+
@Override
125+
public Void visitCase(CaseTree tree, Void unused) {
126+
if (CASE_TREE_GET_LABELS != null) {
127+
try {
128+
scan((List<? extends Tree>) CASE_TREE_GET_LABELS.invoke(tree), null);
129+
} catch (ReflectiveOperationException e) {
130+
throw new LinkageError(e.getMessage(), e);
131+
}
132+
}
133+
return super.visitCase(tree, null);
134+
}
135+
136+
private static final Method CASE_TREE_GET_LABELS = caseTreeGetLabels();
137+
138+
private static Method caseTreeGetLabels() {
139+
try {
140+
return CaseTree.class.getMethod("getLabels");
141+
} catch (NoSuchMethodException e) {
142+
return null;
143+
}
144+
}
145+
118146
@Override
119147
public Void scan(Tree tree, Void unused) {
120148
if (tree == null) {
@@ -146,7 +174,9 @@ public Void visitIdentifier(com.sun.source.doctree.IdentifierTree node, Void aVo
146174
public Void visitReference(ReferenceTree referenceTree, Void unused) {
147175
DCReference reference = (DCReference) referenceTree;
148176
long basePos =
149-
reference.getSourcePosition((DCTree.DCDocComment) getCurrentPath().getDocComment());
177+
reference
178+
.pos((DCTree.DCDocComment) getCurrentPath().getDocComment())
179+
.getStartPosition();
150180
// the position of trees inside the reference node aren't stored, but the qualifier's
151181
// start position is the beginning of the reference node
152182
if (reference.qualifierExpression != null) {

src/main/java/com/google/googlejavaformat/java/java14/Java14InputAstVisitor.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package com.google.googlejavaformat.java.java14;
1616

1717
import static com.google.common.collect.ImmutableList.toImmutableList;
18+
import static com.google.common.collect.Iterables.getOnlyElement;
1819

1920
import com.google.common.base.Verify;
2021
import com.google.common.collect.ImmutableList;
@@ -27,7 +28,6 @@
2728
import com.sun.source.tree.CaseTree;
2829
import com.sun.source.tree.ClassTree;
2930
import com.sun.source.tree.CompilationUnitTree;
30-
import com.sun.source.tree.ExpressionTree;
3131
import com.sun.source.tree.InstanceOfTree;
3232
import com.sun.source.tree.ModifiersTree;
3333
import com.sun.source.tree.ModuleTree;
@@ -59,6 +59,7 @@ public class Java14InputAstVisitor extends JavaInputAstVisitor {
5959
maybeGetMethod(BindingPatternTree.class, "getType");
6060
private static final Method BINDING_PATTERN_TREE_GET_BINDING =
6161
maybeGetMethod(BindingPatternTree.class, "getBinding");
62+
private static final Method CASE_TREE_GET_LABELS = maybeGetMethod(CaseTree.class, "getLabels");
6263

6364
public Java14InputAstVisitor(OpsBuilder builder, int indentMultiplier) {
6465
super(builder, indentMultiplier);
@@ -247,14 +248,25 @@ public Void visitCase(CaseTree node, Void unused) {
247248
sync(node);
248249
markForPartialFormat();
249250
builder.forcedBreak();
250-
if (node.getExpressions().isEmpty()) {
251+
List<? extends Tree> labels;
252+
boolean isDefault;
253+
if (CASE_TREE_GET_LABELS != null) {
254+
labels = (List<? extends Tree>) invoke(CASE_TREE_GET_LABELS, node);
255+
isDefault =
256+
labels.size() == 1
257+
&& getOnlyElement(labels).getKind().name().equals("DEFAULT_CASE_LABEL");
258+
} else {
259+
labels = node.getExpressions();
260+
isDefault = labels.isEmpty();
261+
}
262+
if (isDefault) {
251263
token("default", plusTwo);
252264
} else {
253265
token("case", plusTwo);
254-
builder.open(node.getExpressions().size() > 1 ? plusFour : ZERO);
266+
builder.open(labels.size() > 1 ? plusFour : ZERO);
255267
builder.space();
256268
boolean first = true;
257-
for (ExpressionTree expression : node.getExpressions()) {
269+
for (Tree expression : labels) {
258270
if (!first) {
259271
token(",");
260272
builder.breakOp(" ");

src/test/java/com/google/googlejavaformat/java/FormatterIntegrationTest.java

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,28 @@
1414

1515
package com.google.googlejavaformat.java;
1616

17-
import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_VERSION;
18-
import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;
17+
import static com.google.common.collect.MoreCollectors.toOptional;
1918
import static com.google.common.io.Files.getFileExtension;
2019
import static com.google.common.io.Files.getNameWithoutExtension;
2120
import static java.nio.charset.StandardCharsets.UTF_8;
2221
import static org.junit.Assert.assertEquals;
2322
import static org.junit.Assert.assertTrue;
2423
import static org.junit.Assert.fail;
2524

26-
import com.google.common.collect.ImmutableSet;
25+
import com.google.common.collect.ImmutableMultimap;
2726
import com.google.common.io.CharStreams;
2827
import com.google.common.reflect.ClassPath;
2928
import com.google.common.reflect.ClassPath.ResourceInfo;
3029
import com.google.googlejavaformat.Newlines;
3130
import java.io.IOException;
3231
import java.io.InputStream;
3332
import java.io.InputStreamReader;
34-
import java.lang.reflect.Method;
3533
import java.nio.file.Path;
3634
import java.nio.file.Paths;
3735
import java.util.ArrayList;
3836
import java.util.List;
3937
import java.util.Map;
38+
import java.util.Optional;
4039
import java.util.TreeMap;
4140
import org.junit.Test;
4241
import org.junit.runner.RunWith;
@@ -47,12 +46,13 @@
4746
@RunWith(Parameterized.class)
4847
public class FormatterIntegrationTest {
4948

50-
private static final ImmutableSet<String> JAVA14_TESTS =
51-
ImmutableSet.of("I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574", "I594");
52-
53-
private static final ImmutableSet<String> JAVA15_TESTS = ImmutableSet.of("I603");
54-
55-
private static final ImmutableSet<String> JAVA16_TESTS = ImmutableSet.of("I588");
49+
private static final ImmutableMultimap<Integer, String> VERSIONED_TESTS =
50+
ImmutableMultimap.<Integer, String>builder()
51+
.putAll(14, "I477", "Records", "RSLs", "Var", "ExpressionSwitch", "I574", "I594")
52+
.putAll(15, "I603")
53+
.putAll(16, "I588")
54+
.putAll(17, "I683", "I684")
55+
.build();
5656

5757
@Parameters(name = "{index}: {0}")
5858
public static Iterable<Object[]> data() throws IOException {
@@ -91,35 +91,16 @@ public static Iterable<Object[]> data() throws IOException {
9191
String input = inputs.get(fileName);
9292
assertTrue("unmatched input", outputs.containsKey(fileName));
9393
String expectedOutput = outputs.get(fileName);
94-
if (JAVA14_TESTS.contains(fileName) && getMajor() < 14) {
95-
continue;
96-
}
97-
if (JAVA15_TESTS.contains(fileName) && getMajor() < 15) {
98-
continue;
99-
}
100-
if (JAVA16_TESTS.contains(fileName) && getMajor() < 16) {
94+
Optional<Integer> version =
95+
VERSIONED_TESTS.inverse().get(fileName).stream().collect(toOptional());
96+
if (version.isPresent() && Runtime.version().feature() < version.get()) {
10197
continue;
10298
}
10399
testInputs.add(new Object[] {fileName, input, expectedOutput});
104100
}
105101
return testInputs;
106102
}
107103

108-
private static int getMajor() {
109-
try {
110-
Method versionMethod = Runtime.class.getMethod("version");
111-
Object version = versionMethod.invoke(null);
112-
return (int) version.getClass().getMethod("major").invoke(version);
113-
} catch (Exception e) {
114-
// continue below
115-
}
116-
int version = (int) Double.parseDouble(JAVA_CLASS_VERSION.value());
117-
if (49 <= version && version <= 52) {
118-
return version - (49 - 5);
119-
}
120-
throw new IllegalStateException("Unknown Java version: " + JAVA_SPECIFICATION_VERSION.value());
121-
}
122-
123104
private final String name;
124105
private final String input;
125106
private final String expected;

src/test/java/com/google/googlejavaformat/java/MainTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ public void packageInfo() throws Exception {
322322
"@ParametersAreNonnullByDefault",
323323
"package com.google.common.labs.base;",
324324
"",
325-
"import javax.annotation.CheckReturnValue;",
325+
"import com.google.errorprone.annotations.CheckReturnValue;",
326326
"import javax.annotation.ParametersAreNonnullByDefault;",
327327
"",
328328
};
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2021 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
15+
package com.google.googlejavaformat.java;
16+
17+
import static com.google.common.truth.Truth.assertThat;
18+
import static com.google.googlejavaformat.java.RemoveUnusedImports.removeUnusedImports;
19+
import static org.junit.Assume.assumeTrue;
20+
21+
import com.google.common.base.Joiner;
22+
import org.junit.Test;
23+
import org.junit.runner.RunWith;
24+
import org.junit.runners.JUnit4;
25+
26+
/** Tests that unused import removal doesn't remove types used in case labels. */
27+
@RunWith(JUnit4.class)
28+
public class RemoveUnusedImportsCaseLabelsTest {
29+
@Test
30+
public void preserveTypesInCaseLabels() throws FormatterException {
31+
assumeTrue(Runtime.version().feature() >= 17);
32+
String input =
33+
Joiner.on('\n')
34+
.join(
35+
"package example;",
36+
"import example.model.SealedInterface;",
37+
"import example.model.TypeA;",
38+
"import example.model.TypeB;",
39+
"public class Main {",
40+
" public void apply(SealedInterface sealedInterface) {",
41+
" switch(sealedInterface) {",
42+
" case TypeA a -> System.out.println(\"A!\");",
43+
" case TypeB b -> System.out.println(\"B!\");",
44+
" }",
45+
" }",
46+
"}");
47+
assertThat(removeUnusedImports(input)).isEqualTo(input);
48+
}
49+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
interface Test {
2+
3+
static class Test1 implements Test{}
4+
static class Test2 implements Test{}
5+
6+
public static void main(String[] args) {
7+
Test test = new Test1();
8+
switch (test) {
9+
case Test1 test1 -> {}
10+
case Test2 test2 -> {}
11+
default -> throw new IllegalStateException("Unexpected value: " + test);
12+
}
13+
}
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
interface Test {
2+
3+
static class Test1 implements Test {}
4+
5+
static class Test2 implements Test {}
6+
7+
public static void main(String[] args) {
8+
Test test = new Test1();
9+
switch (test) {
10+
case Test1 test1 -> {}
11+
case Test2 test2 -> {}
12+
default -> throw new IllegalStateException("Unexpected value: " + test);
13+
}
14+
}
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package example;
2+
3+
import example.model.SealedInterface;
4+
import example.model.TypeA;
5+
import example.model.TypeB;
6+
7+
public class Main {
8+
public void apply(SealedInterface sealedInterface) {
9+
switch(sealedInterface) {
10+
case TypeA a -> System.out.println("A!");
11+
case TypeB b -> System.out.println("B!");
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)