1616
1717import static java .lang .Math .min ;
1818import static java .nio .charset .StandardCharsets .UTF_8 ;
19+ import static java .util .Comparator .comparing ;
1920
2021import com .google .common .io .ByteStreams ;
2122import com .google .common .util .concurrent .MoreExecutors ;
3031import java .nio .file .Path ;
3132import java .nio .file .Paths ;
3233import java .time .Duration ;
34+ import java .util .ArrayList ;
3335import java .util .Arrays ;
34- import java .util .LinkedHashMap ;
35- import java .util .Map ;
36+ import java .util .Collections ;
37+ import java .util .List ;
3638import java .util .concurrent .ExecutionException ;
39+ import java .util .concurrent .ExecutorCompletionService ;
3740import java .util .concurrent .ExecutorService ;
3841import java .util .concurrent .Executors ;
39- import java .util .concurrent .Future ;
4042
4143/** The main class for the Java formatter CLI. */
4244public final class Main {
@@ -123,50 +125,54 @@ private int formatFiles(CommandLineOptions parameters, JavaFormatterOptions opti
123125 int numThreads = min (MAX_THREADS , parameters .files ().size ());
124126 ExecutorService executorService = Executors .newFixedThreadPool (numThreads );
125127
126- Map < Path , String > inputs = new LinkedHashMap <>();
127- Map < Path , Future < String >> results = new LinkedHashMap <>();
128+ ExecutorCompletionService < FormatFileCallable . Result > cs =
129+ new ExecutorCompletionService <>(executorService );
128130 boolean allOk = true ;
129131
132+ int files = 0 ;
130133 for (String fileName : parameters .files ()) {
131134 if (!fileName .endsWith (".java" )) {
132135 errWriter .println ("Skipping non-Java file: " + fileName );
133136 continue ;
134137 }
135138 Path path = Paths .get (fileName );
136- String input ;
137139 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 ++;
142142 } catch (IOException e ) {
143143 errWriter .println (fileName + ": could not read file: " + e .getMessage ());
144144 allOk = false ;
145145 }
146146 }
147147
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 ) {
151150 try {
152- formatted = result .getValue ().get ();
151+ files --;
152+ results .add (cs .take ().get ());
153153 } catch (InterruptedException e ) {
154154 errWriter .println (e .getMessage ());
155155 allOk = false ;
156156 continue ;
157157 } 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 );
165170 }
166171 allOk = false ;
167172 continue ;
168173 }
169- boolean changed = !formatted .equals (inputs .get (path ));
174+ String formatted = result .output ();
175+ boolean changed = result .changed ();
170176 if (changed && parameters .setExitIfChanged ()) {
171177 allOk = false ;
172178 }
@@ -205,9 +211,16 @@ private int formatStdin(CommandLineOptions parameters, JavaFormatterOptions opti
205211 }
206212 String stdinFilename = parameters .assumeFilename ().orElse (STDIN_FILENAME );
207213 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 ();
211224 if (changed && parameters .setExitIfChanged ()) {
212225 ok = false ;
213226 }
@@ -218,12 +231,6 @@ private int formatStdin(CommandLineOptions parameters, JavaFormatterOptions opti
218231 } else {
219232 outWriter .write (output );
220233 }
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).
227234 }
228235 return ok ? 0 : 1 ;
229236 }
0 commit comments