16
16
17
17
import static java .lang .Math .min ;
18
18
import static java .nio .charset .StandardCharsets .UTF_8 ;
19
+ import static java .util .Comparator .comparing ;
19
20
20
21
import com .google .common .io .ByteStreams ;
21
22
import com .google .common .util .concurrent .MoreExecutors ;
30
31
import java .nio .file .Path ;
31
32
import java .nio .file .Paths ;
32
33
import java .time .Duration ;
34
+ import java .util .ArrayList ;
33
35
import java .util .Arrays ;
34
- import java .util .LinkedHashMap ;
35
- import java .util .Map ;
36
+ import java .util .Collections ;
37
+ import java .util .List ;
36
38
import java .util .concurrent .ExecutionException ;
39
+ import java .util .concurrent .ExecutorCompletionService ;
37
40
import java .util .concurrent .ExecutorService ;
38
41
import java .util .concurrent .Executors ;
39
- import java .util .concurrent .Future ;
40
42
41
43
/** The main class for the Java formatter CLI. */
42
44
public final class Main {
@@ -123,50 +125,54 @@ private int formatFiles(CommandLineOptions parameters, JavaFormatterOptions opti
123
125
int numThreads = min (MAX_THREADS , parameters .files ().size ());
124
126
ExecutorService executorService = Executors .newFixedThreadPool (numThreads );
125
127
126
- Map < Path , String > inputs = new LinkedHashMap <>();
127
- Map < Path , Future < String >> results = new LinkedHashMap <>();
128
+ ExecutorCompletionService < FormatFileCallable . Result > cs =
129
+ new ExecutorCompletionService <>(executorService );
128
130
boolean allOk = true ;
129
131
132
+ int files = 0 ;
130
133
for (String fileName : parameters .files ()) {
131
134
if (!fileName .endsWith (".java" )) {
132
135
errWriter .println ("Skipping non-Java file: " + fileName );
133
136
continue ;
134
137
}
135
138
Path path = Paths .get (fileName );
136
- String input ;
137
139
try {
138
- input = new String (Files .readAllBytes (path ), UTF_8 );
139
- inputs .put (path , input );
140
- results .put (
141
- path , executorService .submit (new FormatFileCallable (parameters , input , options )));
140
+ cs .submit (new FormatFileCallable (parameters , path , Files .readString (path ), options ));
141
+ files ++;
142
142
} catch (IOException e ) {
143
143
errWriter .println (fileName + ": could not read file: " + e .getMessage ());
144
144
allOk = false ;
145
145
}
146
146
}
147
147
148
- for (Map .Entry <Path , Future <String >> result : results .entrySet ()) {
149
- Path path = result .getKey ();
150
- String formatted ;
148
+ List <FormatFileCallable .Result > results = new ArrayList <>();
149
+ while (files > 0 ) {
151
150
try {
152
- formatted = result .getValue ().get ();
151
+ files --;
152
+ results .add (cs .take ().get ());
153
153
} catch (InterruptedException e ) {
154
154
errWriter .println (e .getMessage ());
155
155
allOk = false ;
156
156
continue ;
157
157
} catch (ExecutionException e ) {
158
- if (e .getCause () instanceof FormatterException ) {
159
- for (FormatterDiagnostic diagnostic : ((FormatterException ) e .getCause ()).diagnostics ()) {
160
- errWriter .println (path + ":" + diagnostic );
161
- }
162
- } else {
163
- errWriter .println (path + ": error: " + e .getCause ().getMessage ());
164
- e .getCause ().printStackTrace (errWriter );
158
+ errWriter .println ("error: " + e .getCause ().getMessage ());
159
+ e .getCause ().printStackTrace (errWriter );
160
+ allOk = false ;
161
+ continue ;
162
+ }
163
+ }
164
+ Collections .sort (results , comparing (FormatFileCallable .Result ::path ));
165
+ for (FormatFileCallable .Result result : results ) {
166
+ Path path = result .path ();
167
+ if (result .exception () != null ) {
168
+ for (FormatterDiagnostic diagnostic : result .exception ().diagnostics ()) {
169
+ errWriter .println (path + ":" + diagnostic );
165
170
}
166
171
allOk = false ;
167
172
continue ;
168
173
}
169
- boolean changed = !formatted .equals (inputs .get (path ));
174
+ String formatted = result .output ();
175
+ boolean changed = result .changed ();
170
176
if (changed && parameters .setExitIfChanged ()) {
171
177
allOk = false ;
172
178
}
@@ -205,9 +211,16 @@ private int formatStdin(CommandLineOptions parameters, JavaFormatterOptions opti
205
211
}
206
212
String stdinFilename = parameters .assumeFilename ().orElse (STDIN_FILENAME );
207
213
boolean ok = true ;
208
- try {
209
- String output = new FormatFileCallable (parameters , input , options ).call ();
210
- boolean changed = !input .equals (output );
214
+ FormatFileCallable .Result result =
215
+ new FormatFileCallable (parameters , null , input , options ).call ();
216
+ if (result .exception () != null ) {
217
+ for (FormatterDiagnostic diagnostic : result .exception ().diagnostics ()) {
218
+ errWriter .println (stdinFilename + ":" + diagnostic );
219
+ }
220
+ ok = false ;
221
+ } else {
222
+ String output = result .output ();
223
+ boolean changed = result .changed ();
211
224
if (changed && parameters .setExitIfChanged ()) {
212
225
ok = false ;
213
226
}
@@ -218,12 +231,6 @@ private int formatStdin(CommandLineOptions parameters, JavaFormatterOptions opti
218
231
} else {
219
232
outWriter .write (output );
220
233
}
221
- } catch (FormatterException e ) {
222
- for (FormatterDiagnostic diagnostic : e .diagnostics ()) {
223
- errWriter .println (stdinFilename + ":" + diagnostic );
224
- }
225
- ok = false ;
226
- // TODO(cpovirk): Catch other types of exception (as we do in the formatFiles case).
227
234
}
228
235
return ok ? 0 : 1 ;
229
236
}
0 commit comments