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 d16b30e2ae1..8bc63cee05a 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 @@ -1097,8 +1097,10 @@ public class CodeFormatterVisitor extends CPPASTVisitor { scribe.alignFragment(alignment, i); exceptionSpecification[i].accept(this); } - // preferences.insert_space_before_closing_paren_in_exception_specification_throw - scribe.printNextToken(Token.tRPAREN, scribe.printComment()); + if (peekNextToken() == Token.tRPAREN) { + // preferences.insert_space_before_closing_paren_in_exception_specification_throw + scribe.printNextToken(Token.tRPAREN, scribe.printComment()); + } ok = true; } catch (AlignmentException e) { scribe.redoAlignment(e); @@ -1477,20 +1479,22 @@ public class CodeFormatterVisitor extends CPPASTVisitor { if (preferences.indent_body_declarations_compare_to_access_specifier) { scribe.unIndent(); } - startNode(declaration); - try { - scribe.startNewLine(); - visit((ICPPASTVisibilityLabel)declaration); - } finally { - endOfNode(declaration); + if (startNode(declaration)) { + try { + scribe.startNewLine(); + visit((ICPPASTVisibilityLabel)declaration); + } finally { + endOfNode(declaration); + } } } else { - startNode(declaration); - try { - scribe.startNewLine(); - formatDeclaration(declaration); - } finally { - endOfNode(declaration); + if (startNode(declaration)) { + try { + scribe.startNewLine(); + formatDeclaration(declaration); + } finally { + endOfNode(declaration); + } } if (preferences.indent_body_declarations_compare_to_access_specifier) { scribe.unIndent(); @@ -2400,7 +2404,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor { } finally { fInsideFor= false; } - scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_for); + if (peekNextToken() == Token.tRPAREN) { + scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_for); + } formatAction(line, node.getBody(), preferences.brace_position_for_block); return PROCESS_SKIP; @@ -2419,14 +2425,15 @@ public class CodeFormatterVisitor extends CPPASTVisitor { } else { condExpr.accept(this); } - scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_if); - + if (peekNextToken() == Token.tRPAREN) { + scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_if); + } final IASTStatement thenStatement = node.getThenClause(); final IASTStatement elseStatement = node.getElseClause(); boolean thenStatementIsBlock = false; if (thenStatement != null) { - if (thenStatement instanceof IASTCompoundStatement) { + if (thenStatement instanceof IASTCompoundStatement && !startsWithMacroExpansion(thenStatement)) { final IASTCompoundStatement block = (IASTCompoundStatement) thenStatement; thenStatementIsBlock = true; final List statements = Arrays.asList(block.getStatements()); @@ -2444,7 +2451,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor { } else { formatLeftCurlyBrace(line, preferences.brace_position_for_block); thenStatement.accept(this); - if (elseStatement != null && (preferences.insert_new_line_before_else_in_if_statement)) { + if (elseStatement != null && preferences.insert_new_line_before_else_in_if_statement) { scribe.startNewLine(); } } @@ -2692,7 +2699,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor { } wasACase = false; wasAStatement = true; - } else if (statement instanceof IASTCompoundStatement) { + } else if (statement instanceof IASTCompoundStatement && !startsWithMacroExpansion(statement)) { String bracePosition; if (wasACase) { if (preferences.indent_switchstatements_compare_to_cases) { @@ -2788,8 +2795,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor { conditionDecl.accept(this); } } - scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_while); - + if (peekNextToken() == Token.tRPAREN) { + scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_while); + } formatAction(line, node.getBody(), preferences.brace_position_for_block); return PROCESS_SKIP; } @@ -2906,10 +2914,10 @@ public class CodeFormatterVisitor extends CPPASTVisitor { } } else { - int nextTokenOffset= getNextTokenOffset(); - if (nextTokenOffset < nodeEndOffset && nextTokenOffset >= startOffset && nextTokenOffset <= endOffset) { - scribe.skipRange(startOffset, endOffset); - } +// int nextTokenOffset= getNextTokenOffset(); +// if (nextTokenOffset < nodeEndOffset && nextTokenOffset >= startOffset && nextTokenOffset <= endOffset) { +// scribe.skipRange(startOffset, endOffset); +// } break; } } @@ -2976,9 +2984,13 @@ public class CodeFormatterVisitor extends CPPASTVisitor { operand.accept(this); } if (peekNextToken() != Token.tRPAREN) { - scribe.skipToToken(Token.tRPAREN); + if (!enclosedInMacroExpansion(operand)) { + scribe.skipToToken(Token.tRPAREN); + } + } + if (peekNextToken() == Token.tRPAREN) { + scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_parenthesized_expression); } - scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_parenthesized_expression); } private void formatAction(final int line, final IASTStatement stmt, String brace_position) { @@ -3001,6 +3013,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor { stmt.accept(this); scribe.unIndent(); } else { + scribe.printTrailingComment(); scribe.startNewLine(); scribe.indent(); stmt.accept(this); @@ -3009,7 +3022,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor { } } - private boolean startsWithMacroExpansion(IASTNode node) { + private static boolean startsWithMacroExpansion(IASTNode node) { IASTNodeLocation[] locations= node.getNodeLocations(); if (locations.length == 0) { } else if (node instanceof IASTProblemHolder) { @@ -3021,6 +3034,11 @@ public class CodeFormatterVisitor extends CPPASTVisitor { return false; } + private static boolean enclosedInMacroExpansion(IASTNode node) { + IASTNodeLocation[] locations= node.getNodeLocations(); + return locations.length == 1 && locations[0] instanceof IASTMacroExpansionLocation; + } + private void formatBlock(IASTCompoundStatement block, String block_brace_position, boolean insertSpaceBeforeOpeningBrace, boolean indentStatements) { formatOpeningBrace(block_brace_position, insertSpaceBeforeOpeningBrace); IASTStatement[] statements = block.getStatements(); 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 8f25dcf3867..81885558482 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 @@ -872,4 +872,79 @@ public class CodeFormatterTest extends BaseUITestCase { public void testPreserveNecessarySpace_Bug250969() throws Exception { assertFormatterResult(); } + + //#define FOREVER1 for(;;) + //#define FOREVER2 while(1) + // + //int main(int argc, char **argv) { + // FOREVER1 { + // doSomething(); + // } + // FOREVER2 { + // doSomething(); + // } + //} + + //#define FOREVER1 for(;;) + //#define FOREVER2 while(1) + // + //int main(int argc, char **argv) { + // FOREVER1 { + // doSomething(); + // } + // FOREVER2 { + // doSomething(); + // } + //} + public void testFormatterProblemsWithForeverMacro() throws Exception { + assertFormatterResult(); + } + + //#define BLOCK { } + //#define DOIT1() { } + //#define DOIT2() do { } while(false) + //#define ALWAYS if(true) + //#define NEVER if(false) + //#define FOREVER for(;;) + // + //void foo() { + // int i=0; + // if (true) DOIT1(); + // if (true) DOIT2(); + // for (;;) BLOCK + // ALWAYS BLOCK + // NEVER FOREVER BLOCK + // switch(i) { + // case 0: BLOCK + // } + //} + + //#define BLOCK { } + //#define DOIT1() { } + //#define DOIT2() do { } while(false) + //#define ALWAYS if(true) + //#define NEVER if(false) + //#define FOREVER for(;;) + // + //void foo() { + // int i = 0; + // if (true) + // DOIT1(); + // if (true) + // DOIT2(); + // for (;;) + // BLOCK + // ALWAYS + // BLOCK + // NEVER + // FOREVER + // BLOCK + // switch (i) { + // case 0: + // BLOCK + // } + //} + public void testCompoundStatementAsMacro_Bug244928() throws Exception { + assertFormatterResult(); + } }