private void handleMultiLineComment(Token comment, int index) { flushBuffer(comment.originalStart); if (this.childBuilder == null) { this.childBuilder = new TextEditsBuilder(this); } this.childBuilder.traverseInternalStructure(comment, index); this.edits.addAll(this.childBuilder.edits); this.childBuilder.edits.clear(); this.counter = this.childBuilder.sourceLimit; }
public TextEditsBuilder(String source, List<IRegion> regions, TokenManager tokenManager, DefaultCodeFormatterOptions options) { this.source = source; this.tm = tokenManager; this.options = options; this.regions = adaptRegions(regions); this.alignChar = this.options.align_with_spaces ? DefaultCodeFormatterOptions.SPACE : this.options.tab_char; this.sourceLimit = source.length(); this.parent = null; this.buffer = new StringBuilder(); }
public String createIndentationString(final int indentationLevel) { if (indentationLevel < 0) { throw new IllegalArgumentException(); } StringBuilder sb = new StringBuilder(); int indent = indentationLevel * this.originalOptions.indentation_size; TextEditsBuilder.appendIndentationString(sb, this.originalOptions.tab_char, this.originalOptions.tab_size, indent, 0); return sb.toString(); }
private void bufferWhitespaceBefore(Token token, int index) { if (getLineBreaksBefore() > 0) { this.stringLiteralsInLine.clear(); if (getLineBreaksBefore() > 1) { Token indentToken = null; if (this.options.indent_empty_lines && token.tokenType != TokenNameNotAToken) { for (int i = 1; i < getLineBreaksBefore(); i++) { bufferLineSeparator(token, true); if (indentToken != null) bufferIndent(indentToken, index); bufferLineSeparator(token, false); bufferAlign(token, index); bufferIndent(token, index); } else if (index == 0 && this.parent == null) { bufferIndent(token, index); } else { if (!bufferAlign(token, index) && isSpaceBefore()) this.buffer.append(' ');
@Override protected boolean token(Token token, int index) { bufferWhitespaceBefore(token, index); List<Token> structure = token.getInternalStructure(); if (token.tokenType == TokenNameCOMMENT_LINE) { handleSingleLineComment(token, index); } else if (structure != null && !structure.isEmpty()) { handleMultiLineComment(token, index); } else { flushBuffer(token.originalStart); if (token.isToEscape()) { this.buffer.append(this.tm.toString(token)); flushBuffer(token.originalEnd + 1); } else { this.counter = token.originalEnd + 1; } } if (token.tokenType == TokenNameStringLiteral) this.stringLiteralsInLine.add(token); if (getNext() == null) { for (int i = 0; i < token.getLineBreaksAfter(); i++) bufferLineSeparator(null, i + 1 == token.getLineBreaksAfter()); char lastChar = this.source.charAt(this.sourceLimit - 1); if (token.getLineBreaksAfter() == 0 && (lastChar == '\r' || lastChar == '\n')) bufferLineSeparator(null, false); flushBuffer(this.sourceLimit); } return true; }
this.parent.bufferLineSeparator(null, false); this.parent.bufferIndent(this.parent.tm.get(this.parentTokenIndex), this.parentTokenIndex); this.counter = this.parent.counter; return; // this is an unformatted block comment, don't force asterisk if (getNext() == null && !emptyLine) return; // this is the last token of block comment, asterisk is included if (c == '*') { this.buffer.append(' '); flushBuffer(i); while (i + 1 < this.sourceLimit && this.source.charAt(i + 1) == '*') i++;
TextEditsBuilder resultBuilder = new TextEditsBuilder(source, this.formatRegions, this.tokenManager, this.workingOptions); resultBuilder.setAlignChar(DefaultCodeFormatterOptions.SPACE); for (Token token : this.tokens) { List<Token> structure = token.getInternalStructure(); if (structure != null && !structure.isEmpty()) resultBuilder.processComment(token); for (TextEdit edit : resultBuilder.getEdits()) { result.addChild(edit);
private void handleSingleLineComment(Token lineComment, int index) { List<Token> structure = lineComment.getInternalStructure(); if (structure == null) { flushBuffer(lineComment.originalStart); this.counter = lineComment.originalEnd + 1; return; flushBuffer(structure.get(0).originalStart); } else { flushBuffer(lineComment.originalStart); bufferLineSeparator(fragment, false); bufferIndent(fragment, index); } else if (fragment.isSpaceBefore() && i > 0) { this.buffer.append(' '); flushBuffer(fragment.originalStart); this.counter = fragment.originalEnd + 1; flushBuffer(lineComment.originalEnd + 1);
/** * {@inheritDoc} */ public TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) { if (!regionsSatisfiesPreconditions(regions, source.length())) { throw new IllegalArgumentException(); } this.formatRegions = Arrays.asList(regions); updateWorkingOptions(indentationLevel, lineSeparator, kind); if ((kind & K_COMMENTS_MASK) != 0) return formatComments(source, kind & K_COMMENTS_MASK); if (prepareFormattedCode(source, kind) == null) return this.tokens.isEmpty() ? new MultiTextEdit() : null; MultiTextEdit result = new MultiTextEdit(); TextEditsBuilder resultBuilder = new TextEditsBuilder(this.sourceString, this.formatRegions, this.tokenManager, this.workingOptions); this.tokenManager.traverse(0, resultBuilder); for (TextEdit edit : resultBuilder.getEdits()) { result.addChild(edit); } return result; }
private void bufferIndent(Token token, int index) { int indent = token.getIndent(); if (getCurrent() != null && getCurrent() != token) indent += getCurrent().getEmptyLineIndentAdjustment(); int spaces = 0; if (this.options.use_tabs_only_for_leading_indentations && this.options.tab_char != DefaultCodeFormatterOptions.SPACE) { WrapPolicy wrapPolicy = token.getWrapPolicy(); boolean isWrappedBlockComment = this.childBuilder != null && this.childBuilder.parentTokenIndex == index; if (isWrappedBlockComment) { Token lineStart = this.tm.get(this.tm.findFirstTokenInLine(index)); spaces = token.getIndent() - lineStart.getIndent(); token = lineStart; wrapPolicy = token.getWrapPolicy(); } while (wrapPolicy != null) { Token parentLineStart = this.tm.get(this.tm.findFirstTokenInLine(wrapPolicy.wrapParentIndex)); if (wrapPolicy.wrapMode != WrapMode.FORCED) spaces += token.getIndent() - parentLineStart.getIndent(); token = parentLineStart; wrapPolicy = token.getWrapPolicy(); } } appendIndentationString(this.buffer, this.options.tab_char, this.options.tab_size, indent - spaces, spaces); }
private ReplaceEdit getReplaceEdit(int editStart, int editEnd, String text, IRegion region) { int regionEnd = region.getOffset() + region.getLength(); if (editStart < region.getOffset() && regionEnd < editEnd) { int breaksInReplacement = this.tm.countLineBreaksBetween(text, 0, text.length()); int breaksBeforeRegion = this.tm.countLineBreaksBetween(this.source, editStart, region.getOffset()); int breaksAfterRegion = this.tm.countLineBreaksBetween(this.source, regionEnd, editEnd); if (breaksBeforeRegion + breaksAfterRegion > breaksInReplacement) { text = ""; //$NON-NLS-1$ editStart = region.getOffset(); editEnd = regionEnd; } } if (region.getOffset() > editStart && isOnlyWhitespace(text)) { int breaksInReplacement = this.tm.countLineBreaksBetween(text, 0, text.length()); int breaksOutsideRegion = this.tm.countLineBreaksBetween(this.source, editStart, region.getOffset()); int breaksToPreserve = breaksInReplacement - breaksOutsideRegion; text = adaptReplaceText(text, breaksToPreserve, false, region.getOffset() - 1); editStart = region.getOffset(); } if (regionEnd < editEnd && isOnlyWhitespace(text)) { int breaksInReplacement = this.tm.countLineBreaksBetween(text, 0, text.length()); int breaksOutsideRegion = this.tm.countLineBreaksBetween(this.source, regionEnd, editEnd); int breaksToPreserve = breaksInReplacement - breaksOutsideRegion; text = adaptReplaceText(text, breaksToPreserve, true, regionEnd); editEnd = regionEnd; } return new ReplaceEdit(editStart, editEnd - editStart, text); }
@Override protected boolean token(Token token, int index) { bufferWhitespaceBefore(token, index); List<Token> structure = token.getInternalStructure(); if (token.tokenType == TokenNameCOMMENT_LINE) { handleSingleLineComment(token, index); } else if (structure != null && !structure.isEmpty()) { handleMultiLineComment(token, index); } else { flushBuffer(token.originalStart); if (token.isToEscape()) { this.buffer.append(this.tm.toString(token)); flushBuffer(token.originalEnd + 1); } else { this.counter = token.originalEnd + 1; } } if (token.tokenType == TokenNameStringLiteral) this.stringLiteralsInLine.add(token); if (getNext() == null) { for (int i = 0; i < token.getLineBreaksAfter(); i++) bufferLineSeparator(null, i + 1 == token.getLineBreaksAfter()); char lastChar = this.source.charAt(this.sourceLimit - 1); if (token.getLineBreaksAfter() == 0 && (lastChar == '\r' || lastChar == '\n')) bufferLineSeparator(null, false); flushBuffer(this.sourceLimit); } return true; }
private void bufferWhitespaceBefore(Token token, int index) { if (getLineBreaksBefore() > 0) { this.stringLiteralsInLine.clear(); if (getLineBreaksBefore() > 1) { Token indentToken = null; if (this.options.indent_empty_lines && token.tokenType != TokenNameNotAToken) { for (int i = 1; i < getLineBreaksBefore(); i++) { bufferLineSeparator(token, true); if (indentToken != null) bufferIndent(indentToken, index); bufferLineSeparator(token, false); bufferAlign(token, index); bufferIndent(token, index); } else if (index == 0 && this.parent == null) { bufferIndent(token, index); } else { bufferAlign(token, index); if (isSpaceBefore() && token.getAlign() == 0) this.buffer.append(' ');
this.parent.bufferLineSeparator(null, false); this.parent.bufferIndent(this.parent.tm.get(this.parentTokenIndex), this.parentTokenIndex); this.counter = this.parent.counter; return; // this is an unformatted block comment, don't force asterisk if (getNext() == null && !emptyLine) return; // this is the last token of block comment, asterisk is included if (c == '*') { this.buffer.append(' '); flushBuffer(i); while (i + 1 < this.sourceLimit && this.source.charAt(i + 1) == '*') i++;
TextEditsBuilder resultBuilder = new TextEditsBuilder(source, this.formatRegions, this.tokenManager, this.workingOptions); resultBuilder.setAlignChar(DefaultCodeFormatterOptions.SPACE); for (Token token : this.tokens) { List<Token> structure = token.getInternalStructure(); if (structure != null && !structure.isEmpty()) resultBuilder.processComment(token); for (TextEdit edit : resultBuilder.getEdits()) { result.addChild(edit);
private void handleSingleLineComment(Token lineComment, int index) { List<Token> structure = lineComment.getInternalStructure(); if (structure == null) { flushBuffer(lineComment.originalStart); this.counter = lineComment.originalEnd + 1; return; flushBuffer(structure.get(0).originalStart); } else { flushBuffer(lineComment.originalStart); bufferLineSeparator(fragment, false); bufferIndent(fragment, index); } else if (fragment.isSpaceBefore() && i > 0) { this.buffer.append(' '); flushBuffer(fragment.originalStart); this.counter = fragment.originalEnd + 1; flushBuffer(lineComment.originalEnd + 1);
/** * {@inheritDoc} */ @Override public TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) { if (!regionsSatisfiesPreconditions(regions, source.length())) { throw new IllegalArgumentException(); } this.formatRegions = Arrays.asList(regions); updateWorkingOptions(indentationLevel, lineSeparator, kind); if ((kind & K_COMMENTS_MASK) != 0) return formatComments(source, kind & K_COMMENTS_MASK); if (prepareFormattedCode(source, kind) == null) return this.tokens.isEmpty() ? new MultiTextEdit() : null; MultiTextEdit result = new MultiTextEdit(); TextEditsBuilder resultBuilder = new TextEditsBuilder(this.sourceString, this.formatRegions, this.tokenManager, this.workingOptions); this.tokenManager.traverse(0, resultBuilder); for (TextEdit edit : resultBuilder.getEdits()) { result.addChild(edit); } return result; }
private void bufferIndent(Token token, int index) { int indent = token.getIndent(); if (getCurrent() != null && getCurrent() != token) indent += getCurrent().getEmptyLineIndentAdjustment(); int spaces = 0; if (this.options.use_tabs_only_for_leading_indentations && this.options.tab_char != DefaultCodeFormatterOptions.SPACE) { WrapPolicy wrapPolicy = token.getWrapPolicy(); boolean isWrappedBlockComment = this.childBuilder != null && this.childBuilder.parentTokenIndex == index; if (isWrappedBlockComment) { Token lineStart = this.tm.get(this.tm.findFirstTokenInLine(index)); spaces = token.getIndent() - lineStart.getIndent(); token = lineStart; wrapPolicy = token.getWrapPolicy(); } while (wrapPolicy != null) { Token parentLineStart = this.tm.get(this.tm.findFirstTokenInLine(wrapPolicy.wrapParentIndex)); if (wrapPolicy.wrapMode != WrapMode.BLOCK_INDENT) spaces += token.getIndent() - parentLineStart.getIndent(); token = parentLineStart; wrapPolicy = token.getWrapPolicy(); } } appendIndentationString(this.buffer, this.options.tab_char, this.options.tab_size, indent - spaces, spaces); }
private ReplaceEdit getReplaceEdit(int editStart, int editEnd, String text, IRegion region) { int regionEnd = region.getOffset() + region.getLength(); if (editStart < region.getOffset() && regionEnd < editEnd) { int breaksInReplacement = this.tm.countLineBreaksBetween(text, 0, text.length()); int breaksBeforeRegion = this.tm.countLineBreaksBetween(this.source, editStart, region.getOffset()); int breaksAfterRegion = this.tm.countLineBreaksBetween(this.source, regionEnd, editEnd); if (breaksBeforeRegion + breaksAfterRegion > breaksInReplacement) { text = ""; //$NON-NLS-1$ editStart = region.getOffset(); editEnd = regionEnd; } } if (region.getOffset() > editStart && isOnlyWhitespace(text)) { int breaksInReplacement = this.tm.countLineBreaksBetween(text, 0, text.length()); int breaksOutsideRegion = this.tm.countLineBreaksBetween(this.source, editStart, region.getOffset()); int breaksToPreserve = breaksInReplacement - breaksOutsideRegion; text = adaptReplaceText(text, breaksToPreserve, false, region.getOffset() - 1); editStart = region.getOffset(); } if (regionEnd < editEnd && isOnlyWhitespace(text)) { int breaksInReplacement = this.tm.countLineBreaksBetween(text, 0, text.length()); int breaksOutsideRegion = this.tm.countLineBreaksBetween(this.source, regionEnd, editEnd); int breaksToPreserve = breaksInReplacement - breaksOutsideRegion; text = adaptReplaceText(text, breaksToPreserve, true, regionEnd); editEnd = regionEnd; } return new ReplaceEdit(editStart, editEnd - editStart, text); }
@Override protected boolean token(Token token, int index) { bufferWhitespaceBefore(token, index); List<Token> structure = token.getInternalStructure(); if (token.tokenType == TokenNameCOMMENT_LINE) { handleSingleLineComment(token, index); } else if (structure != null && !structure.isEmpty()) { handleMultiLineComment(token, index); } else { flushBuffer(token.originalStart); if (token.isToEscape()) { this.buffer.append(this.tm.toString(token)); flushBuffer(token.originalEnd + 1); } else { this.counter = token.originalEnd + 1; } } if (token.tokenType == TokenNameStringLiteral) this.stringLiteralsInLine.add(token); if (getNext() == null) { for (int i = 0; i < token.getLineBreaksAfter(); i++) bufferLineSeparator(null, i + 1 == token.getLineBreaksAfter()); char lastChar = this.source.charAt(this.sourceLimit - 1); if (token.getLineBreaksAfter() == 0 && (lastChar == '\r' || lastChar == '\n')) bufferLineSeparator(null, false); flushBuffer(this.sourceLimit); } return true; }