public EclipseCCodeFormatter() {
   HashMap<String, String> options = CCorePlugin.getOptions();
   codeFormatter = org.eclipse.cdt.core.ToolFactory.createDefaultCodeFormatter(options);
 }
Beispiel #2
0
  /**
   * Applies the C++ code formatter to the code affected by refactoring.
   *
   * @param multiEdit The text edit produced by refactoring.
   * @param code The code being modified.
   * @param project The project containing the code.
   * @return The text edit containing formatted refactoring changes, or the original text edit in
   *     case of errors.
   */
  private MultiTextEdit formatChangedCode(MultiTextEdit multiEdit, String code, IProject project) {
    IDocument document = new Document(code);
    try {
      // Apply refactoring changes to a temporary document.
      TextEdit edit = multiEdit.copy();
      edit.apply(document, TextEdit.UPDATE_REGIONS);

      // Expand regions affected by the changes to cover complete lines. We calculate two
      // sets of regions, reflecting the state of the document before and after
      // the refactoring changes.
      TextEdit[] edits = edit.getChildren();
      TextEdit[] originalEdits = multiEdit.getChildren();
      IRegion[] regionsAfter = new IRegion[edits.length];
      IRegion[] regionsBefore = new IRegion[edits.length];
      int numRegions = 0;
      int prevEnd = -1;
      for (int i = 0; i < edits.length; i++) {
        edit = edits[i];
        int offset = edit.getOffset();
        int end = offset + edit.getLength();
        int newOffset = document.getLineInformationOfOffset(offset).getOffset();
        int newEnd = endOffset(document.getLineInformationOfOffset(end));
        edit = originalEdits[i];
        int offsetBefore = edit.getOffset();
        int newOffsetBefore = newOffset + offsetBefore - offset;
        int newEndBefore = newEnd + offsetBefore + edit.getLength() - end;
        if (newOffset <= prevEnd) {
          numRegions--;
          newOffset = regionsAfter[numRegions].getOffset();
          newOffsetBefore = regionsBefore[numRegions].getOffset();
        }
        prevEnd = newEnd;
        regionsAfter[numRegions] = new Region(newOffset, newEnd - newOffset);
        regionsBefore[numRegions] = new Region(newOffsetBefore, newEndBefore - newOffsetBefore);
        numRegions++;
      }

      if (numRegions < regionsAfter.length) {
        regionsAfter = Arrays.copyOf(regionsAfter, numRegions);
        regionsBefore = Arrays.copyOf(regionsBefore, numRegions);
      }

      // Calculate formatting changes for the regions after the refactoring changes.
      ICProject proj = CCorePlugin.getDefault().getCoreModel().create(project);
      Map<String, String> options = proj.getOptions(true);
      // Allow all comments to be indented.
      options.put(
          DefaultCodeFormatterConstants
              .FORMATTER_COMMENT_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN,
          DefaultCodeFormatterConstants.FALSE);
      CodeFormatter formatter = ToolFactory.createCodeFormatter(options);
      code = document.get();
      TextEdit[] formatEdits =
          formatter.format(
              CodeFormatter.K_TRANSLATION_UNIT,
              code,
              regionsAfter,
              TextUtilities.getDefaultLineDelimiter(document));

      // For each of the regions we apply formatting changes and create a ReplaceEdit using
      // the region before the refactoring changes and the text after the formatting changes.
      MultiTextEdit resultEdit = new MultiTextEdit();
      for (int i = 0; i < regionsAfter.length; i++) {
        IRegion region = regionsAfter[i];
        int offset = region.getOffset();
        edit = formatEdits[i];
        edit.moveTree(-offset);
        document = new Document(code.substring(offset, offset + region.getLength()));
        edit.apply(document, TextEdit.NONE);
        region = regionsBefore[i];
        edit = new ReplaceEdit(region.getOffset(), region.getLength(), document.get());
        resultEdit.addChild(edit);
      }
      return resultEdit;
    } catch (MalformedTreeException e) {
      CCorePlugin.log(e);
      return multiEdit;
    } catch (BadLocationException e) {
      CCorePlugin.log(e);
      return multiEdit;
    }
  }