Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMarco Stornelli2019-03-22 18:18:04 +0000
committerMarco Stornelli2019-05-15 17:49:05 +0000
commit38a084ce6dac1515bb299fbea16f5b68e9829638 (patch)
tree9f9ebb8170f70e12e877008ebfb7f64db239aedd /core
parent8b2c6229aadf97d65d749ee6962047df512a5024 (diff)
downloadorg.eclipse.cdt-38a084ce6dac1515bb299fbea16f5b68e9829638.tar.gz
org.eclipse.cdt-38a084ce6dac1515bb299fbea16f5b68e9829638.tar.xz
org.eclipse.cdt-38a084ce6dac1515bb299fbea16f5b68e9829638.zip
Bug 500000 - Added proper formatting for lambda expressions
Change-Id: Ia530b00f3710b74d1749978c9c5d23a2d55646f0 Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterConstants.java35
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterOptions.java33
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java166
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/align/Alignment.java1
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java71
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.java6
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.properties7
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/LineWrappingTabPage.java12
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/WhiteSpaceOptions.java19
9 files changed, 347 insertions, 3 deletions
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 c9a7ab8ca99..fd0b2c45b14 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
@@ -338,6 +338,17 @@ public class DefaultCodeFormatterConstants {
*/
public static final String FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION = CCorePlugin.PLUGIN_ID
+ ".formatter.alignment_for_throws_clause_in_method_declaration"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option for alignment of lambda expression
+ * - option id: "org.eclipse.cdt.core.formatter.alignment_for_lambda_expression"
+ * - possible values: values returned by {@code createAlignmentValue(boolean, int, int)} call
+ * - default: createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+ * </pre>
+ * @see #createAlignmentValue(boolean, int, int)
+ */
+ public static final String FORMATTER_ALIGNMENT_FOR_LAMBDA_EXPRESSION = CCorePlugin.PLUGIN_ID
+ + ".formatter.alignment_for_lambda_expression"; //$NON-NLS-1$
// /**
// * <pre>
// * FORMATTER / Option to add blank lines after #include directive
@@ -1530,6 +1541,30 @@ public class DefaultCodeFormatterConstants {
+ ".formatter.insert_space_after_unary_operator"; //$NON-NLS-1$
/**
* <pre>
+ * FORMATTER / Option to insert a space after lambda return
+ * - option id: "org.eclipse.cdt.core.formatter.insert_space_after_lambda_return"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see CCorePlugin#INSERT
+ * @see CCorePlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_AFTER_LAMBDA_RETURN = CCorePlugin.PLUGIN_ID
+ + ".formatter.insert_space_after_lambda_return"; //$NON-NLS-1$
+ /**
+ * <pre>
+ * FORMATTER / Option to insert a space before lambda return
+ * - option id: "org.eclipse.cdt.core.formatter.insert_before_lambda_return"
+ * - possible values: { INSERT, DO_NOT_INSERT }
+ * - default: INSERT
+ * </pre>
+ * @see CCorePlugin#INSERT
+ * @see CCorePlugin#DO_NOT_INSERT
+ */
+ public static final String FORMATTER_INSERT_SPACE_BEFORE_LAMBDA_RETURN = CCorePlugin.PLUGIN_ID
+ + ".formatter.insert_space_before_lambda_return"; //$NON-NLS-1$
+ /**
+ * <pre>
* FORMATTER / Option to insert a space before an assignment operator
* - option id: "org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator"
* - possible values: { INSERT, DO_NOT_INSERT }
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterOptions.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterOptions.java
index 7596897a0e4..4a0cd58b204 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterOptions.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterOptions.java
@@ -79,6 +79,7 @@ public class DefaultCodeFormatterOptions {
public int alignment_for_parameters_in_method_declaration;
public int alignment_for_throws_clause_in_method_declaration;
public int alignment_for_constructor_initializer_list;
+ public int alignment_for_lambda_expression;
// public boolean align_type_members_on_columns;
@@ -204,6 +205,8 @@ public class DefaultCodeFormatterOptions {
public boolean insert_space_after_question_in_conditional;
public boolean insert_space_after_semicolon_in_for;
public boolean insert_space_after_unary_operator;
+ public boolean insert_space_after_lambda_return;
+ public boolean insert_space_before_lambda_return;
public boolean insert_space_before_assignment_operator;
public boolean insert_space_before_binary_operator;
public boolean insert_space_before_closing_angle_bracket_in_template_arguments;
@@ -359,6 +362,8 @@ public class DefaultCodeFormatterOptions {
getAlignment(this.alignment_for_constructor_initializer_list));
options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION,
getAlignment(this.alignment_for_throws_clause_in_method_declaration));
+ options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_LAMBDA_EXPRESSION,
+ getAlignment(this.alignment_for_lambda_expression));
// options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS, this.align_type_members_on_columns ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
// options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AFTER_IMPORTS, Integer.toString(this.blank_lines_after_includes));
// options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_BEFORE_FIELD, Integer.toString(this.blank_lines_before_field));
@@ -569,6 +574,10 @@ public class DefaultCodeFormatterOptions {
this.insert_space_after_semicolon_in_for ? CCorePlugin.INSERT : CCorePlugin.DO_NOT_INSERT);
options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_UNARY_OPERATOR,
this.insert_space_after_unary_operator ? CCorePlugin.INSERT : CCorePlugin.DO_NOT_INSERT);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_LAMBDA_RETURN,
+ this.insert_space_after_lambda_return ? CCorePlugin.INSERT : CCorePlugin.DO_NOT_INSERT);
+ options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_LAMBDA_RETURN,
+ this.insert_space_before_lambda_return ? CCorePlugin.INSERT : CCorePlugin.DO_NOT_INSERT);
options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR,
this.insert_space_before_assignment_operator ? CCorePlugin.INSERT : CCorePlugin.DO_NOT_INSERT);
options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_BINARY_OPERATOR,
@@ -982,6 +991,17 @@ public class DefaultCodeFormatterOptions {
this.alignment_for_throws_clause_in_method_declaration = Alignment.M_COMPACT_SPLIT;
}
}
+ final Object alignmentForLambdaExpressionOption = settings
+ .get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_LAMBDA_EXPRESSION);
+ if (alignmentForLambdaExpressionOption != null) {
+ try {
+ this.alignment_for_lambda_expression = Integer.parseInt((String) alignmentForLambdaExpressionOption);
+ } catch (NumberFormatException e) {
+ this.alignment_for_lambda_expression = Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_BY_ONE;
+ } catch (ClassCastException e) {
+ this.alignment_for_lambda_expression = Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_BY_ONE;
+ }
+ }
// final Object alignTypeMembersOnColumnsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS);
// if (alignTypeMembersOnColumnsOption != null) {
// this.align_type_members_on_columns = DefaultCodeFormatterConstants.TRUE.equals(alignTypeMembersOnColumnsOption);
@@ -1645,6 +1665,16 @@ public class DefaultCodeFormatterOptions {
if (insertSpaceAfterUnaryOperatorOption != null) {
this.insert_space_after_unary_operator = CCorePlugin.INSERT.equals(insertSpaceAfterUnaryOperatorOption);
}
+ final Object insertSpaceAfterLambdaReturnOption = settings
+ .get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_LAMBDA_RETURN);
+ if (insertSpaceAfterLambdaReturnOption != null) {
+ this.insert_space_after_lambda_return = CCorePlugin.INSERT.equals(insertSpaceAfterLambdaReturnOption);
+ }
+ final Object insertSpaceBeforeLambdaReturnOption = settings
+ .get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_LAMBDA_RETURN);
+ if (insertSpaceBeforeLambdaReturnOption != null) {
+ this.insert_space_before_lambda_return = CCorePlugin.INSERT.equals(insertSpaceBeforeLambdaReturnOption);
+ }
final Object insertSpaceBeforeAssignmentOperatorOption = settings
.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR);
if (insertSpaceBeforeAssignmentOperatorOption != null) {
@@ -2174,6 +2204,7 @@ public class DefaultCodeFormatterOptions {
this.alignment_for_parameters_in_method_declaration = Alignment.M_COMPACT_SPLIT;
// this.alignment_for_selector_in_method_invocation = Alignment.M_COMPACT_SPLIT;
this.alignment_for_throws_clause_in_method_declaration = Alignment.M_COMPACT_SPLIT;
+ this.alignment_for_lambda_expression = Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_BY_ONE;
// this.align_type_members_on_columns = false;
// this.blank_lines_after_includes = 1;
// this.blank_lines_before_field = 1;
@@ -2271,6 +2302,8 @@ public class DefaultCodeFormatterOptions {
this.insert_space_after_question_in_conditional = true;
this.insert_space_after_semicolon_in_for = true;
this.insert_space_after_unary_operator = false;
+ this.insert_space_after_lambda_return = true;
+ this.insert_space_before_lambda_return = true;
this.insert_space_before_assignment_operator = true;
this.insert_space_before_binary_operator = true;
this.insert_space_before_closing_angle_bracket_in_template_arguments = false;
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 2914d8bd5f6..bd5c069f87b 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
@@ -111,6 +111,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAttributeList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTClassVirtSpecifier;
@@ -132,6 +133,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression.CaptureDefault;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
@@ -206,9 +209,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
boolean fSpaceBeforeOpeningParen;
int fContinuationIndentation = -1;
int fTieBreakRule = Alignment.R_INNERMOST;
+ CaptureDefault captureDefault;
+ int rightToken;
+ int leftToken;
ListOptions(int mode) {
this.fMode = mode;
+ captureDefault = CaptureDefault.UNSPECIFIED;
+ rightToken = Token.tRPAREN;
+ leftToken = Token.tLPAREN;
}
}
@@ -304,7 +313,23 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
@Override
public void run() {
boolean needSpace = skipConstVolatileRestrict(true);
+ // Skip mutable or constexpr keywords for a lambda expression
+ needSpace = skipMutableConstexpr() || needSpace;
int token = peekNextToken();
+ // Lambda return value
+ if (token == Token.tARROW) {
+ scribe.printNextToken(token, preferences.insert_space_before_lambda_return);
+ if (preferences.insert_space_after_lambda_return)
+ scribe.space();
+ if (node.getParent() instanceof ICPPASTLambdaExpression) {
+ final IASTTypeId returnValue = ((ICPPASTFunctionDeclarator) node).getTrailingReturnType();
+ returnValue.accept(CodeFormatterVisitor.this);
+ scribe.printTrailingComment();
+ scribe.space();
+ }
+ token = peekNextToken();
+ needSpace = true;
+ }
// Ref-qualifier.
if (token == Token.tAMPER || token == Token.tAND) {
scribe.printNextToken(token, true);
@@ -360,10 +385,19 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
private final boolean spaceBeforeClosingParen;
private final Runnable continuationFormatter;
private final int parenPosition;
+ private final int token;
+
+ public ClosingParensesisTailFormatter(boolean spaceBeforeClosingParen, Runnable tailFormatter, int token) {
+ this.spaceBeforeClosingParen = spaceBeforeClosingParen;
+ this.continuationFormatter = tailFormatter;
+ this.token = token;
+ this.parenPosition = scribe.findToken(token);
+ }
public ClosingParensesisTailFormatter(boolean spaceBeforeClosingParen, Runnable tailFormatter) {
this.spaceBeforeClosingParen = spaceBeforeClosingParen;
this.continuationFormatter = tailFormatter;
+ this.token = Token.tRPAREN;
this.parenPosition = scribe.findToken(Token.tRPAREN);
}
@@ -374,7 +408,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
if (offset < parenPosition)
scribe.restartAtOffset(parenPosition);
scribe.undoSpace();
- scribe.printNextToken(Token.tRPAREN, spaceBeforeClosingParen);
+ scribe.printNextToken(token, spaceBeforeClosingParen);
}
if (continuationFormatter != null)
continuationFormatter.run();
@@ -955,6 +989,8 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
visit((ICPPASTSimpleTypeConstructorExpression) node);
} else if (node instanceof IASTProblemExpression) {
visit((IASTProblemExpression) node);
+ } else if (node instanceof ICPPASTLambdaExpression) {
+ visit((ICPPASTLambdaExpression) node);
} else {
formatRaw(node);
}
@@ -962,6 +998,83 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return PROCESS_SKIP;
}
+ public int visit(ICPPASTLambdaExpression node) {
+ final int line = scribe.line;
+
+ final ListOptions options = createListOptionsForLambdaCapturesParameters(node);
+ ICPPASTCapture[] captures = node.getCaptures();
+ formatList(Arrays.asList(captures), options, true, captures.length > 0 && captures[0].isPackExpansion(), null,
+ new Runnable() {
+ @Override
+ public void run() {
+ if (options.captureDefault == CaptureDefault.BY_COPY) {
+ scribe.printNextToken(Token.tASSIGN, options.fSpaceAfterOpeningParen);
+ } else if (options.captureDefault == CaptureDefault.BY_REFERENCE) {
+ scribe.printNextToken(Token.tAMPER, options.fSpaceAfterOpeningParen);
+ }
+
+ if (options.captureDefault != CaptureDefault.UNSPECIFIED && node.getCaptures().length > 0) {
+ scribe.printNextToken(Token.tCOMMA, options.fSpaceBeforeSeparator);
+ if (options.fSpaceAfterSeparator)
+ scribe.space();
+ }
+ }
+ });
+
+ // declarator
+ final ICPPASTFunctionDeclarator declarator = node.getDeclarator();
+ skipNonWhitespaceToNode(declarator);
+ boolean hasSpace = scribe.printComment();
+ boolean hasPointerOps = declarator.getPointerOperators().length > 0;
+ boolean needSpace = (hasPointerOps && hasSpace) || (!hasPointerOps && peekNextToken() == Token.tIDENTIFIER);
+ if (needSpace) {
+ scribe.space();
+ }
+ Runnable tailFormatter = null;
+ IASTStatement bodyStmt = node.getBody();
+ if (DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_method_declaration)
+ && bodyStmt instanceof IASTCompoundStatement && !startsWithMacroExpansion(bodyStmt)) {
+ tailFormatter = new TrailingTokenFormatter(Token.tLBRACE, nodeOffset(bodyStmt),
+ preferences.insert_space_before_opening_brace_in_method_declaration, false);
+ scribe.setTailFormatter(tailFormatter);
+ }
+ declarator.accept(this);
+
+ IASTAttributeSpecifier[] attributes = declarator.getAttributeSpecifiers();
+ if (attributes.length > 0) {
+ formatAttributes(declarator, true, false);
+ }
+
+ if (tailFormatter != null) {
+ scribe.runTailFormatter();
+ scribe.setTailFormatter(null);
+ }
+
+ Alignment alignment = scribe.createAlignment(Alignment.LAMBDA_EXPRESSION,
+ preferences.alignment_for_lambda_expression, Alignment.R_INNERMOST, 1, getCurrentPosition());
+ scribe.enterAlignment(alignment);
+
+ // Body
+ if (bodyStmt instanceof IASTCompoundStatement) {
+ if (enterNode(bodyStmt)) {
+ if (getCurrentPosition() <= nodeOffset(bodyStmt)) {
+ formatLeftCurlyBrace(line, preferences.brace_position_for_method_declaration);
+ }
+ formatBlock((IASTCompoundStatement) bodyStmt, preferences.brace_position_for_method_declaration,
+ preferences.insert_space_before_opening_brace_in_method_declaration,
+ preferences.indent_statements_compare_to_body);
+ exitNode(bodyStmt);
+ }
+ } else if (bodyStmt != null) {
+ bodyStmt.accept(this);
+ }
+ scribe.printTrailingComment();
+
+ // go back to the previous alignment again:
+ scribe.exitAlignment(alignment, true);
+ return PROCESS_SKIP;
+ }
+
/*
* @see ASTVisitor#visit(IASTStatement)
*/
@@ -1556,6 +1669,17 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return skipped;
}
+ private boolean skipMutableConstexpr() {
+ boolean skipped = false;
+ int token = peekNextToken();
+ while (token == Token.t_mutable || token == Token.t_constexpr) {
+ scribe.printNextToken(token, true);
+ token = peekNextToken();
+ skipped = true;
+ }
+ return skipped;
+ }
+
private int visit(IASTStandardFunctionDeclarator node) {
final List<IASTParameterDeclaration> parameters = Arrays.asList(node.getParameters());
final ListOptions options = createListOptionsForFunctionDeclarationParameters();
@@ -1575,6 +1699,21 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return options;
}
+ private ListOptions createListOptionsForLambdaCapturesParameters(ICPPASTLambdaExpression expr) {
+ final ListOptions options = new ListOptions(preferences.alignment_for_parameters_in_method_declaration);
+ options.fSpaceBeforeOpeningParen = preferences.insert_space_before_opening_paren_in_method_declaration;
+ options.fSpaceAfterOpeningParen = preferences.insert_space_after_opening_paren_in_method_declaration;
+ options.fSpaceBeforeClosingParen = preferences.insert_space_before_closing_paren_in_method_declaration;
+ options.fSpaceBetweenEmptyParen = preferences.insert_space_between_empty_parens_in_method_declaration;
+ options.fSpaceBeforeSeparator = preferences.insert_space_before_comma_in_method_declaration_parameters;
+ options.fSpaceAfterSeparator = preferences.insert_space_after_comma_in_method_declaration_parameters;
+ options.fTieBreakRule = Alignment.R_OUTERMOST;
+ options.rightToken = Token.tRBRACKET;
+ options.leftToken = Token.tLBRACKET;
+ options.captureDefault = expr.getCaptureDefault();
+ return options;
+ }
+
/**
* Returns the position of the last character of a node, or -1 if that character is part of
* a macro expansion.
@@ -2257,16 +2396,37 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
*/
private void formatList(List<?> elements, ListOptions options, boolean encloseInParen, boolean addEllipsis,
Runnable tailFormatter) {
+ formatList(elements, options, encloseInParen, addEllipsis, tailFormatter, null);
+ }
+
+ /**
+ * Format a given list of elements according alignment options.
+ *
+ * @param elements the elements to format, which can be either {@link IASTNode}s or
+ * {@link TokenRange}s.
+ * @param options formatting options
+ * @param encloseInParen indicates whether the list should be enclosed in parentheses
+ * @param addEllipsis indicates whether ellipsis should be added after the last element
+ * @param tailFormatter formatter for the trailing text that should be kept together with
+ * the last element of the list.
+ * @param prefix A custom list prefix to format the first element
+ */
+ private void formatList(List<?> elements, ListOptions options, boolean encloseInParen, boolean addEllipsis,
+ Runnable tailFormatter, Runnable prefix) {
if (encloseInParen)
- scribe.printNextToken(Token.tLPAREN, options.fSpaceBeforeOpeningParen);
+ scribe.printNextToken(options.leftToken, options.fSpaceBeforeOpeningParen);
final int elementsLength = elements.size();
if (encloseInParen) {
boolean spaceBeforeClosingParen = elements.isEmpty() && !addEllipsis ? options.fSpaceBetweenEmptyParen
: options.fSpaceBeforeClosingParen;
- tailFormatter = new ClosingParensesisTailFormatter(spaceBeforeClosingParen, tailFormatter);
+ tailFormatter = new ClosingParensesisTailFormatter(spaceBeforeClosingParen, tailFormatter,
+ options.rightToken);
}
+ if (prefix != null)
+ prefix.run();
+
if (!elements.isEmpty() || addEllipsis) {
if (options.fSpaceAfterOpeningParen) {
scribe.space();
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/align/Alignment.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/align/Alignment.java
index 4ce3410da34..5e4c8f63a4b 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/align/Alignment.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/align/Alignment.java
@@ -32,6 +32,7 @@ public class Alignment {
public static final String CONDITIONAL_EXPRESSION = "conditionalExpression"; //$NON-NLS-1$
public static final String CONDITIONAL_EXPRESSION_CHAIN = "conditionalExpressionChain"; //$NON-NLS-1$
public static final String DECLARATION_INITIALIZER = "declarationInitializer"; //$NON-NLS-1$
+ public static final String LAMBDA_EXPRESSION = "lambdaExpression"; //$NON-NLS-1$
public static final String DESIGNATED_INITIALIZER = "designatedInitializer"; //$NON-NLS-1$
public static final String EXCEPTION_SPECIFICATION = "exceptionSpecification"; //$NON-NLS-1$
public static final String FIELD_REFERENCE = "fieldReference"; //$NON-NLS-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 e612154189f..fa128f2d680 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
@@ -4152,4 +4152,75 @@ public class CodeFormatterTest extends BaseUITestCase {
public void testNamespacesWithInactiveSections_Bug405049() throws Exception {
assertFormatterResult();
}
+
+ //int main() {
+ // auto f = []() {
+ //
+ // for(int c1 = 0; c1 < 3; c1 ++) {
+ // for(int i = 0; i < 5; i ++) {
+ // for(int c2 = 0; c2 < 3; c2 ++) {
+ // // keep me here
+ // }
+ // }
+ // }
+ // };
+ // f();
+ // return 0;
+ //}
+
+ //int main() {
+ // auto f = []() {
+ //
+ // for (int c1 = 0; c1 < 3; c1++) {
+ // for (int i = 0; i < 5; i++) {
+ // for (int c2 = 0; c2 < 3; c2++) {
+ // // keep me here
+ // }
+ // }
+ // }
+ // };
+ // f();
+ // return 0;
+ //}
+ public void testAlignmentOfLambda1_Bug500000() throws Exception {
+ assertFormatterResult();
+ }
+
+ //int main() {
+ // int n = 0;
+ // auto f = [=]()mutable{n= 20;};
+ // f();
+ // return 0;
+ //}
+
+ //int main() {
+ // int n = 0;
+ // auto f = [=]() mutable {
+ // n = 20;
+ // };
+ // f();
+ // return 0;
+ //}
+ public void testAlignmentOfLambda2_Bug500000() throws Exception {
+ assertFormatterResult();
+ }
+
+ //int main() {
+ // int n = 0;
+ // auto f = [=]()throw(int)[[deprecated]]{throw 1;};
+ // f();
+ // return 0;
+ //}
+
+ //int main() {
+ // int n = 0;
+ // auto f = [=]() throw (int) [[deprecated]] {
+ // throw 1;
+ // };
+ // f();
+ // return 0;
+ //}
+ public void testAlignmentOfLambda3_Bug500000() throws Exception {
+ 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 7332e953e88..fecf76a9955 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
@@ -43,6 +43,9 @@ final class FormatterMessages extends NLS {
public static String WhiteSpaceTabPage_operators_after_prefix_operators;
public static String WhiteSpaceTabPage_operators_before_postfix_operators;
public static String WhiteSpaceTabPage_operators_after_postfix_operators;
+ public static String WhiteSpaceTabPage_lambda_expressions;
+ public static String WhiteSpaceTabPage_lambda_before_return;
+ public static String WhiteSpaceTabPage_lambda_after_return;
public static String WhiteSpaceTabPage_classes;
public static String WhiteSpaceTabPage_classes_before_opening_brace_of_a_class;
public static String WhiteSpaceTabPage_classes_before_colon_of_base_clause;
@@ -129,6 +132,7 @@ final class FormatterMessages extends NLS {
public static String WhiteSpaceOptions_unary_operator;
public static String WhiteSpaceOptions_prefix_operator;
public static String WhiteSpaceOptions_postfix_operator;
+ public static String WhiteSpaceOptions_lambda_arrow_operator;
public static String WhiteSpaceOptions_opening_paren;
public static String WhiteSpaceOptions_pointer;
public static String WhiteSpaceOptions_catch;
@@ -209,6 +213,7 @@ final class FormatterMessages extends NLS {
public static String LineWrappingTabPage_parameters;
public static String LineWrappingTabPage_arguments;
public static String LineWrappingTabPage_throws_clause;
+ public static String LineWrappingTabPage_lambda_expression;
public static String LineWrappingTabPage_constructor_initializer_list;
public static String LineWrappingTabPage_enum_decls;
public static String LineWrappingTabPage_enumerator_list;
@@ -232,6 +237,7 @@ final class FormatterMessages extends NLS {
public static String LineWrappingTabPage_parameters_lowercase;
public static String LineWrappingTabPage_arguments_lowercase;
public static String LineWrappingTabPage_throws_clause_lowercase;
+ public static String LineWrappingTabPage_lambda_expression_lowercase;
public static String LineWrappingTabPage_constructor_initializer_list_lowercase;
public static String LineWrappingTabPage_enum_decls_lowercase;
public static String LineWrappingTabPage_enumerator_list_lowercase;
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 4cb176db07c..ffcf7dec9e5 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
@@ -30,6 +30,10 @@ WhiteSpaceTabPage_operators_after_prefix_operators=after prefix operators
WhiteSpaceTabPage_operators_before_postfix_operators=before postfix operators
WhiteSpaceTabPage_operators_after_postfix_operators=after postfix operators
+WhiteSpaceTabPage_lambda_expressions=Lambda expressions
+WhiteSpaceTabPage_lambda_before_return=before return arrow
+WhiteSpaceTabPage_lambda_after_return=after return arrow
+
WhiteSpaceTabPage_classes=Types
WhiteSpaceTabPage_classes_before_opening_brace_of_a_class=before opening brace of a class
WhiteSpaceTabPage_classes_before_colon_of_base_clause=before colon of base clause
@@ -140,6 +144,7 @@ WhiteSpaceOptions_binary_operator=Binary operator
WhiteSpaceOptions_unary_operator=Unary operator
WhiteSpaceOptions_prefix_operator=Prefix operator
WhiteSpaceOptions_postfix_operator=Postfix operator
+WhiteSpaceOptions_lambda_arrow_operator=Lambda arrow operator
WhiteSpaceOptions_pointer=Pointer
WhiteSpaceOptions_before_pointer=Before pointer
@@ -240,6 +245,7 @@ LineWrappingTabPage_base_clause=Base-clause
LineWrappingTabPage_parameters=Parameters
LineWrappingTabPage_arguments=Arguments
LineWrappingTabPage_throws_clause=Exception specification
+LineWrappingTabPage_lambda_expression=Lambda expression
LineWrappingTabPage_constructor_initializer_list=Constructor initializer list
#LineWrappingTabPage_object_allocation=Object allocation arguments
LineWrappingTabPage_enum_decls='enum' declaration
@@ -265,6 +271,7 @@ LineWrappingTabPage_base_clause_lowercase=base-clause
LineWrappingTabPage_parameters_lowercase=parameters
LineWrappingTabPage_arguments_lowercase=arguments
LineWrappingTabPage_throws_clause_lowercase=exception specification
+LineWrappingTabPage_lambda_expression_lowercase=lambda expression
LineWrappingTabPage_constructor_initializer_list_lowercase=constructor initializer list
#LineWrappingTabPage_object_allocation_lowercase=object allocation arguments
LineWrappingTabPage_enum_decls_lowercase='enum' declaration
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 d01c56d97a6..9673756f15a 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
@@ -412,6 +412,17 @@ public class LineWrappingTabPage extends FormatterTabPage {
FormatterMessages.LineWrappingTabPage_throws_clause,
FormatterMessages.LineWrappingTabPage_throws_clause_lowercase);
+ private final Category fLambdaCategory = new Category(
+ DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_LAMBDA_EXPRESSION, "int foo() {" + //$NON-NLS-1$
+ " auto f = [](){for(int c1 = 0; c1 < 3; c1 ++) {\n" + //$NON-NLS-1$
+ " for(int i = 0; i < 5; i ++) {\n" + //$NON-NLS-1$
+ " for(int c2 = 0; c2 < 3; c2 ++) {\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ " }\n" + //$NON-NLS-1$
+ " }};}", //$NON-NLS-1$
+ FormatterMessages.LineWrappingTabPage_lambda_expression,
+ FormatterMessages.LineWrappingTabPage_lambda_expression_lowercase);
+
private final Category fConstructorInitializerListCategory = new Category(
DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONSTRUCTOR_INITIALIZER_LIST, "class Point {" + //$NON-NLS-1$
"public:" + //$NON-NLS-1$
@@ -638,6 +649,7 @@ public class LineWrappingTabPage extends FormatterTabPage {
methodDeclarations.children.add(fMethodDeclarationsParametersCategory);
methodDeclarations.children.add(fMethodThrowsClauseCategory);
methodDeclarations.children.add(fConstructorInitializerListCategory);
+ methodDeclarations.children.add(fLambdaCategory);
final Category enumDeclarations = new Category(FormatterMessages.LineWrappingTabPage_enum_decls,
FormatterMessages.LineWrappingTabPage_enum_decls_lowercase);
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/WhiteSpaceOptions.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/WhiteSpaceOptions.java
index 109b053864b..7336a30e56c 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/WhiteSpaceOptions.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/WhiteSpaceOptions.java
@@ -180,6 +180,9 @@ public final class WhiteSpaceOptions {
"void bar(int x, int y) throw() {}" + //$NON-NLS-1$
"void* baz(int* x, int& y) {return 0;}"); //$NON-NLS-1$
+ private final PreviewSnippet LAMBDA_PREVIEW = new PreviewSnippet(CodeFormatter.K_CLASS_BODY_DECLARATIONS,
+ "void foo() { auto f = []()->int{return 0;};}"); //$NON-NLS-1$
+
private final PreviewSnippet INITIALIZER_LIST_PREVIEW = new PreviewSnippet(CodeFormatter.K_STATEMENTS,
"int array[]= {1, 2, 3};"); //$NON-NLS-1$
@@ -470,6 +473,7 @@ public final class WhiteSpaceOptions {
createNamespaceTree(workingValues, declarations);
createLinkageTree(workingValues, declarations);
// createConstructorTree(workingValues, declarations);
+ createLambdaDeclTree(workingValues, declarations);
createMethodDeclTree(workingValues, declarations);
createExceptionSpecificationTree(workingValues, declarations);
createLabelTree(workingValues, declarations);
@@ -591,6 +595,8 @@ public final class WhiteSpaceOptions {
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_PREFIX_OPERATOR, OPERATOR_PREVIEW);
createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_postfix_operator,
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_POSTFIX_OPERATOR, OPERATOR_PREVIEW);
+ createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_lambda_arrow_operator,
+ DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_LAMBDA_RETURN, LAMBDA_PREVIEW);
}
private void createBeforeClosingBracketTree(Map<String, String> workingValues, final InnerNode parent) {
@@ -822,6 +828,8 @@ public final class WhiteSpaceOptions {
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_PREFIX_OPERATOR, OPERATOR_PREVIEW);
createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_postfix_operator,
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_POSTFIX_OPERATOR, OPERATOR_PREVIEW);
+ createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_lambda_arrow_operator,
+ DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_LAMBDA_RETURN, LAMBDA_PREVIEW);
}
private void createAfterOpenBracketTree(Map<String, String> workingValues, final InnerNode parent) {
@@ -971,6 +979,17 @@ public final class WhiteSpaceOptions {
return root;
}
+ private InnerNode createLambdaDeclTree(Map<String, String> workingValues, InnerNode parent) {
+ final InnerNode root = new InnerNode(parent, workingValues,
+ FormatterMessages.WhiteSpaceTabPage_lambda_expressions);
+
+ createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_lambda_before_return,
+ DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_LAMBDA_RETURN, LAMBDA_PREVIEW);
+ createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_lambda_after_return,
+ DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_LAMBDA_RETURN, LAMBDA_PREVIEW);
+ return root;
+ }
+
private InnerNode createMethodDeclTree(Map<String, String> workingValues, InnerNode parent) {
final InnerNode root = new InnerNode(parent, workingValues, FormatterMessages.WhiteSpaceTabPage_functions);

Back to the top