diff options
author | Marco Stornelli | 2019-03-22 18:18:04 +0000 |
---|---|---|
committer | Marco Stornelli | 2019-05-15 17:49:05 +0000 |
commit | 38a084ce6dac1515bb299fbea16f5b68e9829638 (patch) | |
tree | 9f9ebb8170f70e12e877008ebfb7f64db239aedd /core | |
parent | 8b2c6229aadf97d65d749ee6962047df512a5024 (diff) | |
download | org.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')
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); |