1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-28 19:35:36 +02:00

Formatting of conditional expressions.

This commit is contained in:
Sergey Prigogin 2011-03-31 02:15:52 +00:00
parent be1a78cd90
commit ae4651ac31
4 changed files with 113 additions and 64 deletions

View file

@ -205,6 +205,12 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
this.spaceAfterToken = spaceAfterToken; this.spaceAfterToken = spaceAfterToken;
} }
TrailingTokenFormatter(int tokenType, IASTNode containingNode,
boolean spaceBeforeToken, boolean spaceAfterToken) {
this(tokenType, findTokenWithinNode(tokenType, containingNode),
spaceBeforeToken, spaceAfterToken);
}
TrailingTokenFormatter(int tokenType, boolean spaceBeforeToken, boolean spaceAfterToken) { TrailingTokenFormatter(int tokenType, boolean spaceBeforeToken, boolean spaceAfterToken) {
this(tokenType, scribe.findToken(tokenType), spaceBeforeToken, spaceAfterToken); this(tokenType, scribe.findToken(tokenType), spaceBeforeToken, spaceAfterToken);
} }
@ -2032,7 +2038,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
if (options.fInsertNewLineBeforeListIfNecessary && if (options.fInsertNewLineBeforeListIfNecessary &&
(options.fMode & Alignment.M_INDENT_ON_COLUMN) != 0) { (options.fMode & Alignment.M_INDENT_ON_COLUMN) != 0) {
wrapperAlignment = scribe.createAlignment( wrapperAlignment = scribe.createAlignment(
Alignment.LIST_WRAPPER, Alignment.COLUMN_WRAPPER,
Alignment.M_COMPACT_FIRST_BREAK_SPLIT, Alignment.M_COMPACT_FIRST_BREAK_SPLIT,
Alignment.R_INNERMOST, Alignment.R_INNERMOST,
1, 1,
@ -2175,61 +2181,70 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
private int visit(IASTConditionalExpression node) { private int visit(IASTConditionalExpression node) {
Runnable tailFormatter = scribe.takeTailFormatter(); Runnable tailFormatter = scribe.takeTailFormatter();
try {
node.getLogicalConditionExpression().accept(this);
} finally {
scribe.setTailFormatter(tailFormatter);
}
scribe.printTrailingComment();
if (preferences.insert_space_before_question_in_conditional) {
scribe.space();
}
Alignment alignment = scribe.createAlignment(
Alignment.CONDITIONAL_EXPRESSION,
preferences.alignment_for_conditional_expression,
2,
scribe.scanner.getCurrentPosition());
scribe.enterAlignment(alignment); scribe.setTailFormatter(new TrailingTokenFormatter(Token.tQUESTION, node,
boolean ok = false; preferences.insert_space_before_question_in_conditional,
do { preferences.insert_space_after_question_in_conditional));
try { node.getLogicalConditionExpression().accept(this);
scribe.alignFragment(alignment, 0); scribe.runTailFormatter();
final IASTExpression positiveExpression = node.getPositiveResultExpression();
final IASTExpression negativeExpression = node.getNegativeResultExpression();
final IASTExpression nextExpression = positiveExpression != null ?
positiveExpression : negativeExpression;
// In case of macros we may have already passed the question mark position.
if (scribe.scanner.getCurrentPosition() < nextExpression.getFileLocation().getNodeOffset()) {
scribe.printNextToken(Token.tQUESTION, false);
if (preferences.insert_space_after_question_in_conditional) {
scribe.space();
}
}
if (positiveExpression != null) { // gcc-extension allows to omit the positive expression. Alignment wrapperAlignment = scribe.createAlignment(
positiveExpression.accept(this); Alignment.CONDITIONAL_EXPRESSION_WRAPPER,
} Alignment.M_COMPACT_FIRST_BREAK_SPLIT,
scribe.printTrailingComment(); Alignment.R_OUTERMOST,
scribe.alignFragment(alignment, 1); 1,
scribe.scanner.getCurrentPosition(),
preferences.continuation_indentation,
false);
scribe.enterAlignment(wrapperAlignment);
boolean success = false;
do {
scribe.alignFragment(wrapperAlignment, 0);
// In case of macros we may have already passed the colon position. try {
if (scribe.scanner.getCurrentPosition() < negativeExpression.getFileLocation().getNodeOffset()) { Alignment alignment = scribe.createAlignment(
scribe.printNextToken(Token.tCOLON, preferences.insert_space_before_colon_in_conditional); Alignment.CONDITIONAL_EXPRESSION,
if (preferences.insert_space_after_colon_in_conditional) { preferences.alignment_for_conditional_expression,
scribe.space(); Alignment.R_OUTERMOST,
} 2,
} scribe.scanner.getCurrentPosition(),
0,
false);
negativeExpression.accept(this); scribe.enterAlignment(alignment);
boolean ok = false;
do {
try {
scribe.alignFragment(alignment, 0);
final IASTExpression positiveExpression = node.getPositiveResultExpression();
final IASTExpression negativeExpression = node.getNegativeResultExpression();
scribe.setTailFormatter(new TrailingTokenFormatter(Token.tCOLON, node,
preferences.insert_space_before_colon_in_conditional,
preferences.insert_space_after_colon_in_conditional));
// A gcc extension allows the positive expression to be omitted.
if (positiveExpression != null) {
positiveExpression.accept(this);
}
scribe.runTailFormatter();
ok = true; scribe.alignFragment(alignment, 1);
} catch (AlignmentException e) { scribe.setTailFormatter(tailFormatter);
scribe.redoAlignment(e); negativeExpression.accept(this);
} scribe.runTailFormatter();
} while (!ok); ok = true;
scribe.exitAlignment(alignment, true); } catch (AlignmentException e) {
return PROCESS_SKIP; scribe.redoAlignment(e);
}
} while (!ok);
scribe.exitAlignment(alignment, true);
success = true;
} catch (AlignmentException e) {
scribe.redoAlignment(e);
}
} while (!success);
scribe.exitAlignment(wrapperAlignment, true);
return PROCESS_SKIP;
} }
private int visit(IASTFunctionCallExpression node) { private int visit(IASTFunctionCallExpression node) {
@ -2360,31 +2375,32 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
private int visit(IASTEqualsInitializer node) { private int visit(IASTEqualsInitializer node) {
if (node.getPropertyInParent() == IASTInitializerList.NESTED_INITIALIZER) { if (node.getPropertyInParent() == IASTInitializerList.NESTED_INITIALIZER) {
assert false; assert false;
// nested initializer expression, no need to apply extra alignment // Nested initializer expression, no need to apply extra alignment
// node.getExpression().accept(this); // node.getExpression().accept(this);
} else { } else {
// declaration initializer // Declaration initializer
Alignment expressionAlignment= scribe.createAlignment( Alignment alignment= scribe.createAlignment(
Alignment.DECLARATION_INITIALIZER, Alignment.DECLARATION_INITIALIZER,
preferences.alignment_for_assignment, preferences.alignment_for_assignment,
Alignment.R_INNERMOST, Alignment.R_INNERMOST,
1, 1,
scribe.scanner.getCurrentPosition()); scribe.scanner.getCurrentPosition());
scribe.enterAlignment(expressionAlignment); Runnable tailFormatter = scribe.getTailFormatter();
scribe.enterAlignment(alignment);
scribe.setTailFormatter(tailFormatter); // Inherit tail formatter from the enclosing alignment
boolean ok = false; boolean ok = false;
do { do {
try { try {
scribe.alignFragment(expressionAlignment, 0); scribe.alignFragment(alignment, 0);
node.getInitializerClause().accept(this); node.getInitializerClause().accept(this);
ok = true; ok = true;
} catch (AlignmentException e) { } catch (AlignmentException e) {
scribe.redoAlignment(e); scribe.redoAlignment(e);
} }
} while (!ok); } while (!ok);
scribe.exitAlignment(expressionAlignment, true); scribe.exitAlignment(alignment, true);
} }
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -2704,7 +2720,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
Alignment wrapperAlignment = null; Alignment wrapperAlignment = null;
if ((preferences.alignment_for_overloaded_left_shift_chain & Alignment.M_INDENT_ON_COLUMN) != 0) { if ((preferences.alignment_for_overloaded_left_shift_chain & Alignment.M_INDENT_ON_COLUMN) != 0) {
wrapperAlignment = scribe.createAlignment( wrapperAlignment = scribe.createAlignment(
Alignment.LIST_WRAPPER, Alignment.COLUMN_WRAPPER,
Alignment.M_COMPACT_FIRST_BREAK_SPLIT, Alignment.M_COMPACT_FIRST_BREAK_SPLIT,
Alignment.R_INNERMOST, Alignment.R_INNERMOST,
1, 1,
@ -2937,10 +2953,12 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
scribe.printNextToken(Token.t_new); scribe.printNextToken(Token.t_new);
scribe.space(); scribe.space();
// placement // Placement
final IASTInitializerClause[] newPlacement= node.getPlacementArguments(); final IASTInitializerClause[] newPlacement= node.getPlacementArguments();
if (newPlacement != null) { if (newPlacement != null) {
Runnable tailFormatter = scribe.takeTailFormatter();
formatFunctionCallArguments(newPlacement); formatFunctionCallArguments(newPlacement);
scribe.setTailFormatter(tailFormatter);
} }
// type-id // type-id
@ -4175,4 +4193,10 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return node instanceof ICPPASTFunctionDefinition && return node instanceof ICPPASTFunctionDefinition &&
((ICPPASTFunctionDefinition) node).getMemberInitializers().length > 0; ((ICPPASTFunctionDefinition) node).getMemberInitializers().length > 0;
} }
private int findTokenWithinNode(int tokenType, IASTNode node) {
IASTFileLocation location = node.getFileLocation();
int endOffset = location.getNodeOffset() + location.getNodeLength();
return scribe.findToken(tokenType, endOffset);
}
} }

View file

@ -23,7 +23,9 @@ public class Alignment {
// Alignment names. // Alignment names.
public static final String ASSIGNMENT_EXPRESSION = "assignmentExpression"; //$NON-NLS-1$ public static final String ASSIGNMENT_EXPRESSION = "assignmentExpression"; //$NON-NLS-1$
public static final String BINARY_EXPRESSION = "binaryExpression"; //$NON-NLS-1$ public static final String BINARY_EXPRESSION = "binaryExpression"; //$NON-NLS-1$
public static final String COLUMN_WRAPPER = "columnWrapper"; //$NON-NLS-1$
public static final String COMPACT_IF = "compactIf"; //$NON-NLS-1$ public static final String COMPACT_IF = "compactIf"; //$NON-NLS-1$
public static final String CONDITIONAL_EXPRESSION_WRAPPER = "conditionalExpressionWrapper"; //$NON-NLS-1$
public static final String CONDITIONAL_EXPRESSION = "conditionalExpression"; //$NON-NLS-1$ public static final String CONDITIONAL_EXPRESSION = "conditionalExpression"; //$NON-NLS-1$
public static final String DECLARATION_INITIALIZER = "declarationInitializer"; //$NON-NLS-1$ public static final String DECLARATION_INITIALIZER = "declarationInitializer"; //$NON-NLS-1$
public static final String DESIGNATED_INITIALIZER = "designatedInitializer"; //$NON-NLS-1$ public static final String DESIGNATED_INITIALIZER = "designatedInitializer"; //$NON-NLS-1$
@ -31,7 +33,6 @@ public class Alignment {
public static final String FIELD_REFERENCE = "fieldReference"; //$NON-NLS-1$ public static final String FIELD_REFERENCE = "fieldReference"; //$NON-NLS-1$
public static final String FOR = "for"; //$NON-NLS-1$ public static final String FOR = "for"; //$NON-NLS-1$
public static final String LIST_ELEMENTS_PREFIX = "listElements_"; //$NON-NLS-1$ public static final String LIST_ELEMENTS_PREFIX = "listElements_"; //$NON-NLS-1$
public static final String LIST_WRAPPER = "listWrapper"; //$NON-NLS-1$
public static final String MACRO_ARGUMENTS = "macroArguments"; //$NON-NLS-1$ public static final String MACRO_ARGUMENTS = "macroArguments"; //$NON-NLS-1$
public static final String OVERLOADED_LEFT_SHIFT_CHAIN = "overloadedLeftShiftChain"; //$NON-NLS-1$ public static final String OVERLOADED_LEFT_SHIFT_CHAIN = "overloadedLeftShiftChain"; //$NON-NLS-1$
public static final String TRAILING_TEXT = "trailingText"; //$NON-NLS-1$ public static final String TRAILING_TEXT = "trailingText"; //$NON-NLS-1$

View file

@ -47,8 +47,8 @@ int foo(int bar) const {
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 1000, int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 1000,
2000, 3000, 4000, 5000 }; 2000, 3000, 4000, 5000 };
int compare(int argument, int otherArg) { int compare(int argument, int otherArg) {
return argument + otherArg > argument * otherArg + 1000000 ? 100000 + 50000 return argument + otherArg > argument * otherArg + 1000000 ?
: 200000 - 30000; 100000 + 50000 : 200000 - 30000;
} }
class Other { class Other {
static void bar(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, static void bar(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6,

View file

@ -2009,6 +2009,30 @@ public class CodeFormatterTest extends BaseUITestCase {
assertFormatterResult(); assertFormatterResult();
} }
//void test() {
//int variable1 = 1000000 < 2000000 ? 3000000 + 40000000 : 8000000 + 90000000;
//int variable2 = 1000000 < 2000000 ? 3000000 + 40000000 : 8000000 + 900000000;
//int variable3 = 1000000 < 2000000 ? 3000000 + 4000000 + 5000000 + 6000000 + 7000000 : 8000000 + 9000000;
//int variable4 = 1000000 < 2000000 ? 3000000 + 4000000 + 5000000 + 6000000 + 7000000 : 8000000 + 90000000;
//}
//void test() {
// int variable1 = 1000000 < 2000000 ? 3000000 + 40000000 : 8000000 + 90000000;
// int variable2 = 1000000 < 2000000 ?
// 3000000 + 40000000 : 8000000 + 900000000;
// int variable3 = 1000000 < 2000000 ?
// 3000000 + 4000000 + 5000000 + 6000000 + 7000000 : 8000000 + 9000000;
// int variable4 = 1000000 < 2000000 ?
// 3000000 + 4000000 + 5000000 + 6000000 + 7000000 :
// 8000000 + 90000000;
//}
public void testConditionalExpression() throws Exception {
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE);
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION,
Integer.toString(Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_ON_COLUMN));
assertFormatterResult();
}
//// Breaking at '<=' is preferred to breaking at '+'. //// Breaking at '<=' is preferred to breaking at '+'.
//bool x = 1000000 + 2000000 + 3000000 + 4000000 <= 5000000 + 6000000 + 7000000 + 8000000; //bool x = 1000000 + 2000000 + 3000000 + 4000000 <= 5000000 + 6000000 + 7000000 + 8000000;