Skip to content

Commit 8b89b3d

Browse files
cushongoogle-java-format Team
authored andcommitted
Consolidate uses of javac's parser in google-java-format
PiperOrigin-RevId: 843673254
1 parent f5f92bf commit 8b89b3d

File tree

5 files changed

+87
-136
lines changed

5 files changed

+87
-136
lines changed

core/src/main/java/com/google/googlejavaformat/java/Formatter.java

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414

1515
package com.google.googlejavaformat.java;
1616

17-
import static java.nio.charset.StandardCharsets.UTF_8;
1817

1918
import com.google.common.collect.ImmutableList;
20-
import com.google.common.collect.Iterables;
2119
import com.google.common.collect.Iterators;
2220
import com.google.common.collect.Range;
2321
import com.google.common.collect.RangeSet;
@@ -31,25 +29,14 @@
3129
import com.google.googlejavaformat.Newlines;
3230
import com.google.googlejavaformat.Op;
3331
import com.google.googlejavaformat.OpsBuilder;
34-
import com.sun.tools.javac.file.JavacFileManager;
35-
import com.sun.tools.javac.parser.JavacParser;
36-
import com.sun.tools.javac.parser.ParserFactory;
3732
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
3833
import com.sun.tools.javac.util.Context;
39-
import com.sun.tools.javac.util.Log;
40-
import com.sun.tools.javac.util.Options;
41-
import java.io.IOError;
4234
import java.io.IOException;
43-
import java.net.URI;
4435
import java.util.ArrayList;
4536
import java.util.Collection;
4637
import java.util.List;
4738
import javax.tools.Diagnostic;
48-
import javax.tools.DiagnosticCollector;
49-
import javax.tools.DiagnosticListener;
5039
import javax.tools.JavaFileObject;
51-
import javax.tools.SimpleJavaFileObject;
52-
import javax.tools.StandardLocation;
5340

5441
/**
5542
* 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) {
11299
static void format(final JavaInput javaInput, JavaOutput javaOutput, JavaFormatterOptions options)
113100
throws FormatterException {
114101
Context context = new Context();
115-
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
116-
context.put(DiagnosticListener.class, diagnostics);
117-
Options.instance(context).put("allowStringFolding", "false");
118-
Options.instance(context).put("--enable-preview", "true");
119-
JCCompilationUnit unit;
120-
JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8);
121-
try {
122-
fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of());
123-
} catch (IOException e) {
124-
// impossible
125-
throw new IOError(e);
126-
}
127-
SimpleJavaFileObject source =
128-
new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) {
129-
@Override
130-
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
131-
return javaInput.getText();
132-
}
133-
};
134-
Log.instance(context).useSource(source);
135-
ParserFactory parserFactory = ParserFactory.instance(context);
136-
JavacParser parser =
137-
parserFactory.newParser(
138-
javaInput.getText(),
139-
/* keepDocComments= */ true,
140-
/* keepEndPos= */ true,
141-
/* keepLineMap= */ true);
142-
unit = parser.parseCompilationUnit();
143-
unit.sourcefile = source;
102+
List<Diagnostic<? extends JavaFileObject>> errorDiagnostics = new ArrayList<>();
103+
JCCompilationUnit unit =
104+
Trees.parse(
105+
context, errorDiagnostics, /* allowStringFolding= */ false, javaInput.getText());
144106

145107
javaInput.setCompilationUnit(unit);
146-
Iterable<Diagnostic<? extends JavaFileObject>> errorDiagnostics =
147-
Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic);
148-
if (!Iterables.isEmpty(errorDiagnostics)) {
108+
if (!errorDiagnostics.isEmpty()) {
149109
throw FormatterException.fromJavacDiagnostics(errorDiagnostics);
150110
}
151111
OpsBuilder builder = new OpsBuilder(javaInput, javaOutput);

core/src/main/java/com/google/googlejavaformat/java/FormatterException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414

1515
package com.google.googlejavaformat.java;
1616

17+
import static com.google.common.collect.ImmutableList.toImmutableList;
1718
import static java.util.Locale.ENGLISH;
1819

1920
import com.google.common.base.CharMatcher;
2021
import com.google.common.base.Splitter;
2122
import com.google.common.collect.ImmutableList;
22-
import com.google.common.collect.Iterables;
2323
import com.google.googlejavaformat.FormatterDiagnostic;
2424
import java.util.List;
2525
import java.util.regex.Pattern;
@@ -49,9 +49,11 @@ public List<FormatterDiagnostic> diagnostics() {
4949
}
5050

5151
public static FormatterException fromJavacDiagnostics(
52-
Iterable<Diagnostic<? extends JavaFileObject>> diagnostics) {
52+
List<Diagnostic<? extends JavaFileObject>> diagnostics) {
5353
return new FormatterException(
54-
Iterables.transform(diagnostics, FormatterException::toFormatterDiagnostic));
54+
diagnostics.stream()
55+
.map(FormatterException::toFormatterDiagnostic)
56+
.collect(toImmutableList()));
5557
}
5658

