mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 357423 - Code formatter gets confused by a macro. Macro involving an
'if' statement.
This commit is contained in:
parent
1c153dcece
commit
a090d9bd2c
2 changed files with 239 additions and 120 deletions
|
@ -114,6 +114,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
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.ICPPASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
|
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.ICPPASTLinkageSpecification;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
||||||
|
@ -157,7 +158,7 @@ import org.eclipse.text.edits.TextEdit;
|
||||||
* Some heuristic is applied in case of syntax errors or other problems
|
* Some heuristic is applied in case of syntax errors or other problems
|
||||||
* to skip those areas, but because of incomplete location information
|
* to skip those areas, but because of incomplete location information
|
||||||
* the formatting may fail. The reason of the failure is logged.
|
* the formatting may fail. The reason of the failure is logged.
|
||||||
*
|
*
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, ICASTVisitor {
|
public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, ICASTVisitor {
|
||||||
|
@ -827,7 +828,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given declarator is the first in a list of declarators (if any).
|
* Determine whether the given declarator is the first in a list of declarators (if any).
|
||||||
*
|
*
|
||||||
* @param node the declarator node
|
* @param node the declarator node
|
||||||
* @return <code>true</code> if this node is the first in a list
|
* @return <code>true</code> if this node is the first in a list
|
||||||
*/
|
*/
|
||||||
|
@ -1527,7 +1528,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
/**
|
/**
|
||||||
* Returns the position of the last character of a node, or -1 if that character is part of
|
* Returns the position of the last character of a node, or -1 if that character is part of
|
||||||
* a macro expansion.
|
* a macro expansion.
|
||||||
*
|
*
|
||||||
* @param node an AST node
|
* @param node an AST node
|
||||||
* @return the position of the last character of a node, or -1 if that character is part of
|
* @return the position of the last character of a node, or -1 if that character is part of
|
||||||
* a macro expansion.
|
* a macro expansion.
|
||||||
|
@ -1658,12 +1659,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
Runnable tailFormatter = fExpectSemicolonAfterDeclaration ?
|
Runnable tailFormatter = fExpectSemicolonAfterDeclaration ?
|
||||||
new TrailingSemicolonFormatter(node) : null;
|
new TrailingSemicolonFormatter(node) : null;
|
||||||
if (declarators.size() == 1) {
|
if (declarators.size() == 1) {
|
||||||
scribe.setTailFormatter(tailFormatter);
|
if (tailFormatter != null) {
|
||||||
try {
|
scribe.setTailFormatter(tailFormatter);
|
||||||
|
try {
|
||||||
|
visit(declarators.get(0));
|
||||||
|
scribe.runTailFormatter();
|
||||||
|
} finally {
|
||||||
|
scribe.setTailFormatter(null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
visit(declarators.get(0));
|
visit(declarators.get(0));
|
||||||
scribe.runTailFormatter();
|
|
||||||
} finally {
|
|
||||||
scribe.setTailFormatter(null);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final ListOptions options= new ListOptions(preferences.alignment_for_declarator_list);
|
final ListOptions options= new ListOptions(preferences.alignment_for_declarator_list);
|
||||||
|
@ -2047,7 +2052,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
* @param encloseInParen indicates whether the list should be enclosed in parentheses
|
* @param encloseInParen indicates whether the list should be enclosed in parentheses
|
||||||
* @param addEllipsis indicates whether ellipsis should be added after the last element
|
* @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
|
* @param tailFormatter formatter for the trailing text that should be kept together with
|
||||||
* the last element of the list.
|
* the last element of the list.
|
||||||
*/
|
*/
|
||||||
private void formatList(List<? extends IASTNode> elements, ListOptions options,
|
private void formatList(List<? extends IASTNode> elements, ListOptions options,
|
||||||
boolean encloseInParen, boolean addEllipsis, Runnable tailFormatter) {
|
boolean encloseInParen, boolean addEllipsis, Runnable tailFormatter) {
|
||||||
|
@ -2153,12 +2158,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
final IASTDeclaration decl= node.getDeclaration();
|
final IASTDeclaration decl= node.getDeclaration();
|
||||||
if (decl != null) {
|
if (decl != null) {
|
||||||
fExpectSemicolonAfterDeclaration= false;
|
formatInlineDeclaration(decl);
|
||||||
try {
|
|
||||||
decl.accept(this);
|
|
||||||
} finally {
|
|
||||||
fExpectSemicolonAfterDeclaration= true;
|
|
||||||
}
|
|
||||||
} else if (node.isCatchAll()) {
|
} else if (node.isCatchAll()) {
|
||||||
scribe.printNextToken(Token.tELIPSE, false /* preferences.insert_space_before_ellipsis */);
|
scribe.printNextToken(Token.tELIPSE, false /* preferences.insert_space_before_ellipsis */);
|
||||||
// if (false /* preferences.insert_space_after_ellipsis */) {
|
// if (false /* preferences.insert_space_after_ellipsis */) {
|
||||||
|
@ -2173,6 +2173,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void formatInlineDeclaration(final IASTDeclaration decl) {
|
||||||
|
fExpectSemicolonAfterDeclaration= false;
|
||||||
|
try {
|
||||||
|
decl.accept(this);
|
||||||
|
} finally {
|
||||||
|
fExpectSemicolonAfterDeclaration= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int visit(IASTCompoundStatement node) {
|
private int visit(IASTCompoundStatement node) {
|
||||||
formatBlock(node, preferences.brace_position_for_block, preferences.insert_space_before_opening_brace_in_block, preferences.indent_statements_compare_to_block);
|
formatBlock(node, preferences.brace_position_for_block, preferences.insert_space_before_opening_brace_in_block, preferences.indent_statements_compare_to_block);
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
|
@ -2288,7 +2297,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats given expressions as a function call, ie. enclosed in parenthesis.
|
* Formats given expressions as a function call, ie. enclosed in parenthesis.
|
||||||
*
|
*
|
||||||
* @param args the argument expressions, may be <code>null</code>
|
* @param args the argument expressions, may be <code>null</code>
|
||||||
*/
|
*/
|
||||||
private void formatFunctionCallArguments(IASTInitializerClause[] args) {
|
private void formatFunctionCallArguments(IASTInitializerClause[] args) {
|
||||||
|
@ -2785,7 +2794,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOverloadedLeftShift(IASTBinaryExpression node) {
|
private boolean isOverloadedLeftShift(IASTBinaryExpression node) {
|
||||||
return node.getOperator() == IASTBinaryExpression.op_shiftLeft &&
|
return node.getOperator() == IASTBinaryExpression.op_shiftLeft &&
|
||||||
node instanceof ICPPASTBinaryExpression &&
|
node instanceof ICPPASTBinaryExpression &&
|
||||||
((ICPPASTBinaryExpression) node).getOverload() != null;
|
((ICPPASTBinaryExpression) node).getOverload() != null;
|
||||||
}
|
}
|
||||||
|
@ -3079,14 +3088,29 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private int visit(IASTForStatement node) {
|
private int visit(IASTForStatement node) {
|
||||||
scribe.printNextToken(Token.t_for);
|
if (!startsWithMacroExpansion(node)) {
|
||||||
final int line = scribe.line;
|
scribe.printNextToken(Token.t_for);
|
||||||
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_for);
|
|
||||||
fInsideFor= true;
|
|
||||||
if (preferences.insert_space_after_opening_paren_in_for) {
|
|
||||||
scribe.space();
|
|
||||||
}
|
}
|
||||||
|
final int line = scribe.line;
|
||||||
IASTStatement initializerStmt= node.getInitializerStatement();
|
IASTStatement initializerStmt= node.getInitializerStatement();
|
||||||
|
IASTStatement body = node.getBody();
|
||||||
|
Runnable tailFormatter = null;
|
||||||
|
if (!doNodesHaveSameOffset(node, initializerStmt)) {
|
||||||
|
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_for);
|
||||||
|
fInsideFor= true;
|
||||||
|
if (preferences.insert_space_after_opening_paren_in_for) {
|
||||||
|
scribe.space();
|
||||||
|
}
|
||||||
|
if (DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block) &&
|
||||||
|
body instanceof IASTCompoundStatement && !startsWithMacroExpansion(body)) {
|
||||||
|
tailFormatter = new TrailingTokenFormatter(Token.tLBRACE,
|
||||||
|
body.getFileLocation().getNodeOffset(),
|
||||||
|
preferences.insert_space_before_opening_brace_in_block, false);
|
||||||
|
}
|
||||||
|
tailFormatter = new ClosingParensesisTailFormatter(
|
||||||
|
preferences.insert_space_before_closing_paren_in_for, tailFormatter);
|
||||||
|
}
|
||||||
|
|
||||||
initializerStmt.accept(this);
|
initializerStmt.accept(this);
|
||||||
if (peekNextToken() == Token.tSEMI) {
|
if (peekNextToken() == Token.tSEMI) {
|
||||||
scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon_in_for);
|
scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon_in_for);
|
||||||
|
@ -3124,6 +3148,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon_in_for);
|
scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon_in_for);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scribe.setTailFormatter(tailFormatter);
|
||||||
scribe.alignFragment(alignment, 1);
|
scribe.alignFragment(alignment, 1);
|
||||||
IASTExpression iterationExpr= node.getIterationExpression();
|
IASTExpression iterationExpr= node.getIterationExpression();
|
||||||
if (iterationExpr != null) {
|
if (iterationExpr != null) {
|
||||||
|
@ -3132,52 +3157,62 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
iterationExpr.accept(this);
|
iterationExpr.accept(this);
|
||||||
}
|
}
|
||||||
|
if (tailFormatter != null) {
|
||||||
|
scribe.runTailFormatter();
|
||||||
|
scribe.setTailFormatter(null);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
fInsideFor= false;
|
fInsideFor= false;
|
||||||
}
|
}
|
||||||
if (peekNextToken() == Token.tRPAREN) {
|
ok = true;
|
||||||
scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_for);
|
|
||||||
}
|
|
||||||
IASTStatement body = node.getBody();
|
|
||||||
if (body instanceof IASTCompoundStatement && !startsWithMacroExpansion(body)) {
|
|
||||||
formatLeftCurlyBrace(line, preferences.brace_position_for_block);
|
|
||||||
if (startNode(body)) {
|
|
||||||
try {
|
|
||||||
final boolean braceOnSameLine = DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block);
|
|
||||||
if (!braceOnSameLine) {
|
|
||||||
ok = true;
|
|
||||||
scribe.exitAlignment(alignment, true);
|
|
||||||
}
|
|
||||||
formatBlockOpening((IASTCompoundStatement) body,
|
|
||||||
preferences.brace_position_for_block,
|
|
||||||
preferences.insert_space_before_opening_brace_in_block);
|
|
||||||
if (braceOnSameLine) {
|
|
||||||
ok = true;
|
|
||||||
scribe.exitAlignment(alignment, true);
|
|
||||||
}
|
|
||||||
formatOpenedBlock((IASTCompoundStatement) body,
|
|
||||||
preferences.brace_position_for_block,
|
|
||||||
preferences.indent_statements_compare_to_block);
|
|
||||||
} finally {
|
|
||||||
endOfNode(body);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ok = true;
|
|
||||||
scribe.exitAlignment(alignment, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ok = true;
|
|
||||||
scribe.exitAlignment(alignment, true);
|
|
||||||
formatAction(line, body, preferences.brace_position_for_block);
|
|
||||||
}
|
|
||||||
} catch (AlignmentException e) {
|
} catch (AlignmentException e) {
|
||||||
if (ok) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
scribe.redoAlignment(e);
|
scribe.redoAlignment(e);
|
||||||
}
|
}
|
||||||
} while (!ok);
|
} while (!ok);
|
||||||
|
scribe.exitAlignment(alignment, true);
|
||||||
|
|
||||||
|
if (body instanceof IASTCompoundStatement && !startsWithMacroExpansion(body)) {
|
||||||
|
// if (body instanceof IASTCompoundStatement && !startsWithMacroExpansion(body)) {
|
||||||
|
// formatLeftCurlyBrace(line, preferences.brace_position_for_block);
|
||||||
|
// if (startNode(body)) {
|
||||||
|
// try {
|
||||||
|
// final boolean braceOnSameLine = DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block);
|
||||||
|
// if (!braceOnSameLine) {
|
||||||
|
// ok = true;
|
||||||
|
// scribe.exitAlignment(alignment, true);
|
||||||
|
// }
|
||||||
|
// formatBlockOpening((IASTCompoundStatement) body,
|
||||||
|
// preferences.brace_position_for_block,
|
||||||
|
// preferences.insert_space_before_opening_brace_in_block);
|
||||||
|
// if (braceOnSameLine) {
|
||||||
|
// ok = true;
|
||||||
|
// scribe.exitAlignment(alignment, true);
|
||||||
|
// }
|
||||||
|
// formatOpenedBlock((IASTCompoundStatement) body,
|
||||||
|
// preferences.brace_position_for_block,
|
||||||
|
// preferences.indent_statements_compare_to_block);
|
||||||
|
// } finally {
|
||||||
|
// endOfNode(body);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if (startNode(body)) {
|
||||||
|
try {
|
||||||
|
if (scribe.scanner.getCurrentPosition() <= body.getFileLocation().getNodeOffset()) {
|
||||||
|
formatLeftCurlyBrace(line, preferences.brace_position_for_block);
|
||||||
|
}
|
||||||
|
formatBlock((IASTCompoundStatement) body,
|
||||||
|
preferences.brace_position_for_block,
|
||||||
|
preferences.insert_space_before_opening_brace_in_block,
|
||||||
|
preferences.indent_statements_compare_to_block);
|
||||||
|
} finally {
|
||||||
|
endOfNode(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
formatAction(line, body, preferences.brace_position_for_block);
|
||||||
|
}
|
||||||
|
scribe.printTrailingComment();
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3210,36 +3245,53 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private int visit(IASTIfStatement node) {
|
private int visit(IASTIfStatement node) {
|
||||||
scribe.printNextToken(Token.t_if);
|
if (!startsWithMacroExpansion(node)) {
|
||||||
final int line = scribe.line;
|
scribe.printNextToken(Token.t_if);
|
||||||
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_if);
|
}
|
||||||
if (preferences.insert_space_after_opening_paren_in_if) {
|
final int line = scribe.line;
|
||||||
scribe.space();
|
IASTNode condition = node.getConditionExpression();
|
||||||
|
if (condition == null && node instanceof ICPPASTIfStatement) {
|
||||||
|
condition = ((ICPPASTIfStatement) node).getConditionDeclaration();
|
||||||
}
|
}
|
||||||
IASTExpression condExpr= node.getConditionExpression();
|
|
||||||
final IASTStatement thenStatement = node.getThenClause();
|
final IASTStatement thenStatement = node.getThenClause();
|
||||||
final IASTStatement elseStatement = node.getElseClause();
|
final IASTStatement elseStatement = node.getElseClause();
|
||||||
Runnable tailFormatter = null;
|
|
||||||
if (DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block) &&
|
fExpectSemicolonAfterDeclaration= false;
|
||||||
thenStatement instanceof IASTCompoundStatement && !startsWithMacroExpansion(thenStatement)) {
|
try {
|
||||||
tailFormatter = new TrailingTokenFormatter(Token.tLBRACE,
|
if (condition == null || !doNodesHaveSameOffset(node, condition)) {
|
||||||
thenStatement.getFileLocation().getNodeOffset(),
|
scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_if);
|
||||||
preferences.insert_space_before_opening_brace_in_block, false);
|
if (preferences.insert_space_after_opening_paren_in_if) {
|
||||||
|
scribe.space();
|
||||||
|
}
|
||||||
|
Runnable tailFormatter = null;
|
||||||
|
if (DefaultCodeFormatterConstants.END_OF_LINE.equals(preferences.brace_position_for_block) &&
|
||||||
|
thenStatement instanceof IASTCompoundStatement && !startsWithMacroExpansion(thenStatement)) {
|
||||||
|
tailFormatter = new TrailingTokenFormatter(Token.tLBRACE,
|
||||||
|
thenStatement.getFileLocation().getNodeOffset(),
|
||||||
|
preferences.insert_space_before_opening_brace_in_block, false);
|
||||||
|
}
|
||||||
|
tailFormatter = new ClosingParensesisTailFormatter(
|
||||||
|
preferences.insert_space_before_closing_paren_in_if, tailFormatter);
|
||||||
|
scribe.setTailFormatter(tailFormatter);
|
||||||
|
if (condition == null || condition instanceof IASTProblemHolder) {
|
||||||
|
scribe.skipToToken(Token.tRPAREN);
|
||||||
|
} else {
|
||||||
|
condition.accept(this);
|
||||||
|
}
|
||||||
|
scribe.runTailFormatter();
|
||||||
|
scribe.setTailFormatter(null);
|
||||||
|
} else if (!(condition instanceof IASTProblemHolder)) {
|
||||||
|
condition.accept(this);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
fExpectSemicolonAfterDeclaration= true;
|
||||||
}
|
}
|
||||||
tailFormatter = new ClosingParensesisTailFormatter(
|
|
||||||
preferences.insert_space_before_closing_paren_in_if, tailFormatter);
|
|
||||||
scribe.setTailFormatter(tailFormatter);
|
|
||||||
if (condExpr == null || condExpr instanceof IASTProblemExpression) {
|
|
||||||
scribe.skipToToken(Token.tRPAREN);
|
|
||||||
} else {
|
|
||||||
condExpr.accept(this);
|
|
||||||
}
|
|
||||||
scribe.runTailFormatter();
|
|
||||||
scribe.setTailFormatter(null);
|
|
||||||
|
|
||||||
boolean thenStatementIsBlock = false;
|
boolean thenStatementIsBlock = false;
|
||||||
if (thenStatement != null) {
|
if (thenStatement != null) {
|
||||||
if (thenStatement instanceof IASTCompoundStatement && !startsWithMacroExpansion(thenStatement)) {
|
if (condition != null && doNodeLocationsOverlap(condition, thenStatement)) {
|
||||||
|
thenStatement.accept(this);
|
||||||
|
} else if (thenStatement instanceof IASTCompoundStatement && !startsWithMacroExpansion(thenStatement)) {
|
||||||
final IASTCompoundStatement block = (IASTCompoundStatement) thenStatement;
|
final IASTCompoundStatement block = (IASTCompoundStatement) thenStatement;
|
||||||
thenStatementIsBlock = true;
|
thenStatementIsBlock = true;
|
||||||
final List<IASTStatement> statements = Arrays.asList(block.getStatements());
|
final List<IASTStatement> statements = Arrays.asList(block.getStatements());
|
||||||
|
@ -3263,7 +3315,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (node.getFileLocation().getNodeOffset() == thenStatement.getFileLocation().getNodeOffset()) {
|
if (doNodesHaveSameOffset(node, thenStatement)) {
|
||||||
startNode(thenStatement);
|
startNode(thenStatement);
|
||||||
}
|
}
|
||||||
if (elseStatement == null && preferences.keep_simple_if_on_one_line) {
|
if (elseStatement == null && preferences.keep_simple_if_on_one_line) {
|
||||||
|
@ -3310,34 +3362,38 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elseStatement != null) {
|
if (elseStatement != null) {
|
||||||
if (peekNextToken() == Token.t_else) {
|
if (condition != null && doNodeLocationsOverlap(condition, elseStatement)) {
|
||||||
if (thenStatementIsBlock) {
|
|
||||||
scribe.printNextToken(Token.t_else, preferences.insert_space_after_closing_brace_in_block);
|
|
||||||
} else {
|
|
||||||
scribe.printNextToken(Token.t_else, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elseStatement instanceof IASTCompoundStatement && !enclosedInMacroExpansion(elseStatement)) {
|
|
||||||
elseStatement.accept(this);
|
|
||||||
} else if (elseStatement instanceof IASTIfStatement) {
|
|
||||||
if (!preferences.compact_else_if) {
|
|
||||||
scribe.startNewLine();
|
|
||||||
scribe.indent();
|
|
||||||
}
|
|
||||||
scribe.space();
|
|
||||||
elseStatement.accept(this);
|
|
||||||
if (!preferences.compact_else_if) {
|
|
||||||
scribe.unIndent();
|
|
||||||
}
|
|
||||||
} else if (preferences.keep_else_statement_on_same_line) {
|
|
||||||
scribe.space();
|
|
||||||
elseStatement.accept(this);
|
elseStatement.accept(this);
|
||||||
} else {
|
} else {
|
||||||
scribe.startNewLine();
|
if (peekNextToken() == Token.t_else) {
|
||||||
scribe.indent();
|
if (thenStatementIsBlock) {
|
||||||
elseStatement.accept(this);
|
scribe.printNextToken(Token.t_else, preferences.insert_space_after_closing_brace_in_block);
|
||||||
scribe.unIndent();
|
} else {
|
||||||
|
scribe.printNextToken(Token.t_else, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elseStatement instanceof IASTCompoundStatement && !enclosedInMacroExpansion(elseStatement)) {
|
||||||
|
elseStatement.accept(this);
|
||||||
|
} else if (elseStatement instanceof IASTIfStatement) {
|
||||||
|
if (!preferences.compact_else_if) {
|
||||||
|
scribe.startNewLine();
|
||||||
|
scribe.indent();
|
||||||
|
}
|
||||||
|
scribe.space();
|
||||||
|
elseStatement.accept(this);
|
||||||
|
if (!preferences.compact_else_if) {
|
||||||
|
scribe.unIndent();
|
||||||
|
}
|
||||||
|
} else if (preferences.keep_else_statement_on_same_line) {
|
||||||
|
scribe.space();
|
||||||
|
elseStatement.accept(this);
|
||||||
|
} else {
|
||||||
|
scribe.startNewLine();
|
||||||
|
scribe.indent();
|
||||||
|
elseStatement.accept(this);
|
||||||
|
scribe.unIndent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
|
@ -3624,7 +3680,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.indent();
|
scribe.indent();
|
||||||
}
|
}
|
||||||
scribe.startNewLine();
|
scribe.startNewLine();
|
||||||
|
|
||||||
formatClosingBrace(brace_position);
|
formatClosingBrace(brace_position);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -3684,9 +3740,9 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
* Test whether the next node location is inside a macro expansion. If it is
|
* Test whether the next node location is inside a macro expansion. If it is
|
||||||
* a macro expansion, formatting will be skipped until the next node outside
|
* a macro expansion, formatting will be skipped until the next node outside
|
||||||
* the expansion is reached.
|
* the expansion is reached.
|
||||||
*
|
*
|
||||||
* @param node the AST node to be tested
|
* @param node the AST node to be tested
|
||||||
* @return <code>false</code> if the node should be skipped
|
* @return <code>false</code> if the node should be skipped
|
||||||
*/
|
*/
|
||||||
private boolean startNode(IASTNode node) {
|
private boolean startNode(IASTNode node) {
|
||||||
scribe.startNode();
|
scribe.startNode();
|
||||||
|
@ -3702,7 +3758,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
IASTFileLocation macroLocation = macroExpansion.getFileLocation();
|
IASTFileLocation macroLocation = macroExpansion.getFileLocation();
|
||||||
IASTFileLocation nodeLocation = node.getFileLocation();
|
IASTFileLocation nodeLocation = node.getFileLocation();
|
||||||
if (macroLocation.getNodeOffset() >= scribe.scanner.getCurrentPosition() &&
|
if (macroLocation.getNodeOffset() >= scribe.scanner.getCurrentPosition() &&
|
||||||
!scribe.shouldSkip(macroLocation.getNodeOffset()) &&
|
!scribe.shouldSkip(macroLocation.getNodeOffset()) &&
|
||||||
(nodeLocation.getNodeOffset() + nodeLocation.getNodeLength() ==
|
(nodeLocation.getNodeOffset() + nodeLocation.getNodeLength() ==
|
||||||
macroLocation.getNodeOffset() + macroLocation.getNodeLength() ||
|
macroLocation.getNodeOffset() + macroLocation.getNodeLength() ||
|
||||||
locations.length == 2 && isSemicolonLocation(locations[1])) &&
|
locations.length == 2 && isSemicolonLocation(locations[1])) &&
|
||||||
|
@ -3729,7 +3785,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formatting of node is complete. Undo skip region if any.
|
* Formatting of node is complete. Undo skip region if any.
|
||||||
*
|
*
|
||||||
* @param node
|
* @param node
|
||||||
*/
|
*/
|
||||||
private void endOfNode(IASTNode node) {
|
private void endOfNode(IASTNode node) {
|
||||||
|
@ -3751,7 +3807,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formatting of node continues after completion of a child node. Establish next skip region.
|
* Formatting of node continues after completion of a child node. Establish next skip region.
|
||||||
*
|
*
|
||||||
* @param node
|
* @param node
|
||||||
*/
|
*/
|
||||||
private void continueNode(IASTNode node) {
|
private void continueNode(IASTNode node) {
|
||||||
|
@ -3835,7 +3891,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
/**
|
/**
|
||||||
* Format an expression nested in parenthesis. If the operand is
|
* Format an expression nested in parenthesis. If the operand is
|
||||||
* <code>null</code>, empty parenthesis are expected.
|
* <code>null</code>, empty parenthesis are expected.
|
||||||
*
|
*
|
||||||
* @param operand
|
* @param operand
|
||||||
*/
|
*/
|
||||||
private void formatParenthesizedExpression(final IASTExpression operand) {
|
private void formatParenthesizedExpression(final IASTExpression operand) {
|
||||||
|
@ -3944,11 +4000,25 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the two given nodes have overlapping file locations. For nodes that are
|
||||||
|
* normally separated by other tokens this is an indication that they were produced by the same
|
||||||
|
* macro expansion.
|
||||||
|
*/
|
||||||
private static boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
|
private static boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
|
||||||
IASTFileLocation loc1 = node1.getFileLocation();
|
IASTFileLocation loc1 = node1.getFileLocation();
|
||||||
IASTFileLocation loc2 = node2.getFileLocation();
|
IASTFileLocation loc2 = node2.getFileLocation();
|
||||||
return loc1.getNodeOffset() + loc1.getNodeLength() > loc2.getNodeOffset() &&
|
return loc1.getNodeOffset() + loc1.getNodeLength() > loc2.getNodeOffset() &&
|
||||||
loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength();
|
loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the two given nodes have the same offset. For nodes that are normally
|
||||||
|
* separated by other tokens this is an indication that they were produced by the same macro
|
||||||
|
* expansion.
|
||||||
|
*/
|
||||||
|
private static boolean doNodesHaveSameOffset(IASTNode node1, IASTNode node2) {
|
||||||
|
return node1.getFileLocation().getNodeOffset() == node2.getFileLocation().getNodeOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void formatBlock(IASTCompoundStatement block, String block_brace_position,
|
private void formatBlock(IASTCompoundStatement block, String block_brace_position,
|
||||||
|
|
|
@ -963,7 +963,7 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
//M* A::c(M* tm) { N::iterator it = myN.find(tm); if (!it) return NULL; else return *it; }
|
//M* A::c(M* tm) { N::iterator it = myN.find(tm); if (!it) return NULL; else return *it; }
|
||||||
|
|
||||||
//void A::a(C e) {
|
//void A::a(C e) {
|
||||||
// if (D::iterator it = m.find (e))
|
// if (D::iterator it = m.find(e))
|
||||||
// m.erase(it);
|
// m.erase(it);
|
||||||
//}
|
//}
|
||||||
//T* A::b(T* t) {
|
//T* A::b(T* t) {
|
||||||
|
@ -1505,6 +1505,24 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
assertFormatterResult();
|
assertFormatterResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define BLOCK { }
|
||||||
|
//#define ALWAYS if(true)
|
||||||
|
//
|
||||||
|
//void foo() {
|
||||||
|
//ALWAYS BLOCK
|
||||||
|
//}
|
||||||
|
|
||||||
|
//#define BLOCK { }
|
||||||
|
//#define ALWAYS if(true)
|
||||||
|
//
|
||||||
|
//void foo() {
|
||||||
|
// ALWAYS
|
||||||
|
// BLOCK
|
||||||
|
//}
|
||||||
|
public void testCompoundStatementAsMacro_Temp() throws Exception {
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
//#define BLOCK { }
|
//#define BLOCK { }
|
||||||
//#define DOIT1() { }
|
//#define DOIT1() { }
|
||||||
//#define DOIT2() do { } while(false)
|
//#define DOIT2() do { } while(false)
|
||||||
|
@ -2400,6 +2418,37 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
assertFormatterResult();
|
assertFormatterResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//struct Stream {
|
||||||
|
//Stream& operator <<(const char*);
|
||||||
|
//};
|
||||||
|
//Stream GetStream();
|
||||||
|
//
|
||||||
|
//#define MY_MACRO switch (0) case 0: default: if (bool x = false) ; else GetStream()
|
||||||
|
//
|
||||||
|
//void test() {
|
||||||
|
//MY_MACRO << "Loooooooooooooooooooong string literal" << " another literal.";
|
||||||
|
//MY_MACRO << "Looooooooooooooooooooong string literal" << " another literal.";
|
||||||
|
//}
|
||||||
|
|
||||||
|
//struct Stream {
|
||||||
|
// Stream& operator <<(const char*);
|
||||||
|
//};
|
||||||
|
//Stream GetStream();
|
||||||
|
//
|
||||||
|
//#define MY_MACRO switch (0) case 0: default: if (bool x = false) ; else GetStream()
|
||||||
|
//
|
||||||
|
//void test() {
|
||||||
|
// MY_MACRO << "Loooooooooooooooooooong string literal" << " another literal.";
|
||||||
|
// MY_MACRO << "Looooooooooooooooooooong string literal"
|
||||||
|
// << " another literal.";
|
||||||
|
//}
|
||||||
|
public void testOverloadedLeftShiftChain_6() throws Exception {
|
||||||
|
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE);
|
||||||
|
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_OVERLOADED_LEFT_SHIFT_CHAIN,
|
||||||
|
Integer.toString(Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_ON_COLUMN));
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
//int main() {
|
//int main() {
|
||||||
// std::vector<std::vector<int>> test;
|
// std::vector<std::vector<int>> test;
|
||||||
// // some comment
|
// // some comment
|
||||||
|
|
Loading…
Add table
Reference in a new issue