/**
  * Construct a {@code Formatter} given Java compilation unit. Parses the code; builds a {@link
  * JavaInput} and the corresponding {@link JavaOutput}.
  *
  * @param javaInput the input, a Java compilation unit
  * @param javaOutput the {@link JavaOutput}
  * @param maxWidth the maximum formatted width
  * @param errors mutable list to receive errors
  * @param indentationMultiplier the multiplier for the unit of indent; the default is 1
  */
 static void format(
     JavaInput javaInput,
     JavaOutput javaOutput,
     int maxWidth,
     List<FormatterDiagnostic> errors,
     int indentationMultiplier) {
   ASTParser parser = ASTParser.newParser(AST.JLS8);
   parser.setSource(javaInput.getText().toCharArray());
   @SuppressWarnings("unchecked") // safe by specification
   Map<String, String> options = JavaCore.getOptions();
   JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
   parser.setCompilerOptions(options);
   CompilationUnit unit = (CompilationUnit) parser.createAST(null);
   javaInput.setCompilationUnit(unit);
   if (unit.getMessages().length > 0) {
     for (Message message : unit.getMessages()) {
       errors.add(javaInput.createDiagnostic(message.getStartPosition(), message.getMessage()));
     }
     return;
   }
   OpsBuilder builder = new OpsBuilder(javaInput, javaOutput, errors);
   // Output compilation unit.
   new JavaInputAstVisitor(builder, indentationMultiplier).visit(unit);
   builder.sync(javaInput.getText().length());
   builder.drain();
   Doc doc = new DocBuilder().withOps(builder.build()).build();
   doc.computeBreaks(javaOutput.getCommentsHelper(), maxWidth, new Doc.State(+0, 0, 0));
   doc.write(javaOutput);
   javaOutput.flush();
 }
 /**
  * Emit a list of {@link Replacement}s to convert from input to output.
  *
  * @param input the input compilation unit
  * @param characterRanges the character ranges to reformat
  * @return a list of {@link Replacement}s, sorted from low index to high index, without overlaps
  * @throws FormatterException if the input string cannot be parsed
  */
 public ImmutableList<Replacement> getFormatReplacements(
     String input, List<Range<Integer>> characterRanges) throws FormatterException {
   JavaInput javaInput = new JavaInput(STDIN_FILENAME, input);
   JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper());
   List<FormatterDiagnostic> errors = new ArrayList<>();
   format(javaInput, javaOutput, MAX_WIDTH, errors, 1);
   if (!errors.isEmpty()) {
     throw new FormatterException(errors);
   }
   RangeSet<Integer> tokenRangeSet = characterRangesToTokenRanges(javaInput, characterRanges);
   return javaOutput.getFormatReplacements(tokenRangeSet);
 }
Example #3
0
  /**
   * Input constructor.
   *
   * @param text the input text
   * @throws FormatterException if the input cannot be parsed
   */
  public JavaInput(String filename, String text) throws FormatterException {
    this.filename = filename;
    this.text = text;
    char[] chars = text.toCharArray();
    List<String> lines = NEWLINE_SPLITTER.splitToList(text);
    setLines(ImmutableList.copyOf(lines));
    ImmutableList<Tok> toks = buildToks(text, chars);
    positionToColumnMap = makePositionToColumnMap(toks);
    tokens = buildTokens(toks);
    ImmutableSortedMap.Builder<Integer, Token> locationTokenMap = ImmutableSortedMap.naturalOrder();
    for (Token token : tokens) {
      locationTokenMap.put(JavaOutput.startTok(token).getPosition(), token);
    }
    positionTokenMap = locationTokenMap.build();

    // adjust kN for EOF
    kToToken = new Token[kN + 1];
    for (Token token : tokens) {
      for (Input.Tok tok : token.getToksBefore()) {
        if (tok.getIndex() < 0) {
          continue;
        }
        kToToken[tok.getIndex()] = token;
      }
      kToToken[token.getTok().getIndex()] = token;
      for (Input.Tok tok : token.getToksAfter()) {
        if (tok.getIndex() < 0) {
          continue;
        }
        kToToken[tok.getIndex()] = token;
      }
    }
  }
 /**
  * Format an input string (a compilation), for only the specified character ranges. These ranges
  * are extended as necessary (e.g., to encompass whole lines).
  *
  * @param input the input string
  * @param characterRanges the character ranges to be reformatted
  * @return the output string
  * @throws FormatterException if the input string cannot be parsed
  */
 public String formatSource(String input, List<Range<Integer>> characterRanges)
     throws FormatterException {
   JavaInput javaInput = new JavaInput(STDIN_FILENAME, input);
   JavaOutput javaOutput = new JavaOutput(javaInput, new JavaCommentsHelper());
   List<FormatterDiagnostic> errors = new ArrayList<>();
   format(javaInput, javaOutput, MAX_WIDTH, errors, 1);
   if (!errors.isEmpty()) {
     throw new FormatterException(errors);
   }
   StringBuilder result = new StringBuilder(input.length());
   RangeSet<Integer> tokenRangeSet = characterRangesToTokenRanges(javaInput, characterRanges);
   try {
     javaOutput.writeMerged(result, tokenRangeSet);
   } catch (IOException ignored) {
     throw new AssertionError("IOException impossible for StringWriter");
   }
   return result.toString();
 }