Formatter { static void format(final JavaInput javaInput, JavaOutput javaOutput, JavaFormatterOptions options) throws FormatterException { Context context = new Context(); DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); context.put(DiagnosticListener.class, diagnostics); Options.instance(context).put("allowStringFolding", "false"); Options.instance(context).put("--enable-preview", "true"); JCCompilationUnit unit; JavacFileManager fileManager = new JavacFileManager(context, true, UTF_8); try { fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, ImmutableList.of()); } catch (IOException e) { throw new IOError(e); } SimpleJavaFileObject source = new SimpleJavaFileObject(URI.create("source"), JavaFileObject.Kind.SOURCE) { @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { return javaInput.getText(); } }; Log.instance(context).useSource(source); ParserFactory parserFactory = ParserFactory.instance(context); JavacParser parser = parserFactory.newParser( javaInput.getText(), true, true, true); unit = parser.parseCompilationUnit(); unit.sourcefile = source; javaInput.setCompilationUnit(unit); Iterable<Diagnostic<? extends JavaFileObject>> errorDiagnostics = Iterables.filter(diagnostics.getDiagnostics(), Formatter::errorDiagnostic); if (!Iterables.isEmpty(errorDiagnostics)) { throw FormatterException.fromJavacDiagnostics(errorDiagnostics); } OpsBuilder builder = new OpsBuilder(javaInput, javaOutput); JavaInputAstVisitor visitor; if (getMajor() >= 14) { try { visitor = Class.forName("com.google.googlejavaformat.java.java14.Java14InputAstVisitor") .asSubclass(JavaInputAstVisitor.class) .getConstructor(OpsBuilder.class, int.class) .newInstance(builder, options.indentationMultiplier()); } catch (ReflectiveOperationException e) { throw new LinkageError(e.getMessage(), e); } } else { visitor = new JavaInputAstVisitor(builder, options.indentationMultiplier()); } visitor.scan(unit, null); builder.sync(javaInput.getText().length()); builder.drain(); Doc doc = new DocBuilder().withOps(builder.build()).build(); doc.computeBreaks(javaOutput.getCommentsHelper(), MAX_LINE_LENGTH, new Doc.State(+0, 0)); doc.write(javaOutput); javaOutput.flush(); } Formatter();  Formatter(JavaFormatterOptions options); void formatSource(CharSource input, CharSink output); String formatSource(String input); String formatSourceAndFixImports(String input); String formatSource(String input, Collection<Range<Integer>> characterRanges); ImmutableList<Replacement> getFormatReplacements(
      String input, Collection<Range<Integer>> characterRanges); static RangeSet<Integer> lineRangesToCharRanges(
      String input, RangeSet<Integer> lineRanges); static final int MAX_LINE_LENGTH; }
@Test public void testFormatAosp() throws Exception { String input = "class A{void b(){while(true){weCanBeCertainThatThisWillEndUpGettingWrapped(" + "because, it, is, just, so, very, very, very, very, looong);}}}"; String expectedOutput = Joiner.on("\n") .join( "class A {", " void b() {", " while (true) {", " weCanBeCertainThatThisWillEndUpGettingWrapped(", " because, it, is, just, so, very, very, very, very, looong);", " }", " }", "}", ""); Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("A.java"); Files.write(path, input.getBytes(StandardCharsets.UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); String[] args = {"--aosp", path.toString()}; assertThat(main.format(args)).isEqualTo(0); assertThat(out.toString()).isEqualTo(expectedOutput); }
@Test public void testFormatNonJavaFiles() throws Exception { StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); assertThat(main.format("foo.go")).isEqualTo(0); assertThat(err.toString()).contains("Skipping non-Java file: " + "foo.go"); assertThat(main.format("Foo.java")).isEqualTo(1); assertThat(err.toString()).contains("Foo.java: could not read file: "); }
@Test public void testFormatStdinStdoutWithDashFlag() throws Exception { String input = "class Foo{\n" + "void f\n" + "() {\n" + "}\n" + "}\n"; String expectedOutput = "class Foo {\n" + " void f() {}\n" + "}\n"; InputStream in = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); InputStream oldIn = System.in; System.setIn(in); Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); assertThat(main.format("-")).isEqualTo(0); assertThat(out.toString()).isEqualTo(expectedOutput); System.setIn(oldIn); }
@Test public void testFormatLengthUpToEOF() throws Exception { String input = "class Foo{\n" + "void f\n" + "() {\n" + "}\n" + "}\n\n\n\n\n\n"; String expectedOutput = "class Foo {\n" + " void f() {}\n" + "}\n"; Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); Files.write(path, input.getBytes(StandardCharsets.UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); String[] args = {"--offset", "0", "--length", String.valueOf(input.length()), path.toString()}; assertThat(main.format(args)).isEqualTo(0); assertThat(out.toString()).isEqualTo(expectedOutput); }
@Test public void testFormatLengthOutOfRange() throws Exception { String input = "class Foo{}\n"; Path tmpdir = testFolder.newFolder().toPath(); Path path = tmpdir.resolve("Foo.java"); Files.write(path, input.getBytes(StandardCharsets.UTF_8)); StringWriter out = new StringWriter(); StringWriter err = new StringWriter(); Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in); String[] args = {"--offset", "0", "--length", "9999", path.toString()}; assertThat(main.format(args)).isEqualTo(1); assertThat(err.toString()) .contains("error: invalid length 9999, offset + length (9999) is outside the file"); }