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

Fix for 217435: Braces in macros confuse code formatter

This commit is contained in:
Anton Leherbauer 2008-02-15 12:24:49 +00:00
parent 7f2fe153bd
commit 2b53efe517
5 changed files with 594 additions and 441 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others. * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -210,7 +210,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
private MultiStatus fStatus; private MultiStatus fStatus;
public CodeFormatterVisitor(DefaultCodeFormatterOptions preferences, Map settings, int offset, int length) { public CodeFormatterVisitor(DefaultCodeFormatterOptions preferences, Map<String, String> settings, int offset, int length) {
localScanner = new Scanner() { localScanner = new Scanner() {
public Token nextToken() { public Token nextToken() {
Token t= super.nextToken(); Token t= super.nextToken();
@ -326,14 +326,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclaration) * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
*/ */
public int visit(IASTDeclaration node) { public int visit(IASTDeclaration node) {
startNode(node);
int indentLevel= scribe.indentationLevel; int indentLevel= scribe.indentationLevel;
try { try {
IASTNodeLocation[] locations= node.getNodeLocations();
if (locations.length == 0) {
throw new AbortFormatting("Empty location array in " + node.getClass().getName()); //$NON-NLS-1$
} else if (locations[0] instanceof IASTMacroExpansion && !(node instanceof IASTProblemDeclaration)) {
skipNode(node);
} else
if (node instanceof IASTFunctionDefinition) { if (node instanceof IASTFunctionDefinition) {
return visit((IASTFunctionDefinition)node); return visit((IASTFunctionDefinition)node);
} else if (node instanceof IASTSimpleDeclaration) { } else if (node instanceof IASTSimpleDeclaration) {
@ -375,6 +370,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
scribe.unIndent(); scribe.unIndent();
} }
} }
} finally {
endOfNode(node);
} }
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -383,12 +380,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTName) * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTName)
*/ */
public int visit(IASTName node) { public int visit(IASTName node) {
IASTNodeLocation[] locations= node.getNodeLocations(); startNode(node);
if (locations.length == 0) { try {
return PROCESS_SKIP;
} else if (locations[0] instanceof IASTMacroExpansion) {
formatNode(node);
} else
if (node instanceof ICPPASTQualifiedName) { if (node instanceof ICPPASTQualifiedName) {
visit((ICPPASTQualifiedName)node); visit((ICPPASTQualifiedName)node);
} else if (node instanceof ICPPASTTemplateId) { } else if (node instanceof ICPPASTTemplateId) {
@ -396,6 +389,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} else { } else {
formatNode(node); formatNode(node);
} }
} finally {
endOfNode(node);
}
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -403,14 +399,6 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTInitializer) * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTInitializer)
*/ */
public int visit(IASTInitializer node) { public int visit(IASTInitializer node) {
// IASTNodeLocation[] locations= node.getNodeLocations();
// if (locations.length == 0) {
// return PROCESS_SKIP;
// } else if (locations[0] instanceof IASTMacroExpansion) {
// formatNode(node);
// return PROCESS_SKIP;
// }
if (node instanceof ICPPASTConstructorInitializer) { if (node instanceof ICPPASTConstructorInitializer) {
visit((ICPPASTConstructorInitializer)node); visit((ICPPASTConstructorInitializer)node);
return PROCESS_SKIP; return PROCESS_SKIP;
@ -423,6 +411,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
} }
startNode(node);
try {
if (node instanceof IASTInitializerExpression) { if (node instanceof IASTInitializerExpression) {
visit((IASTInitializerExpression)node); visit((IASTInitializerExpression)node);
} else if (node instanceof IASTInitializerList) { } else if (node instanceof IASTInitializerList) {
@ -432,6 +422,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} else { } else {
formatNode(node); formatNode(node);
} }
} finally {
endOfNode(node);
}
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -440,6 +433,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
*/ */
public int visit(IASTParameterDeclaration parameterDeclaration) { public int visit(IASTParameterDeclaration parameterDeclaration) {
formatNode(parameterDeclaration); formatNode(parameterDeclaration);
endOfNode(parameterDeclaration);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -447,14 +441,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclarator) * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
*/ */
public int visit(IASTDeclarator node) { public int visit(IASTDeclarator node) {
IASTNodeLocation[] locations= node.getNodeLocations(); startNode(node);
if (locations.length == 0) {
return PROCESS_SKIP;
} else if (locations[0] instanceof IASTMacroExpansion) {
formatNode(node);
return PROCESS_SKIP;
}
try {
// common to all declarators // common to all declarators
formatPointers(node.getPointerOperators()); formatPointers(node.getPointerOperators());
if (scribe.printComment()) { if (scribe.printComment()) {
@ -489,6 +478,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
if (initializer != null) { if (initializer != null) {
initializer.accept(this); initializer.accept(this);
} }
} finally {
endOfNode(node);
}
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -496,12 +488,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier) * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier)
*/ */
public int visit(IASTDeclSpecifier node) { public int visit(IASTDeclSpecifier node) {
IASTNodeLocation[] locations= node.getNodeLocations(); startNode(node);
if (locations.length == 0) { try {
return PROCESS_SKIP;
} else if (locations[0] instanceof IASTMacroExpansion) {
formatNode(node);
} else
if (node instanceof ICPPASTCompositeTypeSpecifier) { if (node instanceof ICPPASTCompositeTypeSpecifier) {
visit((ICPPASTCompositeTypeSpecifier)node); visit((ICPPASTCompositeTypeSpecifier)node);
} else if (node instanceof ICASTCompositeTypeSpecifier) { } else if (node instanceof ICASTCompositeTypeSpecifier) {
@ -519,6 +507,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} else { } else {
formatNode(node); formatNode(node);
} }
} finally {
endOfNode(node);
}
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -527,14 +518,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
*/ */
public int visit(IASTExpression node) { public int visit(IASTExpression node) {
scribe.printComment(); scribe.printComment();
IASTNodeLocation[] locations= node.getNodeLocations(); startNode(node);
if (locations.length == 0) { try {
return PROCESS_SKIP;
} else if (locations[0] instanceof IASTMacroExpansion) {
skipNode(node);
} else if (locations[0].getNodeOffset()+locations[0].getNodeLength() < scribe.scanner.getCurrentPosition()) {
return PROCESS_SKIP;
} else
if (node instanceof IASTConditionalExpression) { if (node instanceof IASTConditionalExpression) {
visit((IASTConditionalExpression)node); visit((IASTConditionalExpression)node);
} else if (node instanceof IASTFunctionCallExpression) { } else if (node instanceof IASTFunctionCallExpression) {
@ -560,6 +545,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} else { } else {
formatNode(node); formatNode(node);
} }
} finally {
endOfNode(node);
}
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -568,16 +556,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
*/ */
public int visit(IASTStatement node) { public int visit(IASTStatement node) {
scribe.printComment(); scribe.printComment();
startNode(node);
int indentLevel= scribe.indentationLevel; int indentLevel= scribe.indentationLevel;
IASTNodeLocation[] locations= node.getNodeLocations();
try { try {
if (locations.length == 0) {
return PROCESS_SKIP;
} else if (locations[0] instanceof IASTMacroExpansion && !(node instanceof IASTProblemStatement)) {
skipNode(node);
} else if (locations[0].getNodeOffset()+locations[0].getNodeLength() < scribe.scanner.getCurrentPosition()) {
return PROCESS_SKIP;
} else
if (node instanceof IASTCompoundStatement) { if (node instanceof IASTCompoundStatement) {
visit((IASTCompoundStatement)node); visit((IASTCompoundStatement)node);
} else if (node instanceof IASTNullStatement) { } else if (node instanceof IASTNullStatement) {
@ -632,6 +613,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
scribe.unIndent(); scribe.unIndent();
} }
} }
} finally {
endOfNode(node);
} }
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -639,18 +622,23 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
/* /*
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTTypeId) * @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTTypeId)
*/ */
public int visit(IASTTypeId typeId) { public int visit(IASTTypeId node) {
if (typeId instanceof IASTProblemHolder) { startNode(node);
throw new ASTProblemException(((IASTProblemHolder)typeId).getProblem()); try {
if (node instanceof IASTProblemHolder) {
throw new ASTProblemException(((IASTProblemHolder)node).getProblem());
} }
IASTDeclSpecifier declSpec= typeId.getDeclSpecifier(); IASTDeclSpecifier declSpec= node.getDeclSpecifier();
if (declSpec != null) { if (declSpec != null) {
declSpec.accept(this); declSpec.accept(this);
} }
IASTDeclarator declarator= typeId.getAbstractDeclarator(); IASTDeclarator declarator= node.getAbstractDeclarator();
if (declarator != null) { if (declarator != null) {
declarator.accept(this); declarator.accept(this);
} }
} finally {
endOfNode(node);
}
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -659,6 +647,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
*/ */
public int visit(IASTEnumerator enumerator) { public int visit(IASTEnumerator enumerator) {
formatNode(enumerator); formatNode(enumerator);
endOfNode(enumerator);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -675,6 +664,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
*/ */
public int visit(ICPPASTBaseSpecifier specifier) { public int visit(ICPPASTBaseSpecifier specifier) {
formatNode(specifier); formatNode(specifier);
endOfNode(specifier);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -683,6 +673,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
*/ */
public int visit(ICPPASTNamespaceDefinition node) { public int visit(ICPPASTNamespaceDefinition node) {
scribe.printComment(); scribe.printComment();
startNode(node);
try {
final int line= scribe.line; final int line= scribe.line;
// namespace <name> // namespace <name>
scribe.printNextToken(Token.t_namespace, false); scribe.printNextToken(Token.t_namespace, false);
@ -710,6 +702,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
scribe.unIndent(); scribe.unIndent();
} }
formatClosingBrace(preferences.brace_position_for_namespace_declaration); formatClosingBrace(preferences.brace_position_for_namespace_declaration);
} finally {
endOfNode(node);
}
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -750,13 +745,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
* @see org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor#visit(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter) * @see org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor#visit(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter)
*/ */
public int visit(ICPPASTTemplateParameter node) { public int visit(ICPPASTTemplateParameter node) {
startNode(node);
try { try {
IASTNodeLocation[] locations= node.getNodeLocations();
if (locations.length == 0) {
return PROCESS_SKIP;
} else if (locations[0] instanceof IASTMacroExpansion) {
skipNode(node);
} else
if (node instanceof ICPPASTSimpleTypeTemplateParameter) { if (node instanceof ICPPASTSimpleTypeTemplateParameter) {
visit((ICPPASTSimpleTypeTemplateParameter)node); visit((ICPPASTSimpleTypeTemplateParameter)node);
} else if (node instanceof ICPPASTTemplatedTypeTemplateParameter) { } else if (node instanceof ICPPASTTemplatedTypeTemplateParameter) {
@ -766,11 +756,13 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
} catch (ASTProblemException e) { } catch (ASTProblemException e) {
skipNode(node); skipNode(node);
} finally {
endOfNode(node);
} }
return PROCESS_SKIP; return PROCESS_SKIP;
} }
public int visit(ICPPASTSimpleTypeTemplateParameter node) { private int visit(ICPPASTSimpleTypeTemplateParameter node) {
switch (node.getParameterType()) { switch (node.getParameterType()) {
case ICPPASTSimpleTypeTemplateParameter.st_class: case ICPPASTSimpleTypeTemplateParameter.st_class:
scribe.printNextToken(Token.t_class); scribe.printNextToken(Token.t_class);
@ -794,7 +786,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
return PROCESS_SKIP; return PROCESS_SKIP;
} }
public int visit(ICPPASTTemplatedTypeTemplateParameter node) { private int visit(ICPPASTTemplatedTypeTemplateParameter node) {
scribe.printNextToken(Token.t_template, scribe.printComment()); scribe.printNextToken(Token.t_template, scribe.printComment());
scribe.printNextToken(Token.tLT, scribe.printComment()); scribe.printNextToken(Token.tLT, scribe.printComment());
if (scribe.printComment()) { if (scribe.printComment()) {
@ -822,12 +814,17 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
private int visit(ICPPASTConstructorInitializer node) { private int visit(ICPPASTConstructorInitializer node) {
startNode(node);
try {
scribe.printNextToken(Token.tLPAREN, false); scribe.printNextToken(Token.tLPAREN, false);
final IASTExpression value= node.getExpression(); final IASTExpression value= node.getExpression();
if (value != null) { if (value != null) {
value.accept(this); value.accept(this);
} }
scribe.printNextToken(Token.tRPAREN, false); scribe.printNextToken(Token.tRPAREN, false);
} finally {
endOfNode(node);
}
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -860,11 +857,16 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
decl.accept(this); decl.accept(this);
IASTStatement bodyStmt= node.getBody(); IASTStatement bodyStmt= node.getBody();
if (bodyStmt instanceof IASTCompoundStatement) { if (bodyStmt instanceof IASTCompoundStatement) {
startNode(bodyStmt);
try {
formatLeftCurlyBrace(line, preferences.brace_position_for_method_declaration); formatLeftCurlyBrace(line, preferences.brace_position_for_method_declaration);
formatBlock((IASTCompoundStatement) bodyStmt, formatBlock((IASTCompoundStatement) bodyStmt,
preferences.brace_position_for_method_declaration, preferences.brace_position_for_method_declaration,
preferences.insert_space_before_opening_brace_in_method_declaration, preferences.insert_space_before_opening_brace_in_method_declaration,
preferences.indent_statements_compare_to_body); preferences.indent_statements_compare_to_body);
} finally {
endOfNode(bodyStmt);
}
} else { } else {
bodyStmt.accept(this); bodyStmt.accept(this);
} }
@ -977,7 +979,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
private int visit(IASTStandardFunctionDeclarator node) { private int visit(IASTStandardFunctionDeclarator node) {
final List parameters = Arrays.asList(node.getParameters()); final List<IASTParameterDeclaration> parameters = Arrays.asList(node.getParameters());
final ListAlignment align= new ListAlignment(preferences.alignment_for_parameters_in_method_declaration); final ListAlignment align= new ListAlignment(preferences.alignment_for_parameters_in_method_declaration);
align.fSpaceBeforeOpeningParen= preferences.insert_space_before_opening_paren_in_method_declaration; align.fSpaceBeforeOpeningParen= preferences.insert_space_before_opening_paren_in_method_declaration;
align.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_declaration; align.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_declaration;
@ -1014,7 +1016,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
private int visit(ICASTKnRFunctionDeclarator node) { private int visit(ICASTKnRFunctionDeclarator node) {
final List parameters= Arrays.asList(node.getParameterNames()); final List<IASTName> parameters= Arrays.asList(node.getParameterNames());
ListAlignment align= new ListAlignment(preferences.alignment_for_parameters_in_method_declaration); ListAlignment align= new ListAlignment(preferences.alignment_for_parameters_in_method_declaration);
align.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_declaration; align.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_declaration;
align.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_declaration; align.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_declaration;
@ -1065,8 +1067,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
private int visit(IASTSimpleDeclaration node) { private int visit(IASTSimpleDeclaration node) {
IASTDeclSpecifier declSpec= node.getDeclSpecifier(); IASTDeclSpecifier declSpec= node.getDeclSpecifier();
declSpec.accept(this); declSpec.accept(this);
final List declarators= Arrays.asList(node.getDeclarators()); final List<IASTDeclarator> declarators= Arrays.asList(node.getDeclarators());
if (declarators.size() > 0) { if (declarators.size() >= 1) {
if (scribe.printComment() || peekNextToken() == Token.tIDENTIFIER) { if (scribe.printComment() || peekNextToken() == Token.tIDENTIFIER) {
scribe.space(); scribe.space();
} }
@ -1196,7 +1198,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
node.getName().accept(this); node.getName().accept(this);
// base specifiers // base specifiers
final List baseSpecifiers= Arrays.asList(node.getBaseSpecifiers()); final List<ICPPASTBaseSpecifier> baseSpecifiers= Arrays.asList(node.getBaseSpecifiers());
if (baseSpecifiers.size() > 0) { if (baseSpecifiers.size() > 0) {
scribe.printNextToken(Token.tCOLON, true /*preferences.insert_space_before_colon_in_composite_type_specifier*/); scribe.printNextToken(Token.tCOLON, true /*preferences.insert_space_before_colon_in_composite_type_specifier*/);
scribe.space(); scribe.space();
@ -1301,7 +1303,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
* @param encloseInParen * @param encloseInParen
* @param addEllipsis * @param addEllipsis
*/ */
private void formatList(List elements, ListAlignment align, boolean encloseInParen, boolean addEllipsis) { private void formatList(List<? extends IASTNode> elements, ListAlignment align, boolean encloseInParen, boolean addEllipsis) {
if (encloseInParen) if (encloseInParen)
scribe.printNextToken(Token.tLPAREN, align.fSpaceBeforeOpeningParen); scribe.printNextToken(Token.tLPAREN, align.fSpaceBeforeOpeningParen);
@ -1349,7 +1351,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
if (i > 0 && align.fSpaceAfterComma) { if (i > 0 && align.fSpaceAfterComma) {
scribe.space(); scribe.space();
} }
final IASTNode node= (IASTNode) elements.get(i); final IASTNode node= elements.get(i);
if (node instanceof ICPPASTConstructorChainInitializer) { if (node instanceof ICPPASTConstructorChainInitializer) {
// this is a special case // this is a special case
visit((ICPPASTConstructorChainInitializer)node); visit((ICPPASTConstructorChainInitializer)node);
@ -1497,7 +1499,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
private int visit(IASTExpressionList node) { private int visit(IASTExpressionList node) {
final List expressions = Arrays.asList(node.getExpressions()); final List<IASTExpression> expressions = Arrays.asList(node.getExpressions());
final ListAlignment align= new ListAlignment(preferences.alignment_for_arguments_in_method_invocation); final ListAlignment align= new ListAlignment(preferences.alignment_for_arguments_in_method_invocation);
align.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_invocation; align.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_invocation;
align.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_invocation; align.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_invocation;
@ -1569,8 +1571,13 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
private int visit(IASTInitializerExpression node) { private int visit(IASTInitializerExpression node) {
if (node.getPropertyInParent() == IASTInitializerList.NESTED_INITIALIZER) {
// nested initializer expression, no need to apply extra alignment
node.getExpression().accept(this);
} else {
// declaration initializer
Alignment expressionAlignment= scribe.createAlignment( Alignment expressionAlignment= scribe.createAlignment(
"assignmentExpression", //$NON-NLS-1$ "declarationInitializer", //$NON-NLS-1$
// need configurable alignment // need configurable alignment
Alignment.M_COMPACT_SPLIT, Alignment.M_COMPACT_SPLIT,
1, 1,
@ -1591,13 +1598,14 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
} while (!ok); } while (!ok);
scribe.exitAlignment(expressionAlignment, true); scribe.exitAlignment(expressionAlignment, true);
}
return PROCESS_SKIP; return PROCESS_SKIP;
} }
private int visit(IASTInitializerList node) { private int visit(IASTInitializerList node) {
scribe.printComment(); scribe.printComment();
final List initializers = Arrays.asList(node.getInitializers()); final List<IASTInitializer> initializers = Arrays.asList(node.getInitializers());
if (initializers.isEmpty() && preferences.keep_empty_array_initializer_on_one_line) { if (initializers.isEmpty() && preferences.keep_empty_array_initializer_on_one_line) {
scribe.printNextToken(Token.tLBRACE, preferences.insert_space_before_opening_brace_in_array_initializer); scribe.printNextToken(Token.tLBRACE, preferences.insert_space_before_opening_brace_in_array_initializer);
scribe.printNextToken(Token.tRBRACE, preferences.insert_space_between_empty_braces_in_array_initializer); scribe.printNextToken(Token.tRBRACE, preferences.insert_space_between_empty_braces_in_array_initializer);
@ -1619,6 +1627,14 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
align.fContinuationIndentation= preferences.continuation_indentation_for_array_initializer; align.fContinuationIndentation= preferences.continuation_indentation_for_array_initializer;
formatList(initializers, align, false, false); formatList(initializers, align, false, false);
// handle trailing comma
if (peekNextToken() == Token.tCOMMA) {
scribe.printNextToken(Token.tCOMMA, align.fSpaceBeforeComma);
if (align.fSpaceAfterComma) {
scribe.space();
}
}
if (preferences.insert_new_line_before_closing_brace_in_array_initializer) { if (preferences.insert_new_line_before_closing_brace_in_array_initializer) {
scribe.startNewLine(); scribe.startNewLine();
} }
@ -1798,23 +1814,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
final int line = scribe.line; final int line = scribe.line;
final IASTStatement action = node.getBody(); final IASTStatement action = node.getBody();
if (action != null) { formatAction(line, action, preferences.brace_position_for_block);
if (action instanceof IASTCompoundStatement) {
formatLeftCurlyBrace(line, preferences.brace_position_for_block);
visit((IASTCompoundStatement)action);
} else if (action instanceof IASTNullStatement) {
scribe.indent();
visit((IASTNullStatement)this);
scribe.unIndent();
} else {
scribe.startNewLine();
scribe.indent();
action.accept(this);
scribe.unIndent();
scribe.startNewLine();
}
}
if (peekNextToken() == Token.t_while) {
if (preferences.insert_new_line_before_while_in_do_statement) { if (preferences.insert_new_line_before_while_in_do_statement) {
scribe.startNewLine(); scribe.startNewLine();
} }
@ -1828,6 +1830,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
node.getCondition().accept(this); node.getCondition().accept(this);
scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_while); scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_while);
}
scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon); scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon);
scribe.printTrailingComment(); scribe.printTrailingComment();
return PROCESS_SKIP; return PROCESS_SKIP;
@ -1898,7 +1901,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_for); scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_for);
formatAction(line, node.getBody(), preferences.brace_position_for_block, preferences.insert_space_before_opening_brace_in_block); formatAction(line, node.getBody(), preferences.brace_position_for_block);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -1925,7 +1928,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
if (thenStatement instanceof IASTCompoundStatement) { if (thenStatement instanceof IASTCompoundStatement) {
final IASTCompoundStatement block = (IASTCompoundStatement) thenStatement; final IASTCompoundStatement block = (IASTCompoundStatement) thenStatement;
thenStatementIsBlock = true; thenStatementIsBlock = true;
final List statements = Arrays.asList(block.getStatements()); final List<IASTStatement> statements = Arrays.asList(block.getStatements());
if (isGuardClause(block, statements) && elseStatement == null && preferences.keep_guardian_clause_on_one_line) { if (isGuardClause(block, statements) && elseStatement == null && preferences.keep_guardian_clause_on_one_line) {
/* /*
* Need a specific formatting for guard clauses * Need a specific formatting for guard clauses
@ -1934,7 +1937,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
*/ */
scribe.printNextToken(Token.tLBRACE, preferences.insert_space_before_opening_brace_in_block); scribe.printNextToken(Token.tLBRACE, preferences.insert_space_before_opening_brace_in_block);
scribe.space(); scribe.space();
((IASTStatement) statements.get(0)).accept(this); statements.get(0).accept(this);
scribe.printNextToken(Token.tRBRACE, true); scribe.printNextToken(Token.tRBRACE, true);
scribe.printTrailingComment(); scribe.printTrailingComment();
} else { } else {
@ -2115,18 +2118,20 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
scribe.indent(); scribe.indent();
} }
IASTStatement bodyStmt= node.getBody(); IASTStatement bodyStmt= node.getBody();
final List statements; final List<IASTStatement> statements;
if (bodyStmt instanceof IASTCompoundStatement) { if (bodyStmt instanceof IASTCompoundStatement) {
statements= Arrays.asList(((IASTCompoundStatement)bodyStmt).getStatements()); statements= Arrays.asList(((IASTCompoundStatement)bodyStmt).getStatements());
} else { } else {
statements= Collections.singletonList(bodyStmt); statements= Collections.singletonList(bodyStmt);
} }
final int statementsLength = statements.size(); final int statementsLength = statements.size();
if (statementsLength != 0) {
startNode(bodyStmt);
try {
boolean wasACase = false; boolean wasACase = false;
boolean wasAStatement = false; boolean wasAStatement = false;
if (statementsLength != 0) {
for (int i = 0; i < statementsLength; i++) { for (int i = 0; i < statementsLength; i++) {
final IASTStatement statement = (IASTStatement) statements.get(i); final IASTStatement statement = statements.get(i);
if (statement instanceof IASTCaseStatement || statement instanceof IASTDefaultStatement) { if (statement instanceof IASTCaseStatement || statement instanceof IASTDefaultStatement) {
if (wasACase) { if (wasACase) {
scribe.startNewLine(); scribe.startNewLine();
@ -2172,14 +2177,17 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
bracePosition = preferences.brace_position_for_block_in_case; bracePosition = preferences.brace_position_for_block_in_case;
try { try {
startNode(statement);
formatBlock((IASTCompoundStatement) statement, bracePosition, formatBlock((IASTCompoundStatement) statement, bracePosition,
preferences.insert_space_after_colon_in_case, preferences.insert_space_after_colon_in_case,
preferences.indent_statements_compare_to_block); preferences.indent_statements_compare_to_block);
} catch (ASTProblemException e) { } catch (ASTProblemException e) {
if (i < statementsLength - 1) { if (i < statementsLength - 1) {
final IASTStatement nextStatement = (IASTStatement) statements.get(i + 1); final IASTStatement nextStatement = statements.get(i + 1);
skipToNode(nextStatement); skipToNode(nextStatement);
} }
} finally {
endOfNode(statement);
} }
if (preferences.indent_switchstatements_compare_to_cases) { if (preferences.indent_switchstatements_compare_to_cases) {
scribe.indent(); scribe.indent();
@ -2187,14 +2195,17 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} else { } else {
bracePosition = preferences.brace_position_for_block; bracePosition = preferences.brace_position_for_block;
try { try {
startNode(statement);
formatBlock((IASTCompoundStatement) statement, bracePosition, formatBlock((IASTCompoundStatement) statement, bracePosition,
preferences.insert_space_before_opening_brace_in_block, preferences.insert_space_before_opening_brace_in_block,
preferences.indent_statements_compare_to_block); preferences.indent_statements_compare_to_block);
} catch (ASTProblemException e) { } catch (ASTProblemException e) {
if (i < statementsLength - 1) { if (i < statementsLength - 1) {
final IASTStatement nextStatement = (IASTStatement) statements.get(i + 1); final IASTStatement nextStatement = statements.get(i + 1);
skipToNode(nextStatement); skipToNode(nextStatement);
} }
} finally {
endOfNode(statement);
} }
} }
wasAStatement = true; wasAStatement = true;
@ -2205,7 +2216,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
statement.accept(this); statement.accept(this);
} catch (ASTProblemException e) { } catch (ASTProblemException e) {
if (i < statementsLength - 1) { if (i < statementsLength - 1) {
final IASTStatement nextStatement = (IASTStatement) statements.get(i + 1); final IASTStatement nextStatement = statements.get(i + 1);
skipToNode(nextStatement); skipToNode(nextStatement);
} }
} }
@ -2217,11 +2228,14 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
scribe.printComment(); scribe.printComment();
} }
}
if ((wasACase || wasAStatement) && preferences.indent_switchstatements_compare_to_cases) { if ((wasACase || wasAStatement) && preferences.indent_switchstatements_compare_to_cases) {
scribe.unIndent(); scribe.unIndent();
} }
} finally {
endOfNode(bodyStmt);
}
}
if (preferences.indent_switchstatements_compare_to_switch) { if (preferences.indent_switchstatements_compare_to_switch) {
scribe.unIndent(); scribe.unIndent();
} }
@ -2246,7 +2260,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_while); scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_while);
formatAction(line, node.getBody(), preferences.brace_position_for_block, preferences.insert_space_before_opening_brace_in_block); formatAction(line, node.getBody(), preferences.brace_position_for_block);
return PROCESS_SKIP; return PROCESS_SKIP;
} }
@ -2263,32 +2277,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
private void formatNode(IASTNode node) { private void formatNode(IASTNode node) {
final IASTNodeLocation[] locations= node.getNodeLocations(); scribe.printComment();
final IASTNodeLocation minLocation= getMinFileLocation(locations); skipNode(node);
if (minLocation != null) {
final IASTNodeLocation maxLocation= getMaxFileLocation(locations);
if (maxLocation != null) {
final int startOffset= minLocation.getNodeOffset();
final int endOffset= maxLocation.getNodeOffset() + maxLocation.getNodeLength();
scribe.printRaw(startOffset, endOffset - startOffset);
}
}
}
private static IASTFileLocation getMaxFileLocation(IASTNodeLocation[] locations) {
if (locations == null || locations.length == 0) {
return null;
}
final IASTNodeLocation nodeLocation= locations[locations.length-1];
return nodeLocation.asFileLocation();
}
private static IASTFileLocation getMinFileLocation(IASTNodeLocation[] locations) {
if (locations == null || locations.length == 0) {
return null;
}
final IASTNodeLocation nodeLocation= locations[0];
return nodeLocation.asFileLocation();
} }
private void exitAlignments() { private void exitAlignments() {
@ -2297,11 +2287,60 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
} }
/**
* 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
* the expansion is reached.
*
* @param node the AST node to be tested
*/
private void startNode(IASTNode node) {
IASTNodeLocation[] locations= node.getNodeLocations();
if (locations.length == 0) {
} else if (node instanceof IASTProblemHolder) {
} else if (locations[0] instanceof IASTMacroExpansion) {
IASTFileLocation expansionLocation= locations[0].asFileLocation();
int startOffset= expansionLocation.getNodeOffset();
scribe.skipRange(startOffset, startOffset + expansionLocation.getNodeLength());
} else {
IASTFileLocation fileLocation= node.getFileLocation();
scribe.resetToOffset(fileLocation.getNodeOffset());
}
}
private void endOfNode(IASTNode node) {
IASTNodeLocation[] locations= node.getNodeLocations();
if (locations.length == 0) {
} else if (node instanceof IASTProblemHolder) {
} else if (locations[0] instanceof IASTMacroExpansion) {
IASTFileLocation expansionLocation= locations[0].asFileLocation();
int macroEndOffset= expansionLocation.getNodeOffset() + expansionLocation.getNodeLength();
IASTFileLocation fileLocation= node.getFileLocation();
int nodeEndOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
if (nodeEndOffset >= macroEndOffset) {
IASTNode parent= node.getParent();
IASTFileLocation parentLocation= parent.getFileLocation();
int parentEndOffset= parentLocation.getNodeOffset() + parentLocation.getNodeLength();
if (parentEndOffset > nodeEndOffset) {
scribe.resetToOffset(nodeEndOffset);
} else if (parentEndOffset == nodeEndOffset) {
if (node instanceof IASTCompoundStatement
&& !(parent instanceof IASTCompoundStatement || parent instanceof IASTDoStatement)) {
scribe.resetToOffset(nodeEndOffset);
}
}
}
} else {
IASTFileLocation fileLocation= node.getFileLocation();
int nodeEndOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
scribe.resetToOffset(nodeEndOffset);
}
}
private void skipNode(IASTNode node) { private void skipNode(IASTNode node) {
final IASTNodeLocation[] locations= node.getNodeLocations(); final IASTNodeLocation fileLocation= node.getFileLocation();
final IASTNodeLocation maxLocation= getMaxFileLocation(locations); if (fileLocation != null) {
if (maxLocation != null) { final int endOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
final int endOffset= maxLocation.getNodeOffset() + maxLocation.getNodeLength();
final int currentOffset= scribe.scanner.getCurrentTokenEndPosition() + 1; final int currentOffset= scribe.scanner.getCurrentTokenEndPosition() + 1;
final int restLength= endOffset - currentOffset; final int restLength= endOffset - currentOffset;
if (restLength > 0) { if (restLength > 0) {
@ -2311,10 +2350,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
private void skipToNode(IASTNode node) { private void skipToNode(IASTNode node) {
final IASTNodeLocation[] locations= node.getNodeLocations(); final IASTNodeLocation fileLocation= node.getFileLocation();
final IASTNodeLocation minLocation= getMinFileLocation(locations); if (fileLocation != null) {
if (minLocation != null) { final int startOffset= fileLocation.getNodeOffset();
final int startOffset= minLocation.getNodeOffset();
final int currentOffset= scribe.scanner.getCurrentTokenEndPosition() + 1; final int currentOffset= scribe.scanner.getCurrentTokenEndPosition() + 1;
final int restLength= startOffset - currentOffset; final int restLength= startOffset - currentOffset;
if (restLength > 0) { if (restLength > 0) {
@ -2323,38 +2361,45 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
} }
private void formatAction(final int line, final IASTStatement stmt, String brace_position, boolean insertLineForSingleStatement) { private void formatAction(final int line, final IASTStatement stmt, String brace_position) {
if (stmt != null) { if (stmt != null) {
if (stmt instanceof IASTCompoundStatement) { if (stmt instanceof IASTCompoundStatement && !startsWithMacroExpansion(stmt)) {
formatLeftCurlyBrace(line, brace_position); formatLeftCurlyBrace(line, brace_position);
startNode(stmt);
try {
formatBlock((IASTCompoundStatement)stmt, brace_position, preferences.insert_space_before_opening_brace_in_block, preferences.indent_statements_compare_to_block); formatBlock((IASTCompoundStatement)stmt, brace_position, preferences.insert_space_before_opening_brace_in_block, preferences.indent_statements_compare_to_block);
} finally {
endOfNode(stmt);
}
} else if (stmt instanceof IASTNullStatement) { } else if (stmt instanceof IASTNullStatement) {
scribe.indent(); scribe.indent();
if (preferences.put_empty_statement_on_new_line) { if (preferences.put_empty_statement_on_new_line) {
scribe.startNewLine(); scribe.startNewLine();
} }
visit((IASTNullStatement)stmt); stmt.accept(this);
scribe.unIndent(); scribe.unIndent();
} else { } else {
scribe.startNewLine(); scribe.startNewLine();
scribe.indent(); scribe.indent();
stmt.accept(this); stmt.accept(this);
scribe.unIndent(); scribe.unIndent();
if (insertLineForSingleStatement) {
scribe.startNewLine();
}
} }
} }
} }
private void formatBlock(IASTCompoundStatement block, String block_brace_position, boolean insertSpaceBeforeOpeningBrace, boolean indentStatements) { private boolean startsWithMacroExpansion(IASTNode node) {
IASTNodeLocation[] locations= block.getNodeLocations(); IASTNodeLocation[] locations= node.getNodeLocations();
if (locations.length == 0) { if (locations.length == 0) {
return; } else if (node instanceof IASTProblemHolder) {
} else if (locations[0] instanceof IASTMacroExpansion) { } else if (locations[0] instanceof IASTMacroExpansion) {
formatNode(block); IASTFileLocation expansionLocation= locations[0].asFileLocation();
return; IASTFileLocation fileLocation= node.getFileLocation();
return expansionLocation.getNodeOffset() == fileLocation.getNodeOffset();
} }
return false;
}
private void formatBlock(IASTCompoundStatement block, String block_brace_position, boolean insertSpaceBeforeOpeningBrace, boolean indentStatements) {
formatOpeningBrace(block_brace_position, insertSpaceBeforeOpeningBrace); formatOpeningBrace(block_brace_position, insertSpaceBeforeOpeningBrace);
IASTStatement[] statements = block.getStatements(); IASTStatement[] statements = block.getStatements();
final int statementsLength = statements.length; final int statementsLength = statements.length;
@ -2415,18 +2460,18 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
} }
private void formatStatements(final List statements, boolean insertNewLineAfterLastStatement) { private void formatStatements(final List<IASTStatement> statements, boolean insertNewLineAfterLastStatement) {
final int statementsLength = statements.size(); final int statementsLength = statements.size();
if (statementsLength > 1) { if (statementsLength > 1) {
IASTStatement previousStatement = (IASTStatement) statements.get(0); IASTStatement previousStatement = statements.get(0);
try { try {
previousStatement.accept(this); previousStatement.accept(this);
} catch (ASTProblemException e) { } catch (ASTProblemException e) {
skipToNode((IASTStatement) statements.get(1)); skipToNode(statements.get(1));
} }
final boolean previousStatementIsNullStmt = previousStatement instanceof IASTNullStatement; final boolean previousStatementIsNullStmt = previousStatement instanceof IASTNullStatement;
for (int i = 1; i < statementsLength - 1; i++) { for (int i = 1; i < statementsLength - 1; i++) {
final IASTStatement statement = (IASTStatement) statements.get(i); final IASTStatement statement = statements.get(i);
final boolean statementIsNullStmt = statement instanceof IASTNullStatement; final boolean statementIsNullStmt = statement instanceof IASTNullStatement;
if ((previousStatementIsNullStmt && !statementIsNullStmt) if ((previousStatementIsNullStmt && !statementIsNullStmt)
|| (!previousStatementIsNullStmt && !statementIsNullStmt)) { || (!previousStatementIsNullStmt && !statementIsNullStmt)) {
@ -2435,11 +2480,11 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
try { try {
statement.accept(this); statement.accept(this);
} catch (ASTProblemException e) { } catch (ASTProblemException e) {
skipToNode((IASTStatement) statements.get(i + 1)); skipToNode(statements.get(i + 1));
} }
previousStatement = statement; previousStatement = statement;
} }
final IASTStatement statement = ((IASTStatement) statements.get(statementsLength - 1)); final IASTStatement statement = statements.get(statementsLength - 1);
final boolean statementIsNullStmt = statement instanceof IASTNullStatement; final boolean statementIsNullStmt = statement instanceof IASTNullStatement;
if ((previousStatementIsNullStmt && !statementIsNullStmt) if ((previousStatementIsNullStmt && !statementIsNullStmt)
|| (!previousStatementIsNullStmt && !statementIsNullStmt)) { || (!previousStatementIsNullStmt && !statementIsNullStmt)) {
@ -2447,7 +2492,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
statement.accept(this); statement.accept(this);
} else { } else {
final IASTStatement statement = (IASTStatement) statements.get(0); final IASTStatement statement = statements.get(0);
statement.accept(this); statement.accept(this);
} }
if (insertNewLineAfterLastStatement) { if (insertNewLineAfterLastStatement) {
@ -2483,6 +2528,9 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
protected int peekNextToken() { protected int peekNextToken() {
if (scribe.shouldSkip(scribe.scanner.getCurrentPosition())) {
return Token.tBADCHAR;
}
localScanner.resetTo(scribe.scanner.getCurrentPosition(), scribe.scannerEndPosition - 1); localScanner.resetTo(scribe.scanner.getCurrentPosition(), scribe.scannerEndPosition - 1);
int token = localScanner.getNextToken(); int token = localScanner.getNextToken();
loop: while(true) { loop: while(true) {
@ -2498,28 +2546,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
return token; return token;
} }
protected boolean isClosingTemplateToken() { private boolean isGuardClause(IASTCompoundStatement block, List<IASTStatement> statements) {
localScanner.resetTo(scribe.scanner.getCurrentPosition(), scribe.scannerEndPosition - 1);
int token = localScanner.getNextToken();
loop: while(true) {
switch(token) {
case Token.tBLOCKCOMMENT :
case Token.tLINECOMMENT :
token = localScanner.getNextToken();
continue loop;
default:
break loop;
}
}
switch(token) {
case Token.tGT :
case Token.tSHIFTR :
return true;
}
return false;
}
private boolean isGuardClause(IASTCompoundStatement block, List statements) {
IASTNodeLocation[] locations= block.getNodeLocations(); IASTNodeLocation[] locations= block.getNodeLocations();
if (locations.length == 0) { if (locations.length == 0) {
return false; return false;
@ -2548,24 +2575,24 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
* @param translationUnit the {@link IASTTranslationUnit}, may be <code>null</code> * @param translationUnit the {@link IASTTranslationUnit}, may be <code>null</code>
* @return a {@link List} of {@link Position}s * @return a {@link List} of {@link Position}s
*/ */
private static List collectInactiveCodePositions(IASTTranslationUnit translationUnit) { private static List<Position> collectInactiveCodePositions(IASTTranslationUnit translationUnit) {
if (translationUnit == null) { if (translationUnit == null) {
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
String fileName = translationUnit.getFilePath(); String fileName = translationUnit.getFilePath();
if (fileName == null) { if (fileName == null) {
return Collections.EMPTY_LIST; return Collections.emptyList();
} }
List positions = new ArrayList(); List<Position> positions = new ArrayList<Position>();
int inactiveCodeStart = -1; int inactiveCodeStart = -1;
boolean inInactiveCode = false; boolean inInactiveCode = false;
Stack inactiveCodeStack = new Stack(); Stack<Boolean> inactiveCodeStack = new Stack<Boolean>();
IASTPreprocessorStatement[] preprocStmts = translationUnit.getAllPreprocessorStatements(); IASTPreprocessorStatement[] preprocStmts = translationUnit.getAllPreprocessorStatements();
for (int i = 0; i < preprocStmts.length; i++) { for (int i = 0; i < preprocStmts.length; i++) {
IASTPreprocessorStatement statement = preprocStmts[i]; IASTPreprocessorStatement statement = preprocStmts[i];
if (!fileName.equals(statement.getContainingFilename())) { if (!statement.isPartOfTranslationUnitFile()) {
// preprocessor directive is from a different file // preprocessor directive is from a different file
continue; continue;
} }
@ -2622,7 +2649,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} }
} else if (statement instanceof IASTPreprocessorEndifStatement) { } else if (statement instanceof IASTPreprocessorEndifStatement) {
try { try {
boolean wasInInactiveCode = ((Boolean)inactiveCodeStack.pop()).booleanValue(); boolean wasInInactiveCode = inactiveCodeStack.pop().booleanValue();
if (inInactiveCode && !wasInInactiveCode) { if (inInactiveCode && !wasInInactiveCode) {
int inactiveCodeEnd = nodeLocation.getNodeOffset(); int inactiveCodeEnd = nodeLocation.getNodeOffset();
positions.add(new Position(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart)); positions.add(new Position(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart));

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others. * Copyright (c) 2000, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -92,10 +92,14 @@ public class Scribe {
private boolean preserveNewlines; private boolean preserveNewlines;
private List fSkipPositions= Collections.EMPTY_LIST; private List<Position> fSkipPositions= Collections.emptyList();
private boolean skipOverInactive; private boolean skipOverInactive;
private int fSkipTokensFrom= Integer.MAX_VALUE;
private int fSkipTokensTo;
private int fSkippedIndentations;
Scribe(CodeFormatterVisitor formatter, int offset, int length) { Scribe(CodeFormatterVisitor formatter, int offset, int length) {
scanner= new Scanner(); scanner= new Scanner();
this.formatter= formatter; this.formatter= formatter;
@ -532,6 +536,10 @@ public class Scribe {
} }
public void indent() { public void indent() {
if (shouldSkip(scanner.getCurrentPosition())) {
fSkippedIndentations++;
return;
}
indentationLevel+= indentationSize; indentationLevel+= indentationSize;
numberOfIndentations++; numberOfIndentations++;
} }
@ -549,7 +557,7 @@ public class Scribe {
/** /**
* @param list * @param list
*/ */
public void setSkipPositions(List list) { public void setSkipPositions(List<Position> list) {
fSkipPositions= list; fSkipPositions= list;
skipOverInactive= !list.isEmpty(); skipOverInactive= !list.isEmpty();
} }
@ -611,6 +619,9 @@ public class Scribe {
if (length <= 0) { if (length <= 0) {
return; return;
} }
if (shouldSkip(scanner.getCurrentPosition())) {
return;
}
if (startOffset > scanner.getCurrentPosition()) { if (startOffset > scanner.getCurrentPosition()) {
printComment(); printComment();
} }
@ -649,20 +660,26 @@ public class Scribe {
needSpace= false; needSpace= false;
} }
switch (currentToken.type) { switch (currentToken.type) {
case Token.tLBRACE: case Token.tLBRACE: {
// int currentPosition= scanner.getCurrentPosition();
scanner.resetTo(scanner.getCurrentTokenStartPosition(), scannerEndPosition-1); scanner.resetTo(scanner.getCurrentTokenStartPosition(), scannerEndPosition-1);
formatOpeningBrace(formatter.preferences.brace_position_for_block, formatter.preferences.insert_space_before_opening_brace_in_block); formatOpeningBrace(formatter.preferences.brace_position_for_block, formatter.preferences.insert_space_before_opening_brace_in_block);
if (formatter.preferences.indent_statements_compare_to_block) { if (formatter.preferences.indent_statements_compare_to_block) {
indent(); indent();
} }
// scanner.resetTo(currentPosition, scannerEndPosition-1);
break; break;
case Token.tRBRACE: }
case Token.tRBRACE: {
// int currentPosition= scanner.getCurrentPosition();
scanner.resetTo(scanner.getCurrentTokenStartPosition(), scannerEndPosition-1); scanner.resetTo(scanner.getCurrentTokenStartPosition(), scannerEndPosition-1);
if (formatter.preferences.indent_statements_compare_to_block) { if (formatter.preferences.indent_statements_compare_to_block) {
unIndent(); unIndent();
} }
formatClosingBrace(formatter.preferences.brace_position_for_block); formatClosingBrace(formatter.preferences.brace_position_for_block);
// scanner.resetTo(currentPosition, scannerEndPosition-1);
break; break;
}
case Token.tLPAREN: case Token.tLPAREN:
++parenLevel; ++parenLevel;
print(currentToken.getLength(), hasWhitespace); print(currentToken.getLength(), hasWhitespace);
@ -902,14 +919,16 @@ public class Scribe {
// if we have a space between two tokens we ensure it will be dumped in // if we have a space between two tokens we ensure it will be dumped in
// the formatted string // the formatted string
int currentTokenStartPosition= scanner.getCurrentPosition(); int currentTokenStartPosition= scanner.getCurrentPosition();
if (shouldSkip(currentTokenStartPosition)) {
return false;
}
boolean hasComment= false; boolean hasComment= false;
boolean hasLineComment= false; boolean hasLineComment= false;
boolean hasWhitespace= false; boolean hasWhitespace= false;
int count= 0; int count= 0;
while ((currentToken= scanner.nextToken()) != null) { while ((currentToken= scanner.nextToken()) != null) {
Position inactivePos= null;
if (skipOverInactive) { if (skipOverInactive) {
inactivePos= getInactivePosAt(scanner.getCurrentTokenStartPosition()); Position inactivePos= getInactivePosAt(scanner.getCurrentTokenStartPosition());
if (inactivePos != null) { if (inactivePos != null) {
int startOffset= Math.min(scanner.getCurrentTokenStartPosition(), inactivePos.getOffset()); int startOffset= Math.min(scanner.getCurrentTokenStartPosition(), inactivePos.getOffset());
int endOffset= Math.min(scannerEndPosition, inactivePos.getOffset() + inactivePos.getLength()); int endOffset= Math.min(scannerEndPosition, inactivePos.getOffset() + inactivePos.getLength());
@ -1037,8 +1056,8 @@ public class Scribe {
* @return * @return
*/ */
private Position getInactivePosAt(int offset) { private Position getInactivePosAt(int offset) {
for (Iterator iter= fSkipPositions.iterator(); iter.hasNext();) { for (Iterator<Position> iter= fSkipPositions.iterator(); iter.hasNext();) {
Position pos= (Position) iter.next(); Position pos= iter.next();
if (pos.includes(offset)) { if (pos.includes(offset)) {
return pos; return pos;
} }
@ -1220,23 +1239,15 @@ public class Scribe {
} }
} }
public void printNewLine() { public void printNewLine() {
if (lastNumberOfNewLines >= 1) { printNewLine(scanner.getCurrentTokenEndPosition() + 1);
column= 1; // ensure that the scribe is at the beginning of a new
// line
return;
}
addInsertEdit(scanner.getCurrentTokenEndPosition() + 1, lineSeparator);
line++;
lastNumberOfNewLines= 1;
column= 1;
needSpace= false;
pendingSpace= false;
} }
public void printNewLine(int insertPosition) { public void printNewLine(int insertPosition) {
if (shouldSkip(insertPosition - 1)) {
return;
}
if (lastNumberOfNewLines >= 1) { if (lastNumberOfNewLines >= 1) {
column= 1; // ensure that the scribe is at the beginning of a new column= 1; // ensure that the scribe is at the beginning of a new line
// line
return; return;
} }
addInsertEdit(insertPosition, lineSeparator); addInsertEdit(insertPosition, lineSeparator);
@ -1253,6 +1264,10 @@ public class Scribe {
public void printNextToken(int expectedTokenType, boolean considerSpaceIfAny) { public void printNextToken(int expectedTokenType, boolean considerSpaceIfAny) {
printComment(); printComment();
if (shouldSkip(scanner.getCurrentPosition())) {
// print(0, considerSpaceIfAny);
return;
}
currentToken= scanner.nextToken(); currentToken= scanner.nextToken();
if (currentToken == null || expectedTokenType != currentToken.type) { if (currentToken == null || expectedTokenType != currentToken.type) {
throw new AbortFormatting( throw new AbortFormatting(
@ -1267,6 +1282,10 @@ public class Scribe {
public void printNextToken(int[] expectedTokenTypes, boolean considerSpaceIfAny) { public void printNextToken(int[] expectedTokenTypes, boolean considerSpaceIfAny) {
printComment(); printComment();
if (shouldSkip(scanner.getCurrentPosition())) {
// print(0, considerSpaceIfAny);
return;
}
currentToken= scanner.nextToken(); currentToken= scanner.nextToken();
if (Arrays.binarySearch(expectedTokenTypes, currentToken.type) < 0) { if (Arrays.binarySearch(expectedTokenTypes, currentToken.type) < 0) {
StringBuffer expectations= new StringBuffer(5); StringBuffer expectations= new StringBuffer(5);
@ -1302,6 +1321,9 @@ public class Scribe {
// if we have a space between two tokens we ensure it will be dumped in // if we have a space between two tokens we ensure it will be dumped in
// the formatted string // the formatted string
int currentTokenStartPosition= scanner.getCurrentPosition(); int currentTokenStartPosition= scanner.getCurrentPosition();
if (shouldSkip(currentTokenStartPosition)) {
return;
}
boolean hasWhitespaces= false; boolean hasWhitespaces= false;
boolean hasComment= false; boolean hasComment= false;
boolean hasLineComment= false; boolean hasLineComment= false;
@ -1435,6 +1457,9 @@ public class Scribe {
public void space() { public void space() {
if (!needSpace) if (!needSpace)
return; return;
if (shouldSkip(scanner.getCurrentPosition())) {
return;
}
lastNumberOfNewLines= 0; lastNumberOfNewLines= 0;
pendingSpace= true; pendingSpace= true;
column++; column++;
@ -1470,6 +1495,10 @@ public class Scribe {
} }
public void unIndent() { public void unIndent() {
if (shouldSkip(scanner.getCurrentPosition())) {
fSkippedIndentations--;
return;
}
indentationLevel-= indentationSize; indentationLevel-= indentationSize;
numberOfIndentations--; numberOfIndentations--;
} }
@ -1477,8 +1506,11 @@ public class Scribe {
/** /**
*/ */
public void printModifiers() { public void printModifiers() {
boolean isFirstModifier= true;
int currentTokenStartPosition= scanner.getCurrentPosition(); int currentTokenStartPosition= scanner.getCurrentPosition();
if (shouldSkip(currentTokenStartPosition)) {
return;
}
boolean isFirstModifier= true;
boolean hasComment= false; boolean hasComment= false;
while ((currentToken= scanner.nextToken()) != null) { while ((currentToken= scanner.nextToken()) != null) {
switch (currentToken.type) { switch (currentToken.type) {
@ -1580,6 +1612,9 @@ public class Scribe {
*/ */
public boolean skipToToken(int expectedTokenType) { public boolean skipToToken(int expectedTokenType) {
int skipStart= scanner.getCurrentPosition(); int skipStart= scanner.getCurrentPosition();
if (shouldSkip(skipStart)) {
return true;
}
int braceLevel= 0; int braceLevel= 0;
int parenLevel= 0; int parenLevel= 0;
while ((currentToken= scanner.nextToken()) != null) { while ((currentToken= scanner.nextToken()) != null) {
@ -1634,4 +1669,44 @@ public class Scribe {
} }
} }
/**
* @param offset
* @return
*/
boolean shouldSkip(int offset) {
return offset >= fSkipTokensFrom && offset <= fSkipTokensTo;
}
public void skipRange(int offset, int endOffset) {
if (offset == fSkipTokensFrom) {
return;
}
final int currentPosition= scanner.getCurrentPosition();
if (currentPosition >= offset && currentPosition < endOffset) {
printRaw(offset, endOffset - offset);
}
fSkipTokensFrom= offset;
fSkipTokensTo= endOffset;
}
public void resetToOffset(int offset) {
if (fSkipTokensTo > 0) {
fSkipTokensFrom= Integer.MAX_VALUE;
fSkipTokensTo= 0;
while (fSkippedIndentations > 0) {
indent();
fSkippedIndentations--;
}
while (fSkippedIndentations < 0) {
unIndent();
fSkippedIndentations++;
}
if (offset > scanner.getCurrentPosition()) {
printRaw(scanner.getCurrentPosition(), offset - scanner.getCurrentPosition());
scanner.resetTo(offset, scannerEndPosition - 1);
}
}
}
} }

View file

@ -53,3 +53,10 @@ void bug183220() {
} }
} }
} }
// declaration with array initializer
long dummy[]= { 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, };

View file

@ -28,3 +28,8 @@ void bug183220()
} }
} }
} }
// declaration with array initializer
long dummy[]= { 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
};

View file

@ -58,7 +58,7 @@ public class CodeFormatterTest extends BaseUITestCase {
String before= contents[0].toString(); String before= contents[0].toString();
IDocument document= new Document(before); IDocument document= new Document(before);
String expected= contents[1].toString(); String expected= contents[1].toString();
TextEdit edit= CodeFormatterUtil.format(CodeFormatter.K_COMPILATION_UNIT, before, 0, TextUtilities.getDefaultLineDelimiter(document), fOptions); TextEdit edit= CodeFormatterUtil.format(CodeFormatter.K_TRANSLATION_UNIT, before, 0, TextUtilities.getDefaultLineDelimiter(document), fOptions);
assertNotNull(edit); assertNotNull(edit);
edit.apply(document); edit.apply(document);
assertEquals(expected, document.get()); assertEquals(expected, document.get());
@ -353,4 +353,43 @@ public class CodeFormatterTest extends BaseUITestCase {
assertFormatterResult(); assertFormatterResult();
} }
//#define break_start(); { int foo;
//#define break_end(); foo = 0; }
//
//void break_indenter(int a, int b) {
// break_start(); // This semicolon moves to its own line.
// if(a > b) {
// indentation_remains();
// }
//
// if(b>a)
// indentation_vanishes();
//
// break_end();
//
// if(b == a)
// indentation_remains();
//}
//#define break_start(); { int foo;
//#define break_end(); foo = 0; }
//
//void break_indenter(int a, int b) {
// break_start()
// ; // This semicolon moves to its own line.
// if (a > b) {
// indentation_remains();
// }
//
// if (b>a)
// indentation_vanishes();
//
// break_end();
//
// if (b == a)
// indentation_remains();
//}
public void testBracesInMacros_Bug217435() throws Exception {
assertFormatterResult();
}
} }