5759
private static FormatterDiagnostic toFormatterDiagnostic(Diagnostic<?> input) {

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

Lines changed: 5 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,9 @@
1919
import static com.google.common.base.Preconditions.checkArgument;
2020
import static com.google.googlejavaformat.java.Trees.getEndPosition;
2121
import static java.lang.Math.max;
22-
import static java.nio.charset.StandardCharsets.UTF_8;
2322

2423
import com.google.common.base.CharMatcher;
2524
import com.google.common.collect.HashMultimap;
26-
import com.google.common.collect.ImmutableList;
27-
import com.google.common.collect.Iterables;
2825
import com.google.common.collect.Multimap;
2926
import com.google.common.collect.Range;
3027
import com.google.common.collect.RangeMap;
@@ -43,32 +40,21 @@
4340
import com.sun.source.util.TreePathScanner;
4441
import com.sun.source.util.TreeScanner;
4542
import com.sun.tools.javac.api.JavacTrees;
46-
import com.sun.tools.javac.file.JavacFileManager;
47-
import com.sun.tools.javac.parser.JavacParser;
48-
import com.sun.tools.javac.parser.ParserFactory;
4943
import com.sun.tools.javac.tree.DCTree;
5044
import com.sun.tools.javac.tree.DCTree.DCReference;
5145
import com.sun.tools.javac.tree.JCTree;
5246
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
5347
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
5448
import com.sun.tools.javac.tree.JCTree.JCImport;
5549
import com.sun.tools.javac.util.Context;
56-
import com.sun.tools.javac.util.Log;
57-
import com.sun.tools.javac.util.Options;
58-
import java.io.IOError;
59-
import java.io.IOException;
6050
import java.lang.reflect.Method;
61-
import java.net.URI;
51+
import java.util.ArrayList;
6252
import java.util.LinkedHashSet;
6353
import java.util.List;
6454
import java.util.Map;
6555
import java.util.Set;
6656
import javax.tools.Diagnostic;
67-
import javax.tools.DiagnosticCollector;
68-
import javax.tools.DiagnosticListener;
6957
import javax.tools.JavaFileObject;
70-
import javax.tools.SimpleJavaFileObject;
71-
import javax.tools.StandardLocation;
7258
import org.jspecify.annotations.Nullable;
7359

7460
/**
@@ -231,38 +217,10 @@ public static String removeUnusedImports(final String contents) throws Formatter
231217

232218
private static JCCompilationUnit parse(Context context, String javaInput)
233219
throws FormatterException {
234-
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
235-
context.put(DiagnosticListener.class, diagnostics);
236-
Options.instance(context).put("--enable-preview", "true");
237-
Options.instance(context).put("allowStringFolding", "false");
238-
JCCompilationUnit unit;
239-
JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8);
240-
try {
241-
fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of());
242-
} catch (IOException e) {
243-
// impossible
244-
throw new IOError(e);
245-
}
246-
SimpleJavaFileObject source =
247-
new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) {
248-
@Override
249-
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
250-
return javaInput;
251-
}
252-
};
253-
Log.instance(context).useSource(source);
254-
ParserFactory parserFactory = ParserFactory.instance(context);
255-
JavacParser parser =
256-
parserFactory.newParser(
257-
javaInput,
258-
/* keepDocComments= */ true,
259-
/* keepEndPos= */ true,
260-
/* keepLineMap= */ true);
261-
unit = parser.parseCompilationUnit();
262-
unit.sourcefile = source;
263-
Iterable<Diagnostic<? extends JavaFileObject>> errorDiagnostics =
264-
Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic);
265-
if (!Iterables.isEmpty(errorDiagnostics)) {
220+
List<Diagnostic<? extends JavaFileObject>> errorDiagnostics = new ArrayList<>();
221+
JCTree.JCCompilationUnit unit =
222+
Trees.parse(context, errorDiagnostics, /* allowStringFolding= */ false, javaInput);
223+
if (!errorDiagnostics.isEmpty()) {
266224
// error handling is done during formatting
267225
throw FormatterException.fromJavacDiagnostics(errorDiagnostics);
268226
}

core/src/main/java/com/google/googlejavaformat/java/StringWrapper.java

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,12 @@
1919
import static com.google.googlejavaformat.java.Trees.getEndPosition;
2020
import static com.google.googlejavaformat.java.Trees.getStartPosition;
2121
import static java.lang.Math.min;
22-
import static java.nio.charset.StandardCharsets.UTF_8;
2322
import static java.util.stream.Collectors.joining;
2423

2524
import com.google.common.base.CharMatcher;
2625
import com.google.common.base.Strings;
2726
import com.google.common.base.Verify;
2827
import com.google.common.collect.ImmutableList;
29-
import com.google.common.collect.Iterables;
3028
import com.google.common.collect.Range;
3129
import com.google.common.collect.TreeRangeMap;
3230
import com.google.googlejavaformat.Newlines;
@@ -37,17 +35,9 @@
3735
import com.sun.source.tree.Tree.Kind;
3836
import com.sun.source.util.TreePath;
3937
import com.sun.source.util.TreePathScanner;
40-
import com.sun.tools.javac.file.JavacFileManager;
41-
import com.sun.tools.javac.parser.JavacParser;
42-
import com.sun.tools.javac.parser.ParserFactory;
4338
import com.sun.tools.javac.tree.JCTree;
4439
import com.sun.tools.javac.util.Context;
45-
import com.sun.tools.javac.util.Log;
46-
import com.sun.tools.javac.util.Options;
4740
import com.sun.tools.javac.util.Position;
48-
import java.io.IOException;
49-
import java.io.UncheckedIOException;
50-
import java.net.URI;
5141
import java.util.ArrayDeque;
5242
import java.util.ArrayList;
5343
import java.util.Deque;
@@ -56,11 +46,7 @@
5646
import java.util.Map;
5747
import java.util.concurrent.atomic.AtomicBoolean;
5848
import javax.tools.Diagnostic;
59-
import javax.tools.DiagnosticCollector;
60-
import javax.tools.DiagnosticListener;
6149
import javax.tools.JavaFileObject;
62-
import javax.tools.SimpleJavaFileObject;
63-
import javax.tools.StandardLocation;
6450

6551
/** Wraps string literals that exceed the column limit. */
6652
public final class StringWrapper {
@@ -480,34 +466,11 @@ private static boolean needWrapping(int columnLimit, String input) {
480466
/** Parses the given Java source. */
481467
private static JCTree.JCCompilationUnit parse(String source, boolean allowStringFolding)
482468
throws FormatterException {
483-
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
469+
List<Diagnostic<? extends JavaFileObject>> errorDiagnostics = new ArrayList<>();
484470
Context context = new Context();
485-
context.put(DiagnosticListener.class, diagnostics);
486-
Options.instance(context).put("--enable-preview", "true");
487-
Options.instance(context).put("allowStringFolding", Boolean.toString(allowStringFolding));
488-
JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8);
489-
try {
490-
fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of());
491-
} catch (IOException e) {
492-
throw new UncheckedIOException(e);
493-
}
494-
SimpleJavaFileObject sjfo =
495-
new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) {
496-
@Override
497-
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
498-
return source;
499-
}
500-
};
501-
Log.instance(context).useSource(sjfo);
502-
ParserFactory parserFactory = ParserFactory.instance(context);
503-
JavacParser parser =
504-
parserFactory.newParser(
505-
source, /* keepDocComments= */ true, /* keepEndPos= */ true, /* keepLineMap= */ true);
506-
JCTree.JCCompilationUnit unit = parser.parseCompilationUnit();
507-
unit.sourcefile = sjfo;
508-
Iterable<Diagnostic<? extends JavaFileObject>> errorDiagnostics =
509-
Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic);
510-
if (!Iterables.isEmpty(errorDiagnostics)) {
471+
JCTree.JCCompilationUnit unit =
472+
Trees.parse(context, errorDiagnostics, allowStringFolding, source);
473+
if (!errorDiagnostics.isEmpty()) {
511474
// error handling is done during formatting
512475
throw FormatterException.fromJavacDiagnostics(errorDiagnostics);
513476
}

core/src/main/java/com/google/googlejavaformat/java/Trees.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414

1515
package com.google.googlejavaformat.java;
1616

17+
import static com.google.googlejavaformat.java.Trees.getEndPosition;
18+
import static com.google.googlejavaformat.java.Trees.getStartPosition;
19+
import static java.nio.charset.StandardCharsets.UTF_8;
20+
21+
import com.google.common.collect.ImmutableList;
1722
import com.sun.source.tree.ClassTree;
1823
import com.sun.source.tree.CompilationUnitTree;
1924
import com.sun.source.tree.CompoundAssignmentTree;
@@ -24,13 +29,26 @@
2429
import com.sun.source.tree.ParenthesizedTree;
2530
import com.sun.source.tree.Tree;
2631
import com.sun.source.util.TreePath;
32+
import com.sun.tools.javac.file.JavacFileManager;
33+
import com.sun.tools.javac.parser.JavacParser;
34+
import com.sun.tools.javac.parser.ParserFactory;
2735
import com.sun.tools.javac.tree.JCTree;
2836
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
2937
import com.sun.tools.javac.tree.Pretty;
3038
import com.sun.tools.javac.tree.TreeInfo;
39+
import com.sun.tools.javac.util.Context;
40+
import com.sun.tools.javac.util.Log;
41+
import com.sun.tools.javac.util.Options;
3142
import java.io.IOError;
3243
import java.io.IOException;
44+
import java.net.URI;
45+
import java.util.List;
3346
import javax.lang.model.element.Name;
47+
import javax.tools.Diagnostic;
48+
import javax.tools.DiagnosticListener;
49+
import javax.tools.JavaFileObject;
50+
import javax.tools.SimpleJavaFileObject;
51+
import javax.tools.StandardLocation;
3452

3553
/** Utilities for working with {@link Tree}s. */
3654
class Trees {
@@ -118,4 +136,54 @@ static ClassTree getEnclosingTypeDeclaration(TreePath path) {
118136
static ExpressionTree skipParen(ExpressionTree node) {
119137
return ((ParenthesizedTree) node).getExpression();
120138
}
139+
140+
static JCCompilationUnit parse(
141+
Context context,
142+
List<Diagnostic<? extends JavaFileObject>> errorDiagnostics,
143+
boolean allowStringFolding,
144+
String javaInput) {
145+
DiagnosticListener<JavaFileObject> diagnostics =
146+
diagnostic -> {
147+
if (errorDiagnostic(diagnostic)) {
148+
errorDiagnostics.add(diagnostic);
149+
}
150+
};
151+
context.put(DiagnosticListener.class, diagnostics);
152+
Options.instance(context).put("--enable-preview", "true");
153+
Options.instance(context).put("allowStringFolding", Boolean.toString(allowStringFolding));
154+
JavacFileManager fileManager = new JavacFileManager(context, /* register= */ true, UTF_8);
155+
try {
156+
fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of());
157+
} catch (IOException e) {
158+
// impossible
159+
throw new IOError(e);
160+
}
161+
SimpleJavaFileObject source =
162+
new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) {
163+
@Override
164+
public String getCharContent(boolean ignoreEncodingErrors) {
165+
return javaInput;
166+
}
167+
};
168+
Log.instance(context).useSource(source);
169+
ParserFactory parserFactory = ParserFactory.instance(context);
170+
JavacParser parser =
171+
parserFactory.newParser(
172+
javaInput,
173+
/* keepDocComments= */ true,
174+
/* keepEndPos= */ true,
175+
/* keepLineMap= */ true);
176+
JCCompilationUnit unit = parser.parseCompilationUnit();
177+
unit.sourcefile = source;
178+
return unit;
179+
}
180+
181+
private static boolean errorDiagnostic(Diagnostic<?> input) {
182+
if (input.getKind() != Diagnostic.Kind.ERROR) {
183+
return false;
184+
}
185+
// accept constructor-like method declarations that don't match the name of their
186+
// enclosing class
187+
return !input.getCode().equals("compiler.err.invalid.meth.decl.ret.type.req");
188+
}
121189
}

0 commit comments

Comments
 (0)