diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterConstants.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterConstants.java index 37d46223e84..029c96b504e 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterConstants.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterConstants.java @@ -109,26 +109,28 @@ public class DefaultCodeFormatterConstants { * @see #createAlignmentValue(boolean, int, int) */ public static final String FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION = CCorePlugin.PLUGIN_ID + ".formatter.alignment_for_arguments_in_method_invocation"; //$NON-NLS-1$ -// /** -// *
-// * FORMATTER / Option for alignment of assignment
-// * - option id: "org.eclipse.cdt.core.formatter.alignment_for_assignment"
-// * - possible values: values returned by createAlignmentValue(boolean, int, int)
call
-// * - default: createAlignmentValue(false, M_NO_ALIGNMENT, INDENT_DEFAULT)
-// *
-// * @see #createAlignmentValue(boolean, int, int)
-// */
-// public static final String FORMATTER_ALIGNMENT_FOR_ASSIGNMENT = CCorePlugin.PLUGIN_ID + ".formatter.alignment_for_assignment"; //$NON-NLS-1$
-// /**
-// *
-// * FORMATTER / Option for alignment of binary expression
-// * - option id: "org.eclipse.cdt.core.formatter.alignment_for_binary_expression"
-// * - possible values: values returned by createAlignmentValue(boolean, int, int)
call
-// * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
-// *
-// * @see #createAlignmentValue(boolean, int, int)
-// */
-// public static final String FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION = CCorePlugin.PLUGIN_ID + ".formatter.alignment_for_binary_expression"; //$NON-NLS-1$
+ /**
+ *
+ * FORMATTER / Option for alignment of assignment
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_assignment"
+ * - possible values: values returned by createAlignmentValue(boolean, int, int)
call
+ * - default: createAlignmentValue(false, M_NO_ALIGNMENT, INDENT_DEFAULT)
+ *
+ * @see #createAlignmentValue(boolean, int, int)
+ * @since 5.3
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_ASSIGNMENT = CCorePlugin.PLUGIN_ID + ".formatter.alignment_for_assignment"; //$NON-NLS-1$
+ /**
+ *
+ * FORMATTER / Option for alignment of binary expression
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_binary_expression"
+ * - possible values: values returned by createAlignmentValue(boolean, int, int)
call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ *
+ * @see #createAlignmentValue(boolean, int, int)
+ * @since 5.3
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION = CCorePlugin.PLUGIN_ID + ".formatter.alignment_for_binary_expression"; //$NON-NLS-1$
/**
* * FORMATTER / Option for alignment of compact if @@ -2037,6 +2039,16 @@ public class DefaultCodeFormatterConstants { **/ public static final String FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE = CCorePlugin.PLUGIN_ID + ".formatter.number_of_empty_lines_to_preserve"; //$NON-NLS-1$ + /** + *
+ * FORMATTER / Option to specify whether the formatter can join wrapped lines or not + * - option id: "org.eclipse.cdt.core.formatter.join_wrapped_lines" + * - possible values: { TRUE, FALSE } + * - default: TRUE + *+ * @since 5.3 + */ + public static final String FORMATTER_JOIN_WRAPPED_LINES = CCorePlugin.PLUGIN_ID + ".formatter.join_wrapped_lines"; //$NON-NLS-1$ /** *
* FORMATTER / Option to specify whether or not empty statement should be on a new line diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java index 6e8270fc1ea..3ecf4a8a278 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java @@ -472,7 +472,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, scribe.startNewLine(); } else { // preserve newline if not explicitly requested - if (scribe.preserveNewLine()) { + if (scribe.printCommentPreservingNewLines()) { scribe.space(); } } @@ -1251,7 +1251,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, final Listdeclarators= Arrays.asList(node.getDeclarators()); if (!declarators.isEmpty()) { if (declarators.size() == 1 && declarators.get(0) instanceof IASTFunctionDeclarator) { - if (scribe.preserveNewLine()) { + if (scribe.printCommentPreservingNewLines()) { scribe.space(); } } else { @@ -1324,7 +1324,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } } else { // preserve newline if not explicitly requested - scribe.preserveNewLine(); + scribe.printCommentPreservingNewLines(); } declaration.accept(this); @@ -1795,8 +1795,11 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, private int visit(IASTConditionalExpression node) { node.getLogicalConditionExpression().accept(this); - - Alignment conditionalExpressionAlignment =scribe.createAlignment( + scribe.printTrailingComment(); + if (preferences.insert_space_before_question_in_conditional) { + scribe.space(); + } + Alignment conditionalExpressionAlignment = scribe.createAlignment( "conditionalExpression", //$NON-NLS-1$ preferences.alignment_for_conditional_expression, 2, @@ -1807,7 +1810,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, do { try { scribe.alignFragment(conditionalExpressionAlignment, 0); - scribe.printNextToken(Token.tQUESTION, preferences.insert_space_before_question_in_conditional); + scribe.printNextToken(Token.tQUESTION, false); if (preferences.insert_space_after_question_in_conditional) { scribe.space(); @@ -1961,8 +1964,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, // declaration initializer Alignment expressionAlignment= scribe.createAlignment( "declarationInitializer", //$NON-NLS-1$ - // need configurable alignment - Alignment.M_COMPACT_SPLIT, + preferences.alignment_for_assignment, 1, scribe.scanner.getCurrentPosition()); @@ -2003,7 +2005,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, Alignment expressionAlignment= scribe.createAlignment( "designatedInitializer", //$NON-NLS-1$ - Alignment.M_COMPACT_SPLIT, + preferences.alignment_for_assignment, 1, scribe.scanner.getCurrentPosition()); @@ -2141,21 +2143,26 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } private int visit(IASTBinaryExpression node) { - final IASTExpression op1= node.getOperand1(); - // operand 1 - op1.accept(this); - Alignment expressionAlignment= scribe.createAlignment( - "binaryExpression", //$NON-NLS-1$ - // need configurable alignment - Alignment.M_COMPACT_SPLIT, - 1, - scribe.scanner.getCurrentPosition()); + if (isAssignment(node)) { + return formatAssignment(node); + } + Alignment expressionAlignment= scribe.createAlignment( + "binaryExpression", //$NON-NLS-1$ + preferences.alignment_for_binary_expression, + 2, + scribe.scanner.getCurrentPosition()); - scribe.enterAlignment(expressionAlignment); + scribe.enterAlignment(expressionAlignment); boolean ok = false; do { try { scribe.alignFragment(expressionAlignment, 0); + final IASTExpression op1= node.getOperand1(); + // operand 1 + op1.accept(this); + + scribe.printTrailingComment(); + scribe.alignFragment(expressionAlignment, 1); // operator final int nextToken= peekNextToken(); @@ -2167,22 +2174,6 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, case IASTBinaryExpression.op_pmarrow: scribe.printNextToken(nextToken, false); break; - case IASTBinaryExpression.op_assign: - case IASTBinaryExpression.op_binaryAndAssign: - case IASTBinaryExpression.op_binaryOrAssign: - case IASTBinaryExpression.op_binaryXorAssign: - case IASTBinaryExpression.op_divideAssign: - case IASTBinaryExpression.op_minusAssign: - case IASTBinaryExpression.op_moduloAssign: - case IASTBinaryExpression.op_multiplyAssign: - case IASTBinaryExpression.op_plusAssign: - case IASTBinaryExpression.op_shiftLeftAssign: - case IASTBinaryExpression.op_shiftRightAssign: - scribe.printNextToken(nextToken, forceSpace || preferences.insert_space_before_assignment_operator); - if (forceSpace || preferences.insert_space_after_assignment_operator) { - scribe.space(); - } - break; default: scribe.printNextToken(nextToken, forceSpace || preferences.insert_space_before_binary_operator); if (forceSpace || preferences.insert_space_after_binary_operator) { @@ -2203,6 +2194,64 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, return PROCESS_SKIP; } + private int formatAssignment(IASTBinaryExpression node) { + final IASTExpression op1= node.getOperand1(); + // operand 1 + op1.accept(this); + + Alignment expressionAlignment= scribe.createAlignment( + "assignmentExpression", //$NON-NLS-1$ + preferences.alignment_for_assignment, + 1, + scribe.scanner.getCurrentPosition()); + + scribe.enterAlignment(expressionAlignment); + boolean ok = false; + do { + try { + scribe.alignFragment(expressionAlignment, 0); + + // operator + final int nextToken= peekNextToken(); + // in case of C++ alternative operators, like 'and', 'not', etc. a space + boolean forceSpace= Character.isJavaIdentifierStart(peekNextChar()); + + scribe.printNextToken(nextToken, forceSpace || preferences.insert_space_before_assignment_operator); + if (forceSpace || preferences.insert_space_after_assignment_operator) { + scribe.space(); + } + + // operand 2 + final IASTExpression op2= node.getOperand2(); + op2.accept(this); + + ok = true; + } catch (AlignmentException e) { + scribe.redoAlignment(e); + } + } while (!ok); + scribe.exitAlignment(expressionAlignment, true); + return PROCESS_SKIP; + } + + private boolean isAssignment(IASTBinaryExpression node) { + switch (node.getOperator()) { + case IASTBinaryExpression.op_assign: + case IASTBinaryExpression.op_binaryAndAssign: + case IASTBinaryExpression.op_binaryOrAssign: + case IASTBinaryExpression.op_binaryXorAssign: + case IASTBinaryExpression.op_divideAssign: + case IASTBinaryExpression.op_minusAssign: + case IASTBinaryExpression.op_moduloAssign: + case IASTBinaryExpression.op_multiplyAssign: + case IASTBinaryExpression.op_plusAssign: + case IASTBinaryExpression.op_shiftLeftAssign: + case IASTBinaryExpression.op_shiftRightAssign: + return true; + } + return false; + } + private int visit(IASTLiteralExpression node) { if (node.getKind() == IASTLiteralExpression.lk_string_literal) { // handle concatenation of string literals @@ -3202,13 +3251,18 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, } private void formatLeftCurlyBrace(final int line, final String bracePosition) { - // deal with (quite unexpected) comments right before lcurly - scribe.printComment(); - if (DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP.equals(bracePosition) - && (scribe.line > line || scribe.column >= preferences.page_width)) - { - scribe.startNewLine(); - } + scribe.formatBrace = true; + try { + // deal with (quite unexpected) comments right before lcurly + scribe.printComment(); + if (DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP.equals(bracePosition) + && (scribe.line > line || scribe.column >= preferences.page_width)) + { + scribe.startNewLine(); + } + } finally { + scribe.formatBrace = false; + } } private void formatOpeningBrace(String bracePosition, boolean insertSpaceBeforeBrace) { diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/DefaultCodeFormatterOptions.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/DefaultCodeFormatterOptions.java index af5e0a5822b..3c57b30af60 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/DefaultCodeFormatterOptions.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/DefaultCodeFormatterOptions.java @@ -56,8 +56,8 @@ public class DefaultCodeFormatterOptions { } public int alignment_for_arguments_in_method_invocation; -// public int alignment_for_assignment; -// public int alignment_for_binary_expression; + public int alignment_for_assignment; + public int alignment_for_binary_expression; public int alignment_for_compact_if; public int alignment_for_conditional_expression; public int alignment_for_expressions_in_initializer_list; @@ -238,6 +238,7 @@ public class DefaultCodeFormatterOptions { public boolean keep_simple_if_on_one_line; public boolean keep_then_statement_on_same_line; public int number_of_empty_lines_to_preserve; + public boolean join_wrapped_lines; public boolean put_empty_statement_on_new_line; public int tab_size; public int page_width; @@ -264,8 +265,8 @@ public class DefaultCodeFormatterOptions { Map options = new HashMap (); // options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION, getAlignment(this.alignment_for_arguments_in_allocation_expression)); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION, getAlignment(this.alignment_for_arguments_in_method_invocation)); -// options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT, getAlignment(this.alignment_for_assignment)); -// options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION, getAlignment(this.alignment_for_binary_expression)); + options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT, getAlignment(this.alignment_for_assignment)); + options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION, getAlignment(this.alignment_for_binary_expression)); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_COMPACT_IF, getAlignment(this.alignment_for_compact_if)); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION, getAlignment(this.alignment_for_conditional_expression)); options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_INITIALIZER_LIST, getAlignment(this.alignment_for_expressions_in_initializer_list)); @@ -439,6 +440,7 @@ public class DefaultCodeFormatterOptions { options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_SIMPLE_IF_ON_ONE_LINE, this.keep_simple_if_on_one_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE); options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_THEN_STATEMENT_ON_SAME_LINE, this.keep_then_statement_on_same_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE); options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, Integer.toString(this.number_of_empty_lines_to_preserve)); + options.put(DefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES, this.join_wrapped_lines ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE); options.put(DefaultCodeFormatterConstants.FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE, this.put_empty_statement_on_new_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE); options.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, Integer.toString(this.page_width)); switch(this.tab_char) { @@ -478,26 +480,26 @@ public class DefaultCodeFormatterOptions { this.alignment_for_arguments_in_method_invocation = Alignment.M_COMPACT_SPLIT; } } -// final Object alignmentForAssignmentOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT); -// if (alignmentForAssignmentOption != null) { -// try { -// this.alignment_for_assignment = Integer.parseInt((String) alignmentForAssignmentOption); -// } catch (NumberFormatException e) { -// this.alignment_for_assignment = Alignment.M_ONE_PER_LINE_SPLIT; -// } catch (ClassCastException e) { -// this.alignment_for_assignment = Alignment.M_ONE_PER_LINE_SPLIT; -// } -// } -// final Object alignmentForBinaryExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION); -// if (alignmentForBinaryExpressionOption != null) { -// try { -// this.alignment_for_binary_expression = Integer.parseInt((String) alignmentForBinaryExpressionOption); -// } catch (NumberFormatException e) { -// this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT; -// } catch (ClassCastException e) { -// this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT; -// } -// } + final Object alignmentForAssignmentOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT); + if (alignmentForAssignmentOption != null) { + try { + this.alignment_for_assignment = Integer.parseInt((String) alignmentForAssignmentOption); + } catch (NumberFormatException e) { + this.alignment_for_assignment = Alignment.M_ONE_PER_LINE_SPLIT; + } catch (ClassCastException e) { + this.alignment_for_assignment = Alignment.M_ONE_PER_LINE_SPLIT; + } + } + final Object alignmentForBinaryExpressionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION); + if (alignmentForBinaryExpressionOption != null) { + try { + this.alignment_for_binary_expression = Integer.parseInt((String) alignmentForBinaryExpressionOption); + } catch (NumberFormatException e) { + this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT; + } catch (ClassCastException e) { + this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT; + } + } final Object alignmentForCompactIfOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_COMPACT_IF); if (alignmentForCompactIfOption != null) { try { @@ -1360,6 +1362,10 @@ public class DefaultCodeFormatterOptions { this.number_of_empty_lines_to_preserve = 0; } } + final Object joinWrappedLinesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES); + if (joinWrappedLinesOption != null) { + this.join_wrapped_lines = DefaultCodeFormatterConstants.TRUE.equals(joinWrappedLinesOption); + } final Object putEmptyStatementOnNewLineOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE); if (putEmptyStatementOnNewLineOption != null) { this.put_empty_statement_on_new_line = DefaultCodeFormatterConstants.TRUE.equals(putEmptyStatementOnNewLineOption); @@ -1403,9 +1409,9 @@ public class DefaultCodeFormatterOptions { public void setDefaultSettings() { // this.alignment_for_arguments_in_allocation_expression = Alignment.M_COMPACT_SPLIT; this.alignment_for_arguments_in_method_invocation = Alignment.M_COMPACT_SPLIT; -// this.alignment_for_assignment = Alignment.M_NO_ALIGNMENT; -// this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT; -// this.alignment_for_compact_if = Alignment.M_COMPACT_SPLIT; + this.alignment_for_assignment = Alignment.M_NO_ALIGNMENT; + this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT; + this.alignment_for_compact_if = Alignment.M_COMPACT_SPLIT; this.alignment_for_conditional_expression = Alignment.M_NEXT_PER_LINE_SPLIT; this.alignment_for_expressions_in_initializer_list = Alignment.M_COMPACT_SPLIT; this.alignment_for_declarator_list = Alignment.M_COMPACT_SPLIT; @@ -1576,6 +1582,7 @@ public class DefaultCodeFormatterOptions { this.keep_simple_if_on_one_line = false; this.keep_then_statement_on_same_line = false; this.number_of_empty_lines_to_preserve = 1; + this.join_wrapped_lines = true; this.put_empty_statement_on_new_line = true; this.tab_size = 4; this.page_width = 80; @@ -1659,7 +1666,6 @@ public class DefaultCodeFormatterOptions { this.keep_empty_initializer_list_on_one_line = false; this.keep_simple_if_on_one_line = false; this.keep_then_statement_on_same_line = false; - this.number_of_empty_lines_to_preserve = 1; this.put_empty_statement_on_new_line = true; this.tab_size = 4; this.page_width = 80; @@ -1732,7 +1738,6 @@ public class DefaultCodeFormatterOptions { this.keep_empty_initializer_list_on_one_line = false; this.keep_simple_if_on_one_line = false; this.keep_then_statement_on_same_line = false; - this.number_of_empty_lines_to_preserve = 1; this.put_empty_statement_on_new_line = true; this.tab_size = 2; this.page_width = 80; @@ -1799,7 +1804,6 @@ public class DefaultCodeFormatterOptions { this.keep_empty_initializer_list_on_one_line = false; this.keep_simple_if_on_one_line = false; this.keep_then_statement_on_same_line = false; - this.number_of_empty_lines_to_preserve = 1; this.put_empty_statement_on_new_line = true; this.tab_size = 8; this.page_width = 80; diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/Scribe.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/Scribe.java index 4e0071cd453..8c20b54aaf6 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/Scribe.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/Scribe.java @@ -65,10 +65,11 @@ public class Scribe { private boolean preserveNewLines; private boolean checkLineWrapping; public int lastNumberOfNewLines; + boolean formatBrace; public int line; - public boolean needSpace= false; - public boolean pendingSpace= false; + public boolean needSpace; + public boolean pendingSpace; public int tabLength; public int tabChar; @@ -103,6 +104,7 @@ public class Scribe { } lineSeparator= preferences.line_separator; indentationLevel= preferences.initial_indentation_level * indentationSize; + preserveNewLines = false; textRegionStart= offset; textRegionEnd= offset + length - 1; reset(); @@ -424,8 +426,7 @@ public class Scribe { public String getNewLine() { if (lastNumberOfNewLines >= 1) { - column= 1; // ensure that the scribe is at the beginning of a new - // line + column= 1; // ensure that the scribe is at the beginning of a new line return EMPTY_STRING; } line++; @@ -458,13 +459,26 @@ public class Scribe { } private String getPreserveEmptyLines(int count) { - if (count > 0) { - if (preferences.number_of_empty_lines_to_preserve != 0) { - int linesToPreserve= Math.min(count, preferences.number_of_empty_lines_to_preserve); - return getEmptyLines(linesToPreserve); - } else { - return getNewLine(); + if (count == 0 && !preserveNewLines) { + // preserve line breaks in wrapping if specified + if ((!preferences.join_wrapped_lines) && lastNumberOfNewLines == 0) { + // Create new line + StringBuilder tempBuffer = new StringBuilder(); + tempBuffer.append(getNewLine()); + + if (currentAlignment != null && !formatBrace) { + indentationLevel = currentAlignment.breakIndentationLevel; + } + // Print the computed indentation in the buffer + printIndentationIfNecessary(tempBuffer); + + return tempBuffer.toString(); } + return EMPTY_STRING; + } + if (preferences.number_of_empty_lines_to_preserve != 0) { + int linesToPreserve= Math.min(count, preferences.number_of_empty_lines_to_preserve); + return getEmptyLines(linesToPreserve); } else if (preserveNewLines) { return getNewLine(); } @@ -753,9 +767,6 @@ public class Scribe { lastNumberOfNewLines= 0; printIndentationIfNecessary(); if (considerSpaceIfAny) { - if (currentAlignment != null && currentAlignment.isIndentOnColumn(column)) { - needSpace= true; - } space(); } if (pendingSpace) { @@ -961,7 +972,7 @@ public class Scribe { } else if (hasLineComment) { preserveEmptyLines(count - 1, scanner.getCurrentTokenStartPosition()); addDeleteEdit(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition()); - } else if (count != 0 && preferences.number_of_empty_lines_to_preserve != 0) { + } else if (count != 0 && (!preferences.join_wrapped_lines || preferences.number_of_empty_lines_to_preserve != 0)) { String preservedEmptyLines= getPreserveEmptyLines(count - 1); addReplaceEdit(scanner.getCurrentTokenStartPosition(), scanner.getCurrentTokenEndPosition(), preservedEmptyLines); @@ -1230,7 +1241,8 @@ public class Scribe { return; } if (lastNumberOfNewLines >= 1) { - column= 1; // ensure that the scribe is at the beginning of a new line + // ensure that the scribe is at the beginning of a new line + column = 1; return; } addInsertEdit(insertPosition, lineSeparator); @@ -1246,21 +1258,31 @@ public class Scribe { } public void printNextToken(int expectedTokenType, boolean considerSpaceIfAny) { - printComment(); - if (shouldSkip(scanner.getCurrentPosition())) { - return; + // Set brace flag, it's useful for the scribe while preserving line breaks + switch (expectedTokenType) { + case Token.tRBRACE: + case Token.tLBRACE: + formatBrace = true; } - currentToken= scanner.nextToken(); - if (currentToken == null || expectedTokenType != currentToken.type) { - if (pendingSpace) { - addInsertEdit(scanner.getCurrentTokenStartPosition(), SPACE); + try { + printComment(); + if (shouldSkip(scanner.getCurrentPosition())) { + return; } - pendingSpace= false; - needSpace= true; - throw new AbortFormatting( - "[" + (line+1) + "/" + column + "] unexpected token type, expecting:" + expectedTokenType + ", actual:" + currentToken);//$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + currentToken= scanner.nextToken(); + if (currentToken == null || expectedTokenType != currentToken.type) { + if (pendingSpace) { + addInsertEdit(scanner.getCurrentTokenStartPosition(), SPACE); + } + pendingSpace= false; + needSpace= true; + throw new AbortFormatting( + "[" + (line+1) + "/" + column + "] unexpected token type, expecting:" + expectedTokenType + ", actual:" + currentToken);//$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + print(currentToken.getLength(), considerSpaceIfAny); + } finally { + formatBrace = false; } - print(currentToken.getLength(), considerSpaceIfAny); } public void printNextToken(int[] expectedTokenTypes) { @@ -1596,16 +1618,6 @@ public class Scribe { return !isFirstModifier; } - public boolean preserveNewLine() { - boolean savedPreserveNewLines= preserveNewLines; - try { - preserveNewLines= true; - return printComment(); - } finally { - preserveNewLines= savedPreserveNewLines; - } - } - /** * Skip to the next occurrence of the given token type. * If successful, the next token will be the epxected token, @@ -1672,12 +1684,12 @@ public class Scribe { } public boolean printCommentPreservingNewLines() { - final boolean savedPreserveNL= this.preserveNewLines; - this.preserveNewLines= true; + final boolean savedPreserveNL= preserveNewLines; + preserveNewLines= true; try { return printComment(); } finally { - this.preserveNewLines= savedPreserveNL; + preserveNewLines= savedPreserveNL; } } @@ -1729,7 +1741,6 @@ public class Scribe { scanner.resetTo(offset, scannerEndPosition - 1); } } - } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java index ecd4576b8c7..86d09d68147 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java @@ -222,6 +222,7 @@ public class CodeFormatterTest extends BaseUITestCase { //int verylooooooooooooooooooooooooooooooooooongname = // 0000000000000000000000000000000; public void testLineWrappingOfInitializerExpression_Bug200961() throws Exception { + fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT, Integer.toString(Alignment.M_COMPACT_SPLIT)); assertFormatterResult(); } @@ -1407,5 +1408,43 @@ public class CodeFormatterTest extends BaseUITestCase { public void testRangeBasedFor_Bug328472() throws Exception { assertFormatterResult(); } + + //int table[][] = { + // {1,2,3,4}, + // { 1, 2, 3 , 4}, + //{ 1,2, 3,4 }, + // {1, 2,3, 4} + // }; + //int table[][] = { + // { 1, 2, 3, 4 }, + // { 1, 2, 3, 4 }, + // { 1, 2, 3, 4 }, + // { 1, 2, 3, 4 } + //}; + public void testKeepWrappedLines_Bug322776() throws Exception { + fOptions.put(DefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES, DefaultCodeFormatterConstants.FALSE); + assertFormatterResult(); + } + + //void f() { + //double confidence = 0.316030 // + //- 0.016315 * C_Count // + //+ 0.034336 * N_Count // + //+ 0.066810 * O_Count // + //+ 0.035674 * F_Count; + //} + + //void f() { + // double confidence = 0.316030 // + // - 0.016315 * C_Count // + // + 0.034336 * N_Count // + // + 0.066810 * O_Count // + // + 0.035674 * F_Count; + //} + public void testAlignmentOfBinaryExpression_Bug325787() throws Exception { + fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION, + Integer.toString(Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_ON_COLUMN)); + assertFormatterResult(); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.java index d050d04ead0..3cc40af8330 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.java @@ -205,7 +205,7 @@ final class FormatterMessages extends NLS { public static String LineWrappingTabPage_enumerator_list; public static String LineWrappingTabPage_initializer_list; public static String LineWrappingTabPage_conditionals; -// public static String LineWrappingTabPage_binary_exprs; + public static String LineWrappingTabPage_binary_exprs; public static String LineWrappingTabPage_indentation_default; public static String LineWrappingTabPage_indentation_on_column; public static String LineWrappingTabPage_indentation_by_one; @@ -214,6 +214,7 @@ final class FormatterMessages extends NLS { public static String LineWrappingTabPage_function_calls; public static String LineWrappingTabPage_expressions; // public static String LineWrappingTabPage_statements; + public static String LineWrappingTabPage_do_not_join_lines; public static String LineWrappingTabPage_base_clause_lowercase; // public static String LineWrappingTabPage_compact_if_else_lowercase; @@ -224,7 +225,7 @@ final class FormatterMessages extends NLS { public static String LineWrappingTabPage_enumerator_list_lowercase; public static String LineWrappingTabPage_initializer_list_lowercase; public static String LineWrappingTabPage_conditionals_lowercase; -// public static String LineWrappingTabPage_binary_exprs_lowercase; + public static String LineWrappingTabPage_binary_exprs_lowercase; public static String LineWrappingTabPage_indentation_default_lowercase; public static String LineWrappingTabPage_indentation_on_column_lowercase; public static String LineWrappingTabPage_indentation_by_one_lowercase; @@ -233,7 +234,8 @@ final class FormatterMessages extends NLS { public static String LineWrappingTabPage_function_calls_lowercase; public static String LineWrappingTabPage_expressions_lowercase; // public static String LineWrappingTabPage_statements_lowercase; - + public static String LineWrappingTabPage_assignment_alignment_lowercase; + public static String LineWrappingTabPage_wrapping_policy_label_text; public static String LineWrappingTabPage_indentation_policy_label_text; public static String LineWrappingTabPage_force_split_checkbox_text; @@ -255,7 +257,7 @@ final class FormatterMessages extends NLS { public static String LineWrappingTabPage_width_indent_option_default_indent_wrapped; public static String LineWrappingTabPage_width_indent_option_default_indent_array; public static String LineWrappingTabPage_error_invalid_value; -// public static String LineWrappingTabPage_assignment_alignment; + public static String LineWrappingTabPage_assignment_alignment; public static String AlreadyExistsDialog_message_profile_already_exists; public static String AlreadyExistsDialog_message_profile_name_empty; public static String AlreadyExistsDialog_dialog_title; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.properties index a642bb4a2c4..05e74776b09 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.properties @@ -232,7 +232,7 @@ LineWrappingTabPage_enum_decls='enum' declaration LineWrappingTabPage_enumerator_list=Enumerator list LineWrappingTabPage_initializer_list=Initializer list LineWrappingTabPage_conditionals=Conditionals -#LineWrappingTabPage_binary_exprs=Binary expressions +LineWrappingTabPage_binary_exprs=Binary expressions LineWrappingTabPage_indentation_default=Default indentation LineWrappingTabPage_indentation_on_column=Indent on column LineWrappingTabPage_indentation_by_one=Indent by one @@ -241,6 +241,7 @@ LineWrappingTabPage_function_decls=Function declarations LineWrappingTabPage_function_calls=Function calls LineWrappingTabPage_expressions=Expressions #LineWrappingTabPage_statements=Statements +LineWrappingTabPage_do_not_join_lines=Never join already wrapped lin&es #lower case table entries description; LineWrappingTabPage_base_clause_lowercase=base-clause @@ -253,7 +254,7 @@ LineWrappingTabPage_enum_decls_lowercase='enum' declaration LineWrappingTabPage_enumerator_list_lowercase=enumerator list LineWrappingTabPage_initializer_list_lowercase=initializer list LineWrappingTabPage_conditionals_lowercase=conditionals -#LineWrappingTabPage_binary_exprs_lowercase=binary expressions +LineWrappingTabPage_binary_exprs_lowercase=binary expressions LineWrappingTabPage_indentation_default_lowercase=default indentation LineWrappingTabPage_indentation_on_column_lowercase=indent on column LineWrappingTabPage_indentation_by_one_lowercase=indent by one @@ -262,6 +263,7 @@ LineWrappingTabPage_function_decls_lowercase=function declarations LineWrappingTabPage_function_calls_lowercase=function calls LineWrappingTabPage_expressions_lowercase=expressions #LineWrappingTabPage_statements_lowercase=statements +LineWrappingTabPage_assignment_alignment_lowercase=assignments LineWrappingTabPage_wrapping_policy_label_text=Lin&e wrapping policy: LineWrappingTabPage_indentation_policy_label_text=Indent&ation policy: @@ -284,7 +286,7 @@ LineWrappingTabPage_width_indent_option_max_line_width=Ma&ximum line width: LineWrappingTabPage_width_indent_option_default_indent_wrapped=Defa&ult indentation for wrapped lines: LineWrappingTabPage_width_indent_option_default_indent_array=Default indentation for initializer lists: LineWrappingTabPage_error_invalid_value=The key ''{0}'' contained an invalid value; resetting to defaults. -#LineWrappingTabPage_assignment_alignment=Assignments +LineWrappingTabPage_assignment_alignment=Assignments AlreadyExistsDialog_message_profile_already_exists=A profile with this name already exists. diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterTabPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterTabPage.java index 56d2a63271d..5c8e3eda754 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterTabPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterTabPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -21,12 +21,20 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; +import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.cdt.ui.CUIPlugin; public abstract class FormatterTabPage extends ModifyDialogTabPage { private final static String SHOW_INVISIBLE_PREFERENCE_KEY= CUIPlugin.PLUGIN_ID + ".formatter_page.show_invisible_characters"; //$NON-NLS-1$ - + + /** + * Constant array for boolean true/false selection. + * + * @since 5.3 + */ + protected static String[] TRUE_FALSE= { DefaultCodeFormatterConstants.TRUE, DefaultCodeFormatterConstants.FALSE }; + private CPreview fPreview; private final IDialogSettings fDialogSettings; private Button fShowInvisibleButton; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/LineWrappingTabPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/LineWrappingTabPage.java index e4768cc3a31..29dace9acbd 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/LineWrappingTabPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/LineWrappingTabPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -447,18 +447,18 @@ public class LineWrappingTabPage extends FormatterTabPage { FormatterMessages.LineWrappingTabPage_conditionals_lowercase ); -// private final Category fBinaryExpressionCategory= new Category( -// DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION, -// "class Example extends AnotherClass {" + //$NON-NLS-1$ -// "int foo() {" + //$NON-NLS-1$ -// " int sum= 100 + 200 + 300 + 400 + 500 + 600 + 700 + 800;" + //$NON-NLS-1$ -// " int product= 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10;" + //$NON-NLS-1$ -// " boolean val= true && false && true && false && true;" + //$NON-NLS-1$ -// " return product / sum;}}", //$NON-NLS-1$ -// FormatterMessages.LineWrappingTabPage_binary_exprs, -// FormatterMessages.LineWrappingTabPage_binary_exprs_lowercase -// ); -// + private final Category fBinaryExpressionCategory= new Category( + DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION, + "class Example : AnotherClass {" + //$NON-NLS-1$ + "int foo() {" + //$NON-NLS-1$ + " int sum= 100 + 200 + 300 + 400 + 500 + 600 + 700 + 800;" + //$NON-NLS-1$ + " int product= 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10;" + //$NON-NLS-1$ + " bool val= true && false && true && false && true;" + //$NON-NLS-1$ + " return product / sum;}}", //$NON-NLS-1$ + FormatterMessages.LineWrappingTabPage_binary_exprs, + FormatterMessages.LineWrappingTabPage_binary_exprs_lowercase + ); + // private final Category fEnumConstArgumentsCategory= new Category( // DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ENUM_CONSTANT, // "enum Example {" + //$NON-NLS-1$ @@ -482,18 +482,18 @@ public class LineWrappingTabPage extends FormatterTabPage { FormatterMessages.LineWrappingTabPage_enumerator_list, FormatterMessages.LineWrappingTabPage_enumerator_list_lowercase ); -// -// private final Category fAssignmentCategory= new Category( -// DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT, -// "class Example {" + //$NON-NLS-1$ -// "private static final String string = \"TextTextText\";" + //$NON-NLS-1$ -// "void foo() {" + //$NON-NLS-1$ -// "for (int i = 0; i < 10; i++) {}" + //$NON-NLS-1$ -// "String s;" + //$NON-NLS-1$ -// "s = \"TextTextText\";}}", //$NON-NLS-1$ -// FormatterMessages.LineWrappingTabPage_assignment_alignment, -// FormatterMessages.LineWrappingTabPage_assignment_alignment_lowercase -// ); + + private final Category fAssignmentCategory= new Category( + DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ASSIGNMENT, + "static char* string = \"TextTextText\";" + //$NON-NLS-1$ + "class Example {" + //$NON-NLS-1$ + "void foo() {" + //$NON-NLS-1$ + "for (int i = 0; i < 10; i++) {}" + //$NON-NLS-1$ + "char* s;" + //$NON-NLS-1$ + "s = \"TextTextText\";}}", //$NON-NLS-1$ + FormatterMessages.LineWrappingTabPage_assignment_alignment, + FormatterMessages.LineWrappingTabPage_assignment_alignment_lowercase + ); /** * The default preview line width. @@ -600,10 +600,10 @@ public class LineWrappingTabPage extends FormatterTabPage { // functionCalls.children.add(fQualifiedAllocationExpressionCategory); final Category expressions= new Category(FormatterMessages.LineWrappingTabPage_expressions,FormatterMessages.LineWrappingTabPage_expressions_lowercase); -// expressions.children.add(fBinaryExpressionCategory); + expressions.children.add(fBinaryExpressionCategory); expressions.children.add(fConditionalExpressionCategory); expressions.children.add(fInitializerListExpressionsCategory); -// expressions.children.add(fAssignmentCategory); + expressions.children.add(fAssignmentCategory); // final Category statements= new Category(FormatterMessages.LineWrappingTabPage_statements); // statements.children.add(fCompactIfCategory); @@ -631,6 +631,7 @@ public class LineWrappingTabPage extends FormatterTabPage { createNumberPref(lineWidthGroup, numColumns, FormatterMessages.LineWrappingTabPage_width_indent_option_max_line_width, DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, 0, 9999); createNumberPref(lineWidthGroup, numColumns, FormatterMessages.LineWrappingTabPage_width_indent_option_default_indent_wrapped, DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION, 0, 9999); createNumberPref(lineWidthGroup, numColumns, FormatterMessages.LineWrappingTabPage_width_indent_option_default_indent_array, DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION_FOR_INITIALIZER_LIST, 0, 9999); + createCheckboxPref(lineWidthGroup, numColumns, FormatterMessages.LineWrappingTabPage_do_not_join_lines, DefaultCodeFormatterConstants.FORMATTER_JOIN_WRAPPED_LINES, TRUE_FALSE); fCategoriesViewer= new TreeViewer(composite /*categoryGroup*/, SWT.MULTI | SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL ); fCategoriesViewer.setContentProvider(new ITreeContentProvider() {