mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Formatting of trailing characters in function declarations and calls.
This commit is contained in:
parent
4628ff3643
commit
4b984c2b5f
5 changed files with 487 additions and 230 deletions
|
@ -118,6 +118,7 @@ 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;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
|
||||||
|
@ -167,8 +168,8 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ListAlignment {
|
private static class ListOptions {
|
||||||
public int fMode;
|
public final int fMode;
|
||||||
public boolean fSpaceBeforeComma;
|
public boolean fSpaceBeforeComma;
|
||||||
public boolean fSpaceAfterComma= true;
|
public boolean fSpaceAfterComma= true;
|
||||||
public boolean fSpaceAfterOpeningParen;
|
public boolean fSpaceAfterOpeningParen;
|
||||||
|
@ -178,11 +179,123 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
public int fContinuationIndentation= -1;
|
public int fContinuationIndentation= -1;
|
||||||
public int fTieBreakRule = Alignment.R_INNERMOST;
|
public int fTieBreakRule = Alignment.R_INNERMOST;
|
||||||
|
|
||||||
public ListAlignment(int mode) {
|
public ListOptions(int mode) {
|
||||||
fMode= mode;
|
fMode= mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Formats a given token at a given position.
|
||||||
|
* @see #formatList(List, ListAlignment, boolean, boolean, Runnable)
|
||||||
|
*/
|
||||||
|
class TrailingTokenFormatter implements Runnable {
|
||||||
|
private final int tokenType;
|
||||||
|
private final int tokenPosition;
|
||||||
|
private final boolean spaceBeforeToken;
|
||||||
|
private final boolean spaceAfterToken;
|
||||||
|
|
||||||
|
TrailingTokenFormatter(int tokenType, int tokenPosition,
|
||||||
|
boolean spaceBeforeToken, boolean spaceAfterToken) {
|
||||||
|
this.tokenType = tokenType;
|
||||||
|
this.tokenPosition = tokenPosition;
|
||||||
|
this.spaceBeforeToken = spaceBeforeToken;
|
||||||
|
this.spaceAfterToken = spaceAfterToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
int offset = scribe.scanner.getCurrentPosition();
|
||||||
|
if (tokenPosition < 0 || offset > tokenPosition)
|
||||||
|
return;
|
||||||
|
if (offset < tokenPosition)
|
||||||
|
scribe.restartAtOffset(tokenPosition);
|
||||||
|
int token= peekNextToken();
|
||||||
|
if (token == tokenType) {
|
||||||
|
scribe.pendingSpace = false;
|
||||||
|
scribe.printNextToken(tokenType, spaceBeforeToken);
|
||||||
|
scribe.printTrailingComment();
|
||||||
|
if (spaceAfterToken) {
|
||||||
|
scribe.space();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Formats a trailing comma.
|
||||||
|
* @see #formatList(List, ListAlignment, boolean, boolean, Runnable)
|
||||||
|
*/
|
||||||
|
class TrailingCommaFormatter extends TrailingTokenFormatter {
|
||||||
|
TrailingCommaFormatter(boolean spaceBeforeComma, boolean spaceAfterComma) {
|
||||||
|
super(Token.tCOMMA, scribe.findToken(Token.tCOMMA), spaceBeforeComma, spaceAfterComma);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Formats a trailing semicolon.
|
||||||
|
* @see #formatList(List, ListAlignment, boolean, boolean, Runnable)
|
||||||
|
*/
|
||||||
|
class TrailingSemicolonFormatter extends TrailingTokenFormatter {
|
||||||
|
TrailingSemicolonFormatter(IASTNode node) {
|
||||||
|
super(Token.tSEMI, getLastNodeCharacterPosition(node),
|
||||||
|
fInsideFor ? preferences.insert_space_before_semicolon_in_for :
|
||||||
|
preferences.insert_space_before_semicolon,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Formats the part of a function declaration following the parameter list.
|
||||||
|
* @see #formatList(List, ListAlignment, boolean, boolean, Runnable)
|
||||||
|
*/
|
||||||
|
public class CPPFunctionDeclaratorTailFormatter implements Runnable {
|
||||||
|
private final ICPPASTFunctionDeclarator node;
|
||||||
|
private final Runnable continuationFormatter;
|
||||||
|
|
||||||
|
public CPPFunctionDeclaratorTailFormatter(ICPPASTFunctionDeclarator node,
|
||||||
|
Runnable tailFormatter) {
|
||||||
|
this.node = node;
|
||||||
|
this.continuationFormatter = tailFormatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
boolean needSpace = skipConstVolatileRestrict();
|
||||||
|
if (node.getExceptionSpecification() != null && peekNextToken() == Token.t_throw)
|
||||||
|
return;
|
||||||
|
// Skip the rest (=0)
|
||||||
|
if (needSpace && scribe.printComment()) {
|
||||||
|
scribe.space();
|
||||||
|
}
|
||||||
|
skipNode(node);
|
||||||
|
if (continuationFormatter != null)
|
||||||
|
continuationFormatter.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClosingParensesisTailFormatter implements Runnable {
|
||||||
|
private final boolean spaceBeforeClosingParen;
|
||||||
|
private final Runnable continuationFormatter;
|
||||||
|
private final int parenPosition;
|
||||||
|
|
||||||
|
public ClosingParensesisTailFormatter(boolean spaceBeforeClosingParen,
|
||||||
|
Runnable tailFormatter) {
|
||||||
|
this.spaceBeforeClosingParen = spaceBeforeClosingParen;
|
||||||
|
this.continuationFormatter = tailFormatter;
|
||||||
|
this.parenPosition = scribe.findToken(Token.tRPAREN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
int offset = scribe.scanner.getCurrentPosition();
|
||||||
|
if (parenPosition >= 0 && offset <= parenPosition) {
|
||||||
|
if (offset < parenPosition)
|
||||||
|
scribe.restartAtOffset(parenPosition);
|
||||||
|
scribe.pendingSpace = false;
|
||||||
|
scribe.printNextToken(Token.tRPAREN, spaceBeforeClosingParen);
|
||||||
|
}
|
||||||
|
if (continuationFormatter != null)
|
||||||
|
continuationFormatter.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
shouldVisitNames = true;
|
shouldVisitNames = true;
|
||||||
shouldVisitDeclarations = true;
|
shouldVisitDeclarations = true;
|
||||||
|
@ -1069,10 +1182,10 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
final ICPPASTTemplateParameter[] templateParameters= node.getTemplateParameters();
|
final ICPPASTTemplateParameter[] templateParameters= node.getTemplateParameters();
|
||||||
if (templateParameters.length > 0) {
|
if (templateParameters.length > 0) {
|
||||||
final ListAlignment align= new ListAlignment(Alignment.M_COMPACT_SPLIT);
|
final ListOptions options= new ListOptions(Alignment.M_COMPACT_SPLIT);
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_template_parameters;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_template_parameters;
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_template_parameters;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_template_parameters;
|
||||||
formatList(Arrays.asList(templateParameters), align, false, false);
|
formatList(Arrays.asList(templateParameters), options, false, false, null);
|
||||||
}
|
}
|
||||||
scribe.printNextToken(new int[] { Token.tGT, Token.tSHIFTR }, preferences.insert_space_before_closing_angle_bracket_in_template_parameters);
|
scribe.printNextToken(new int[] { Token.tGT, Token.tSHIFTR }, preferences.insert_space_before_closing_angle_bracket_in_template_parameters);
|
||||||
if (preferences.insert_space_after_closing_angle_bracket_in_template_parameters) {
|
if (preferences.insert_space_after_closing_angle_bracket_in_template_parameters) {
|
||||||
|
@ -1158,9 +1271,9 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.startNewLine();
|
scribe.startNewLine();
|
||||||
scribe.indentForContinuation();
|
scribe.indentForContinuation();
|
||||||
}
|
}
|
||||||
final ListAlignment align= new ListAlignment(preferences.alignment_for_constructor_initializer_list);
|
final ListOptions options= new ListOptions(preferences.alignment_for_constructor_initializer_list);
|
||||||
align.fTieBreakRule = Alignment.R_OUTERMOST;
|
options.fTieBreakRule = Alignment.R_OUTERMOST;
|
||||||
formatList(Arrays.asList(constructorChain), align, false, false);
|
formatList(Arrays.asList(constructorChain), options, false, false, null);
|
||||||
scribe.unIndentForContinuation();
|
scribe.unIndentForContinuation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1203,28 +1316,30 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private int visit(ICPPASTFunctionDeclarator node) {
|
private int visit(ICPPASTFunctionDeclarator node) {
|
||||||
visit((IASTStandardFunctionDeclarator) node);
|
final List<ICPPASTParameterDeclaration> parameters = Arrays.asList(node.getParameters());
|
||||||
|
final ListOptions options = createListOptionsForFunctionParameters();
|
||||||
|
formatList(parameters, options, true, node.takesVarArgs(),
|
||||||
|
new CPPFunctionDeclaratorTailFormatter(node, scribe.getTailFormatter()));
|
||||||
|
|
||||||
boolean needSpace = skipConstVolatileRestrict();
|
IASTFileLocation fileLocation= node.getFileLocation();
|
||||||
|
if (fileLocation != null &&
|
||||||
final IASTTypeId[] exceptionSpecification= node.getExceptionSpecification();
|
scribe.scanner.getCurrentPosition() < fileLocation.getNodeOffset() + fileLocation.getNodeLength()) {
|
||||||
if (exceptionSpecification != null) {
|
skipConstVolatileRestrict();
|
||||||
if (peekNextToken() == Token.t_throw) {
|
|
||||||
|
final IASTTypeId[] exceptionSpecification= node.getExceptionSpecification();
|
||||||
|
if (exceptionSpecification != null && peekNextToken() == Token.t_throw)
|
||||||
formatExceptionSpecification(exceptionSpecification);
|
formatExceptionSpecification(exceptionSpecification);
|
||||||
needSpace = false;
|
// Skip the rest (=0)
|
||||||
}
|
scribe.printTrailingComment();
|
||||||
}
|
|
||||||
// skip the rest (=0)
|
|
||||||
if (needSpace && scribe.printComment()) {
|
|
||||||
scribe.space();
|
scribe.space();
|
||||||
|
skipNode(node);
|
||||||
}
|
}
|
||||||
skipNode(node);
|
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void formatExceptionSpecification(final IASTTypeId[] exceptionSpecification) {
|
private void formatExceptionSpecification(final IASTTypeId[] exceptionSpecification) {
|
||||||
if (exceptionSpecification.length > 0) {
|
if (exceptionSpecification.length > 0) {
|
||||||
Alignment alignment =scribe.createAlignment(
|
Alignment alignment = scribe.createAlignment(
|
||||||
Alignment.EXCEPTION_SPECIFICATION,
|
Alignment.EXCEPTION_SPECIFICATION,
|
||||||
preferences.alignment_for_throws_clause_in_method_declaration,
|
preferences.alignment_for_throws_clause_in_method_declaration,
|
||||||
exceptionSpecification.length,
|
exceptionSpecification.length,
|
||||||
|
@ -1279,19 +1394,43 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
|
|
||||||
private int visit(IASTStandardFunctionDeclarator node) {
|
private int visit(IASTStandardFunctionDeclarator node) {
|
||||||
final List<IASTParameterDeclaration> 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 ListOptions options = createListOptionsForFunctionParameters();
|
||||||
align.fSpaceBeforeOpeningParen= preferences.insert_space_before_opening_paren_in_method_declaration;
|
formatList(parameters, options, true, node.takesVarArgs(), new TrailingSemicolonFormatter(node));
|
||||||
align.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_declaration;
|
|
||||||
align.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_declaration;
|
|
||||||
align.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_declaration;
|
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_method_declaration_parameters;
|
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_method_declaration_parameters;
|
|
||||||
align.fTieBreakRule = Alignment.R_OUTERMOST;
|
|
||||||
formatList(parameters, align, true, node.takesVarArgs());
|
|
||||||
|
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ListOptions createListOptionsForFunctionParameters() {
|
||||||
|
final ListOptions options= new ListOptions(preferences.alignment_for_parameters_in_method_declaration);
|
||||||
|
options.fSpaceBeforeOpeningParen= preferences.insert_space_before_opening_paren_in_method_declaration;
|
||||||
|
options.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_declaration;
|
||||||
|
options.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_declaration;
|
||||||
|
options.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_declaration;
|
||||||
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_method_declaration_parameters;
|
||||||
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_method_declaration_parameters;
|
||||||
|
options.fTieBreakRule = Alignment.R_OUTERMOST;
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the position of the last character of a node, or -1 if that character is part of
|
||||||
|
* a macro expansion.
|
||||||
|
*
|
||||||
|
* @param node an AST node
|
||||||
|
* @return the position of the last character of a node, or -1 if that character is part of
|
||||||
|
* a macro expansion.
|
||||||
|
*/
|
||||||
|
private static int getLastNodeCharacterPosition(IASTNode node) {
|
||||||
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
|
if (locations.length > 0) {
|
||||||
|
IASTNodeLocation lastLocation = locations[locations.length - 1];
|
||||||
|
if (!(lastLocation instanceof IASTMacroExpansionLocation)) {
|
||||||
|
IASTFileLocation fileLocation= lastLocation.asFileLocation();
|
||||||
|
return fileLocation.getNodeOffset() + fileLocation.getNodeLength() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
private void formatPointers(IASTPointerOperator[] pointers) {
|
private void formatPointers(IASTPointerOperator[] pointers) {
|
||||||
for (IASTPointerOperator pointer : pointers) {
|
for (IASTPointerOperator pointer : pointers) {
|
||||||
if (scribe.printComment()) {
|
if (scribe.printComment()) {
|
||||||
|
@ -1323,13 +1462,13 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
|
|
||||||
private int visit(ICASTKnRFunctionDeclarator node) {
|
private int visit(ICASTKnRFunctionDeclarator node) {
|
||||||
final List<IASTName> parameters= Arrays.asList(node.getParameterNames());
|
final List<IASTName> parameters= Arrays.asList(node.getParameterNames());
|
||||||
ListAlignment align= new ListAlignment(preferences.alignment_for_parameters_in_method_declaration);
|
ListOptions options= new ListOptions(preferences.alignment_for_parameters_in_method_declaration);
|
||||||
align.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_declaration;
|
options.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_declaration;
|
||||||
align.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_declaration;
|
options.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_declaration;
|
||||||
align.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_declaration;
|
options.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_declaration;
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_method_declaration_parameters;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_method_declaration_parameters;
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_method_declaration_parameters;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_method_declaration_parameters;
|
||||||
formatList(parameters, align, true, false);
|
formatList(parameters, options, true, false, null);
|
||||||
|
|
||||||
IASTDeclaration[] parameterDecls= node.getParameterDeclarations();
|
IASTDeclaration[] parameterDecls= node.getParameterDeclarations();
|
||||||
scribe.startNewLine();
|
scribe.startNewLine();
|
||||||
|
@ -1405,38 +1544,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.space();
|
scribe.space();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final ListAlignment align= new ListAlignment(preferences.alignment_for_declarator_list);
|
final ListOptions options= new ListOptions(preferences.alignment_for_declarator_list);
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_declarator_list;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_declarator_list;
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_declarator_list;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_declarator_list;
|
||||||
formatList(declarators, align, false, false);
|
Runnable tailFormatter = fExpectSemicolonAfterDeclaration ?
|
||||||
}
|
new TrailingSemicolonFormatter(node) : null;
|
||||||
if (fExpectSemicolonAfterDeclaration) {
|
formatList(declarators, options, false, false, tailFormatter);
|
||||||
handleNodeEndingInSemicolon(node);
|
|
||||||
if (peekNextToken() == Token.tSEMI) {
|
|
||||||
scribe.printNextToken(Token.tSEMI, fInsideFor ? preferences.insert_space_before_semicolon_in_for : preferences.insert_space_before_semicolon);
|
|
||||||
scribe.printTrailingComment();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleNodeEndingInSemicolon(IASTSimpleDeclaration node) {
|
|
||||||
if (scribe.skipRange() && peekNextToken(true) == Token.tSEMI) {
|
|
||||||
IASTNodeLocation[] locations= node.getNodeLocations();
|
|
||||||
if (locations.length > 0) {
|
|
||||||
IASTNodeLocation lastLocation = locations[locations.length - 1];
|
|
||||||
if (!(lastLocation instanceof IASTMacroExpansionLocation)) {
|
|
||||||
IASTFileLocation fileLocation= lastLocation.asFileLocation();
|
|
||||||
int startOffset= fileLocation.getNodeOffset();
|
|
||||||
int currentPosition= scribe.scanner.getCurrentPosition();
|
|
||||||
if (currentPosition >= startOffset) {
|
|
||||||
scribe.restartAtOffset(startOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int visit(ICPPASTTemplateDeclaration node) {
|
private int visit(ICPPASTTemplateDeclaration node) {
|
||||||
if (node.isExported()) {
|
if (node.isExported()) {
|
||||||
scribe.printNextToken(Token.t_export);
|
scribe.printNextToken(Token.t_export);
|
||||||
|
@ -1451,10 +1568,10 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
// template parameters
|
// template parameters
|
||||||
final ICPPASTTemplateParameter[] templateParameters= node.getTemplateParameters();
|
final ICPPASTTemplateParameter[] templateParameters= node.getTemplateParameters();
|
||||||
if (templateParameters.length > 0) {
|
if (templateParameters.length > 0) {
|
||||||
final ListAlignment align= new ListAlignment(Alignment.M_COMPACT_SPLIT);
|
final ListOptions options= new ListOptions(Alignment.M_COMPACT_SPLIT);
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_template_parameters;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_template_parameters;
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_template_parameters;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_template_parameters;
|
||||||
formatList(Arrays.asList(templateParameters), align, false, false);
|
formatList(Arrays.asList(templateParameters), options, false, false, null);
|
||||||
}
|
}
|
||||||
scribe.printNextToken(new int[] { Token.tGT, Token.tSHIFTR }, preferences.insert_space_before_closing_angle_bracket_in_template_parameters);
|
scribe.printNextToken(new int[] { Token.tGT, Token.tSHIFTR }, preferences.insert_space_before_closing_angle_bracket_in_template_parameters);
|
||||||
if (preferences.insert_space_after_closing_angle_bracket_in_template_parameters) {
|
if (preferences.insert_space_after_closing_angle_bracket_in_template_parameters) {
|
||||||
|
@ -1624,10 +1741,10 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
} catch (UnsupportedOperationException exc) {
|
} catch (UnsupportedOperationException exc) {
|
||||||
} catch (ExpansionOverlapsBoundaryException exc) {
|
} catch (ExpansionOverlapsBoundaryException exc) {
|
||||||
}
|
}
|
||||||
final ListAlignment align= new ListAlignment(preferences.alignment_for_base_clause_in_type_declaration);
|
final ListOptions options= new ListOptions(preferences.alignment_for_base_clause_in_type_declaration);
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_base_types;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_base_types;
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_base_types;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_base_types;
|
||||||
formatList(baseSpecifiers, align, false, false);
|
formatList(baseSpecifiers, options, false, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// member declarations
|
// member declarations
|
||||||
|
@ -1774,16 +1891,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
final int enumIndent= scribe.numberOfIndentations;
|
final int enumIndent= scribe.numberOfIndentations;
|
||||||
final IASTEnumerator[] enumerators= node.getEnumerators();
|
final IASTEnumerator[] enumerators= node.getEnumerators();
|
||||||
|
|
||||||
final ListAlignment align= new ListAlignment(preferences.alignment_for_enumerator_list);
|
final ListOptions options= new ListOptions(preferences.alignment_for_enumerator_list);
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_enum_declarations;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_enum_declarations;
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_enum_declarations;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_enum_declarations;
|
||||||
align.fContinuationIndentation= enumIndent == headerIndent ? 1 : 0;
|
options.fContinuationIndentation= enumIndent == headerIndent ? 1 : 0;
|
||||||
formatList(Arrays.asList(enumerators), align, false, false);
|
formatList(Arrays.asList(enumerators), options, false, false, null);
|
||||||
|
|
||||||
// handle trailing comma
|
// handle trailing comma
|
||||||
if (peekNextToken() == Token.tCOMMA) {
|
if (peekNextToken() == Token.tCOMMA) {
|
||||||
scribe.printNextToken(Token.tCOMMA, align.fSpaceBeforeComma);
|
scribe.printNextToken(Token.tCOMMA, options.fSpaceBeforeComma);
|
||||||
if (align.fSpaceAfterComma) {
|
if (options.fSpaceAfterComma) {
|
||||||
scribe.space();
|
scribe.space();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1800,97 +1917,86 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
/**
|
/**
|
||||||
* Format a given list of elements according alignment options.
|
* Format a given list of elements according alignment options.
|
||||||
*
|
*
|
||||||
* @param elements
|
* @param elements the elements to format
|
||||||
* @param align
|
* @param options formatting options
|
||||||
* @param encloseInParen
|
* @param encloseInParen indicates whether the list should be enclosed in parentheses
|
||||||
* @param addEllipsis
|
* @param addEllipsis indicates whether ellipsis should be added after the last element
|
||||||
|
* @param tailFormatter formatter for the trailing text that should be kept together with
|
||||||
|
* the last element of the list.
|
||||||
*/
|
*/
|
||||||
private void formatList(List<? extends IASTNode> elements, ListAlignment align,
|
private void formatList(List<? extends IASTNode> elements, ListOptions options,
|
||||||
boolean encloseInParen, boolean addEllipsis) {
|
boolean encloseInParen, boolean addEllipsis, Runnable tailFormatter) {
|
||||||
if (encloseInParen)
|
if (encloseInParen)
|
||||||
scribe.printNextToken(Token.tLPAREN, align.fSpaceBeforeOpeningParen);
|
scribe.printNextToken(Token.tLPAREN, options.fSpaceBeforeOpeningParen);
|
||||||
|
|
||||||
final int elementsLength = elements.size();
|
final int elementsLength = elements.size();
|
||||||
|
if (encloseInParen) {
|
||||||
|
boolean spaceBeforeClosingParen = elements.isEmpty() && !addEllipsis ?
|
||||||
|
options.fSpaceBetweenEmptyParen : options.fSpaceBeforeClosingParen;
|
||||||
|
tailFormatter = new ClosingParensesisTailFormatter(spaceBeforeClosingParen, tailFormatter);
|
||||||
|
}
|
||||||
|
|
||||||
if (!elements.isEmpty() || addEllipsis) {
|
if (!elements.isEmpty() || addEllipsis) {
|
||||||
if (align.fSpaceAfterOpeningParen) {
|
if (options.fSpaceAfterOpeningParen) {
|
||||||
scribe.space();
|
scribe.space();
|
||||||
}
|
}
|
||||||
final int continuationIndentation= align.fContinuationIndentation >= 0 ?
|
final int continuationIndentation= options.fContinuationIndentation >= 0 ?
|
||||||
align.fContinuationIndentation : preferences.continuation_indentation;
|
options.fContinuationIndentation : preferences.continuation_indentation;
|
||||||
Alignment listAlignment = scribe.createAlignment(
|
Alignment alignment = scribe.createAlignment(
|
||||||
Alignment.LIST_ELEMENTS_PREFIX +
|
Alignment.LIST_ELEMENTS_PREFIX +
|
||||||
(elements.isEmpty() ? "ellipsis" : elements.get(0).getClass().getSimpleName()), //$NON-NLS-1$
|
(elements.isEmpty() ? "ellipsis" : elements.get(0).getClass().getSimpleName()), //$NON-NLS-1$
|
||||||
align.fMode,
|
options.fMode,
|
||||||
align.fTieBreakRule,
|
options.fTieBreakRule,
|
||||||
elementsLength + (addEllipsis ? 1 : 0),
|
elementsLength + (addEllipsis ? 1 : 0),
|
||||||
scribe.scanner.getCurrentPosition(),
|
scribe.scanner.getCurrentPosition(),
|
||||||
continuationIndentation,
|
continuationIndentation,
|
||||||
false);
|
false);
|
||||||
scribe.enterAlignment(listAlignment);
|
scribe.enterAlignment(alignment);
|
||||||
boolean ok = false;
|
boolean ok = false;
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < elementsLength; i++) {
|
for (i = 0; i < elementsLength; i++) {
|
||||||
if (i > 0) {
|
|
||||||
// handle missing parameter
|
|
||||||
int token= peekNextToken();
|
|
||||||
if (token == Token.tIDENTIFIER) {
|
|
||||||
if (!scribe.skipToToken(Token.tCOMMA)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (token == Token.tRPAREN) {
|
|
||||||
if (encloseInParen) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!scribe.skipToToken(Token.tCOMMA)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scribe.printNextToken(Token.tCOMMA, align.fSpaceBeforeComma);
|
|
||||||
scribe.printTrailingComment();
|
|
||||||
}
|
|
||||||
scribe.alignFragment(listAlignment, i);
|
|
||||||
if (i > 0 && align.fSpaceAfterComma) {
|
|
||||||
scribe.space();
|
|
||||||
}
|
|
||||||
final IASTNode node= elements.get(i);
|
final IASTNode node= elements.get(i);
|
||||||
|
if (i < alignment.fragmentCount - 1) {
|
||||||
|
scribe.setTailFormatter(
|
||||||
|
new TrailingCommaFormatter(options.fSpaceBeforeComma,
|
||||||
|
options.fSpaceAfterComma));
|
||||||
|
} else {
|
||||||
|
scribe.setTailFormatter(tailFormatter);
|
||||||
|
}
|
||||||
|
scribe.alignFragment(alignment, i);
|
||||||
if (node instanceof ICPPASTConstructorChainInitializer) {
|
if (node instanceof ICPPASTConstructorChainInitializer) {
|
||||||
// this is a special case
|
// Constructor chain initializer is a special case.
|
||||||
visit((ICPPASTConstructorChainInitializer) node);
|
visit((ICPPASTConstructorChainInitializer) node);
|
||||||
} else {
|
} else {
|
||||||
node.accept(this);
|
node.accept(this);
|
||||||
}
|
}
|
||||||
|
if (i < alignment.fragmentCount - 1) {
|
||||||
|
scribe.runTailFormatter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (addEllipsis) {
|
if (addEllipsis) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
scribe.printNextToken(Token.tCOMMA, align.fSpaceBeforeComma);
|
scribe.printNextToken(Token.tCOMMA, options.fSpaceBeforeComma);
|
||||||
scribe.printTrailingComment();
|
scribe.printTrailingComment();
|
||||||
}
|
}
|
||||||
scribe.alignFragment(listAlignment, i);
|
scribe.alignFragment(alignment, i);
|
||||||
if (i > 0 && align.fSpaceAfterComma) {
|
if (i > 0 && options.fSpaceAfterComma) {
|
||||||
scribe.space();
|
scribe.space();
|
||||||
}
|
}
|
||||||
scribe.printNextToken(Token.tELIPSE);
|
scribe.printNextToken(Token.tELIPSE);
|
||||||
}
|
}
|
||||||
|
scribe.runTailFormatter();
|
||||||
ok = true;
|
ok = true;
|
||||||
} catch (AlignmentException e) {
|
} catch (AlignmentException e) {
|
||||||
scribe.redoAlignment(e);
|
scribe.redoAlignment(e);
|
||||||
} catch (ASTProblemException e) {
|
} catch (ASTProblemException e) {
|
||||||
}
|
}
|
||||||
} while (!ok);
|
} while (!ok);
|
||||||
scribe.exitAlignment(listAlignment, true);
|
scribe.exitAlignment(alignment, true);
|
||||||
}
|
} else if (tailFormatter != null) {
|
||||||
if (encloseInParen) {
|
tailFormatter.run();
|
||||||
// handle missing parameter
|
|
||||||
if (peekNextToken() == Token.tIDENTIFIER) {
|
|
||||||
scribe.skipToToken(Token.tRPAREN);
|
|
||||||
}
|
|
||||||
if (elementsLength == 0 && !addEllipsis) {
|
|
||||||
scribe.printNextToken(Token.tRPAREN, align.fSpaceBetweenEmptyParen);
|
|
||||||
} else {
|
|
||||||
scribe.printNextToken(Token.tRPAREN, align.fSpaceBeforeClosingParen);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1958,17 +2064,17 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
if (preferences.insert_space_before_question_in_conditional) {
|
if (preferences.insert_space_before_question_in_conditional) {
|
||||||
scribe.space();
|
scribe.space();
|
||||||
}
|
}
|
||||||
Alignment conditionalExpressionAlignment = scribe.createAlignment(
|
Alignment alignment = scribe.createAlignment(
|
||||||
Alignment.CONDITIONAL_EXPRESSION,
|
Alignment.CONDITIONAL_EXPRESSION,
|
||||||
preferences.alignment_for_conditional_expression,
|
preferences.alignment_for_conditional_expression,
|
||||||
2,
|
2,
|
||||||
scribe.scanner.getCurrentPosition());
|
scribe.scanner.getCurrentPosition());
|
||||||
|
|
||||||
scribe.enterAlignment(conditionalExpressionAlignment);
|
scribe.enterAlignment(alignment);
|
||||||
boolean ok = false;
|
boolean ok = false;
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
scribe.alignFragment(conditionalExpressionAlignment, 0);
|
scribe.alignFragment(alignment, 0);
|
||||||
scribe.printNextToken(Token.tQUESTION, false);
|
scribe.printNextToken(Token.tQUESTION, false);
|
||||||
|
|
||||||
if (preferences.insert_space_after_question_in_conditional) {
|
if (preferences.insert_space_after_question_in_conditional) {
|
||||||
|
@ -1979,7 +2085,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
positiveExpression.accept(this);
|
positiveExpression.accept(this);
|
||||||
}
|
}
|
||||||
scribe.printTrailingComment();
|
scribe.printTrailingComment();
|
||||||
scribe.alignFragment(conditionalExpressionAlignment, 1);
|
scribe.alignFragment(alignment, 1);
|
||||||
scribe.printNextToken(Token.tCOLON, preferences.insert_space_before_colon_in_conditional);
|
scribe.printNextToken(Token.tCOLON, preferences.insert_space_before_colon_in_conditional);
|
||||||
|
|
||||||
if (preferences.insert_space_after_colon_in_conditional) {
|
if (preferences.insert_space_after_colon_in_conditional) {
|
||||||
|
@ -1992,7 +2098,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.redoAlignment(e);
|
scribe.redoAlignment(e);
|
||||||
}
|
}
|
||||||
} while (!ok);
|
} while (!ok);
|
||||||
scribe.exitAlignment(conditionalExpressionAlignment, true);
|
scribe.exitAlignment(alignment, true);
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2023,26 +2129,26 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
expressions= Arrays.asList(args);
|
expressions= Arrays.asList(args);
|
||||||
} else {
|
} else {
|
||||||
// no arguments
|
// No arguments
|
||||||
expressions= Collections.emptyList();
|
expressions= Collections.emptyList();
|
||||||
}
|
}
|
||||||
final ListAlignment align= new ListAlignment(preferences.alignment_for_arguments_in_method_invocation);
|
final ListOptions options= new ListOptions(preferences.alignment_for_arguments_in_method_invocation);
|
||||||
align.fSpaceBeforeOpeningParen= preferences.insert_space_before_opening_paren_in_method_invocation;
|
options.fSpaceBeforeOpeningParen= preferences.insert_space_before_opening_paren_in_method_invocation;
|
||||||
align.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_invocation;
|
options.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_invocation;
|
||||||
align.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_invocation;
|
options.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_invocation;
|
||||||
align.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_invocation;
|
options.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_invocation;
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_method_invocation_arguments;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_method_invocation_arguments;
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_method_invocation_arguments;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_method_invocation_arguments;
|
||||||
align.fTieBreakRule = Alignment.R_OUTERMOST;
|
options.fTieBreakRule = Alignment.R_OUTERMOST;
|
||||||
formatList(expressions, align, true, false);
|
formatList(expressions, options, true, false, scribe.getTailFormatter());
|
||||||
}
|
}
|
||||||
|
|
||||||
private int visit(IASTExpressionList node) {
|
private int visit(IASTExpressionList node) {
|
||||||
final List<IASTExpression> expressions = Arrays.asList(node.getExpressions());
|
final List<IASTExpression> expressions = Arrays.asList(node.getExpressions());
|
||||||
final ListAlignment align= new ListAlignment(preferences.alignment_for_expression_list);
|
final ListOptions options= new ListOptions(preferences.alignment_for_expression_list);
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_expression_list;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_expression_list;
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_expression_list;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_expression_list;
|
||||||
formatList(expressions, align, false, false);
|
formatList(expressions, options, false, false, null);
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2206,16 +2312,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.space();
|
scribe.space();
|
||||||
}
|
}
|
||||||
|
|
||||||
final ListAlignment align= new ListAlignment(preferences.alignment_for_expressions_in_initializer_list);
|
final ListOptions options= new ListOptions(preferences.alignment_for_expressions_in_initializer_list);
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_initializer_list;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_initializer_list;
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_initializer_list;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_initializer_list;
|
||||||
align.fContinuationIndentation= preferences.continuation_indentation_for_initializer_list;
|
options.fContinuationIndentation= preferences.continuation_indentation_for_initializer_list;
|
||||||
formatList(initializers, align, false, false);
|
formatList(initializers, options, false, false, null);
|
||||||
|
|
||||||
// handle trailing comma
|
// handle trailing comma
|
||||||
if (peekNextToken() == Token.tCOMMA) {
|
if (peekNextToken() == Token.tCOMMA) {
|
||||||
scribe.printNextToken(Token.tCOMMA, align.fSpaceBeforeComma);
|
scribe.printNextToken(Token.tCOMMA, options.fSpaceBeforeComma);
|
||||||
if (align.fSpaceAfterComma) {
|
if (options.fSpaceAfterComma) {
|
||||||
scribe.space();
|
scribe.space();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2665,10 +2771,17 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private int visit(IASTExpressionStatement node) {
|
private int visit(IASTExpressionStatement node) {
|
||||||
node.getExpression().accept(this);
|
Runnable semicolonFormatter = null;
|
||||||
|
if (!fInsideFor) {
|
||||||
|
semicolonFormatter = new TrailingSemicolonFormatter(node);
|
||||||
|
scribe.setTailFormatter(semicolonFormatter);
|
||||||
|
}
|
||||||
|
node.getExpression().accept(this);
|
||||||
|
if (semicolonFormatter != null) {
|
||||||
|
semicolonFormatter.run();
|
||||||
|
scribe.setTailFormatter(null);
|
||||||
|
}
|
||||||
if (!fInsideFor) {
|
if (!fInsideFor) {
|
||||||
scribe.printNextToken(Token.tSEMI, preferences.insert_space_before_semicolon);
|
|
||||||
scribe.printTrailingComment();
|
|
||||||
scribe.startNewLine();
|
scribe.startNewLine();
|
||||||
}
|
}
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
|
@ -2896,6 +3009,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.printNextToken(Token.t_else, true);
|
scribe.printNextToken(Token.t_else, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elseStatement instanceof IASTCompoundStatement) {
|
if (elseStatement instanceof IASTCompoundStatement) {
|
||||||
elseStatement.accept(this);
|
elseStatement.accept(this);
|
||||||
} else if (elseStatement instanceof IASTIfStatement) {
|
} else if (elseStatement instanceof IASTIfStatement) {
|
||||||
|
@ -2926,7 +3040,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
scribe.printNextToken(Token.tCOLONCOLON);
|
scribe.printNextToken(Token.tCOLONCOLON);
|
||||||
}
|
}
|
||||||
IASTName[] names= node.getNames();
|
IASTName[] names= node.getNames();
|
||||||
for (int i = 0; i < names.length-1; i++) {
|
for (int i = 0; i < names.length - 1; i++) {
|
||||||
names[i].accept(this);
|
names[i].accept(this);
|
||||||
scribe.printNextToken(Token.tCOLONCOLON);
|
scribe.printNextToken(Token.tCOLONCOLON);
|
||||||
}
|
}
|
||||||
|
@ -2934,7 +3048,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
// destructor
|
// destructor
|
||||||
scribe.printNextToken(Token.tCOMPL, false);
|
scribe.printNextToken(Token.tCOMPL, false);
|
||||||
}
|
}
|
||||||
names[names.length-1].accept(this);
|
names[names.length - 1].accept(this);
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2948,10 +3062,10 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
int angleBrackets = fOpenAngleBrackets++;
|
int angleBrackets = fOpenAngleBrackets++;
|
||||||
final IASTNode[] templateArguments= node.getTemplateArguments();
|
final IASTNode[] templateArguments= node.getTemplateArguments();
|
||||||
if (templateArguments.length > 0) {
|
if (templateArguments.length > 0) {
|
||||||
final ListAlignment align= new ListAlignment(Alignment.M_COMPACT_SPLIT);
|
final ListOptions options= new ListOptions(Alignment.M_COMPACT_SPLIT);
|
||||||
align.fSpaceAfterComma= preferences.insert_space_after_comma_in_template_arguments;
|
options.fSpaceAfterComma= preferences.insert_space_after_comma_in_template_arguments;
|
||||||
align.fSpaceBeforeComma= preferences.insert_space_before_comma_in_template_arguments;
|
options.fSpaceBeforeComma= preferences.insert_space_before_comma_in_template_arguments;
|
||||||
formatList(Arrays.asList(templateArguments), align, false, false);
|
formatList(Arrays.asList(templateArguments), options, false, false, null);
|
||||||
}
|
}
|
||||||
if (peekNextToken() == Token.tSHIFTR) {
|
if (peekNextToken() == Token.tSHIFTR) {
|
||||||
if (fOpenAngleBrackets == angleBrackets + 2) {
|
if (fOpenAngleBrackets == angleBrackets + 2) {
|
||||||
|
@ -3445,7 +3559,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
IASTNodeLocation[] locations= node.getNodeLocations();
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
if (locations.length == 0) {
|
if (locations.length == 0) {
|
||||||
} else if (node instanceof IASTProblemHolder) {
|
} else if (node instanceof IASTProblemHolder) {
|
||||||
} else if (locations[locations.length-1] instanceof IASTMacroExpansionLocation) {
|
} else if (locations[locations.length - 1] instanceof IASTMacroExpansionLocation) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -49,6 +49,9 @@ public class Scribe {
|
||||||
public Alignment currentAlignment;
|
public Alignment currentAlignment;
|
||||||
public Alignment memberAlignment;
|
public Alignment memberAlignment;
|
||||||
public AlignmentException currentAlignmentException;
|
public AlignmentException currentAlignmentException;
|
||||||
|
|
||||||
|
/** @see Alignment#tailFormatter */
|
||||||
|
private Runnable tailFormatter;
|
||||||
|
|
||||||
public Token currentToken;
|
public Token currentToken;
|
||||||
|
|
||||||
|
@ -869,7 +872,7 @@ public class Scribe {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void print(int length, boolean considerSpaceIfAny) {
|
private void print(int length, boolean considerSpaceIfAny) {
|
||||||
if (checkLineWrapping && length + column > pageWidth) {
|
if (checkLineWrapping && length + column - 1 > pageWidth) {
|
||||||
handleLineTooLong();
|
handleLineTooLong();
|
||||||
}
|
}
|
||||||
lastNumberOfNewLines= 0;
|
lastNumberOfNewLines= 0;
|
||||||
|
@ -882,6 +885,9 @@ public class Scribe {
|
||||||
if (pendingSpace) {
|
if (pendingSpace) {
|
||||||
addInsertEdit(scanner.getCurrentTokenStartPosition(), SPACE);
|
addInsertEdit(scanner.getCurrentTokenStartPosition(), SPACE);
|
||||||
}
|
}
|
||||||
|
if (checkLineWrapping && length + column - 1 > pageWidth) {
|
||||||
|
handleLineTooLong();
|
||||||
|
}
|
||||||
pendingSpace= false;
|
pendingSpace= false;
|
||||||
column += length;
|
column += length;
|
||||||
needSpace= true;
|
needSpace= true;
|
||||||
|
@ -1544,7 +1550,7 @@ public class Scribe {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printNewLine() {
|
public void printNewLine() {
|
||||||
printNewLine(scanner.getCurrentTokenEndPosition() + 1);
|
printNewLine(scanner.getCurrentPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printNewLine(int insertPosition) {
|
public void printNewLine(int insertPosition) {
|
||||||
|
@ -1950,7 +1956,7 @@ public class Scribe {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skip to the next occurrence of the given token type.
|
* Skips to the next occurrence of the given token type.
|
||||||
* If successful, the next token will be the expected token,
|
* If successful, the next token will be the expected token,
|
||||||
* otherwise the scanner position is left unchanged.
|
* otherwise the scanner position is left unchanged.
|
||||||
*
|
*
|
||||||
|
@ -1962,56 +1968,96 @@ public class Scribe {
|
||||||
if (shouldSkip(skipStart)) {
|
if (shouldSkip(skipStart)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int braceLevel= 0;
|
int tokenStart = findToken(expectedTokenType);
|
||||||
int parenLevel= 0;
|
if (tokenStart < 0) {
|
||||||
switch (expectedTokenType) {
|
return false;
|
||||||
case Token.tRBRACE:
|
|
||||||
++braceLevel;
|
|
||||||
break;
|
|
||||||
case Token.tRPAREN:
|
|
||||||
++parenLevel;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
while ((currentToken= scanner.nextToken()) != null) {
|
printRaw(skipStart, tokenStart - skipStart);
|
||||||
switch (currentToken.type) {
|
currentToken= scanner.nextToken();
|
||||||
case Token.tLBRACE:
|
scanner.resetTo(tokenStart, scannerEndPosition - 1);
|
||||||
if (expectedTokenType != Token.tLBRACE) {
|
return true;
|
||||||
++braceLevel;
|
}
|
||||||
}
|
|
||||||
break;
|
/**
|
||||||
|
* Searches for the next occurrence of the given token type.
|
||||||
|
* If successful, returns the offset of the found token, otherwise -1.
|
||||||
|
* The scanner position is left unchanged.
|
||||||
|
*
|
||||||
|
* @param tokenType type of the token to look for
|
||||||
|
* @return <code>true</code> if a matching token was found
|
||||||
|
*/
|
||||||
|
public int findToken(int tokenType) {
|
||||||
|
return findToken(tokenType, scannerEndPosition - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for the next occurrence of the given token type.
|
||||||
|
* If successful, returns the offset of the found token, otherwise -1.
|
||||||
|
* The scanner position is left unchanged.
|
||||||
|
*
|
||||||
|
* @param tokenType type of the token to look for
|
||||||
|
* @param endPosition end position limiting the search
|
||||||
|
* @return <code>true</code> if a matching token was found
|
||||||
|
*/
|
||||||
|
public int findToken(int tokenType, int endPosition) {
|
||||||
|
int startPosition= scanner.getCurrentPosition();
|
||||||
|
if (startPosition >= endPosition) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int braceLevel= 0;
|
||||||
|
int parenLevel= 0;
|
||||||
|
switch (tokenType) {
|
||||||
case Token.tRBRACE:
|
case Token.tRBRACE:
|
||||||
--braceLevel;
|
++braceLevel;
|
||||||
break;
|
|
||||||
case Token.tLPAREN:
|
|
||||||
if (expectedTokenType != Token.tLPAREN) {
|
|
||||||
++parenLevel;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case Token.tRPAREN:
|
case Token.tRPAREN:
|
||||||
--parenLevel;
|
++parenLevel;
|
||||||
break;
|
break;
|
||||||
case Token.tWHITESPACE:
|
|
||||||
case Token.tLINECOMMENT:
|
|
||||||
case Token.tBLOCKCOMMENT:
|
|
||||||
case Token.tPREPROCESSOR:
|
|
||||||
case Token.tPREPROCESSOR_DEFINE:
|
|
||||||
case Token.tPREPROCESSOR_INCLUDE:
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (braceLevel <= 0 && parenLevel <= 0) {
|
Token token;
|
||||||
if (currentToken.type == expectedTokenType) {
|
while ((token= scanner.nextToken()) != null) {
|
||||||
int tokenStart= scanner.getCurrentTokenStartPosition();
|
if (scanner.getCurrentTokenEndPosition() > endPosition)
|
||||||
printRaw(skipStart, tokenStart - skipStart);
|
return -1;
|
||||||
scanner.resetTo(tokenStart, scannerEndPosition - 1);
|
|
||||||
return true;
|
switch (token.type) {
|
||||||
|
case Token.tLBRACE:
|
||||||
|
if (tokenType != Token.tLBRACE) {
|
||||||
|
++braceLevel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Token.tRBRACE:
|
||||||
|
--braceLevel;
|
||||||
|
break;
|
||||||
|
case Token.tLPAREN:
|
||||||
|
if (tokenType != Token.tLPAREN) {
|
||||||
|
++parenLevel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Token.tRPAREN:
|
||||||
|
--parenLevel;
|
||||||
|
break;
|
||||||
|
case Token.tWHITESPACE:
|
||||||
|
case Token.tLINECOMMENT:
|
||||||
|
case Token.tBLOCKCOMMENT:
|
||||||
|
case Token.tPREPROCESSOR:
|
||||||
|
case Token.tPREPROCESSOR_DEFINE:
|
||||||
|
case Token.tPREPROCESSOR_INCLUDE:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (braceLevel <= 0 && parenLevel <= 0) {
|
||||||
|
if (token.type == tokenType) {
|
||||||
|
return scanner.getCurrentTokenStartPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (braceLevel < 0 || parenLevel < 0) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (braceLevel < 0 || parenLevel < 0) {
|
} finally {
|
||||||
break;
|
scanner.resetTo(startPosition, scannerEndPosition - 1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
scanner.resetTo(skipStart, scannerEndPosition - 1);
|
return -1;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean printCommentPreservingNewLines() {
|
public boolean printCommentPreservingNewLines() {
|
||||||
|
@ -2073,4 +2119,41 @@ public class Scribe {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the tail formatter associated with the current alignment or, if there is no current
|
||||||
|
* alignment, with the Scribe itself.
|
||||||
|
* @see #tailFormatter
|
||||||
|
*/
|
||||||
|
public Runnable getTailFormatter() {
|
||||||
|
if (currentAlignment != null) {
|
||||||
|
return currentAlignment.tailFormatter;
|
||||||
|
} else {
|
||||||
|
return this.tailFormatter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets the tail formatter associated with the current alignment or, if there is no current
|
||||||
|
* alignment, with the Scribe itself.
|
||||||
|
* @see #tailFormatter
|
||||||
|
*/
|
||||||
|
public void setTailFormatter(Runnable tailFormatter) {
|
||||||
|
if (currentAlignment != null) {
|
||||||
|
currentAlignment.tailFormatter = tailFormatter;
|
||||||
|
} else {
|
||||||
|
this.tailFormatter = tailFormatter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Runs the tail formatter associated with the current alignment or, if there is no current
|
||||||
|
* alignment, with the Scribe itself.
|
||||||
|
* @see #tailFormatter
|
||||||
|
*/
|
||||||
|
public void runTailFormatter() {
|
||||||
|
Runnable formatter = getTailFormatter();
|
||||||
|
if (formatter != null)
|
||||||
|
formatter.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,26 +33,32 @@ public class Alignment {
|
||||||
public static final String MACRO_ARGUMENTS = "macroArguments"; //$NON-NLS-1$
|
public static final String MACRO_ARGUMENTS = "macroArguments"; //$NON-NLS-1$
|
||||||
public static final String LIST_ELEMENTS_PREFIX = "listElements_"; //$NON-NLS-1$
|
public static final String LIST_ELEMENTS_PREFIX = "listElements_"; //$NON-NLS-1$
|
||||||
|
|
||||||
// name of alignment
|
/** The name of the alignment */
|
||||||
public String name;
|
public String name;
|
||||||
|
|
||||||
// link to enclosing alignment
|
/** Link to the enclosing alignment. */
|
||||||
public Alignment enclosing;
|
public Alignment enclosing;
|
||||||
|
|
||||||
// start location of this alignment
|
/** Start location of this alignment. */
|
||||||
public Location location;
|
public Location location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tail formatter is an encapsulation mechanism for formatting of the trailing text that should
|
||||||
|
* be kept together with the last element of a list.
|
||||||
|
*/
|
||||||
|
public Runnable tailFormatter;
|
||||||
|
|
||||||
// indentation management
|
// Indentation management
|
||||||
public int fragmentIndex;
|
public int fragmentIndex;
|
||||||
public int fragmentCount;
|
public int fragmentCount;
|
||||||
public int[] fragmentIndentations;
|
public int[] fragmentIndentations;
|
||||||
public boolean needRedoColumnAlignment;
|
public boolean needRedoColumnAlignment;
|
||||||
|
|
||||||
// chunk management
|
// Chunk management
|
||||||
public int chunkStartIndex;
|
public int chunkStartIndex;
|
||||||
public int chunkKind;
|
public int chunkKind;
|
||||||
|
|
||||||
// break management
|
// Break management
|
||||||
public int originalIndentationLevel;
|
public int originalIndentationLevel;
|
||||||
public int breakIndentationLevel;
|
public int breakIndentationLevel;
|
||||||
public int shiftBreakIndentationLevel;
|
public int shiftBreakIndentationLevel;
|
||||||
|
@ -68,7 +74,7 @@ public class Alignment {
|
||||||
public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level)
|
public static final int M_INDENT_ON_COLUMN = 2; // if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level)
|
||||||
public static final int M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation)
|
public static final int M_INDENT_BY_ONE = 4; // if bit set, broken fragments will be indented one level below current (not using continuation indentation)
|
||||||
|
|
||||||
// split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN
|
// Split modes can be combined either with M_FORCE or M_INDENT_ON_COLUMN
|
||||||
|
|
||||||
/** foobar(#fragment1, #fragment2, <ul>
|
/** foobar(#fragment1, #fragment2, <ul>
|
||||||
* <li> #fragment3, #fragment4 </li>
|
* <li> #fragment3, #fragment4 </li>
|
||||||
|
@ -113,7 +119,7 @@ public class Alignment {
|
||||||
//64+32
|
//64+32
|
||||||
//64+32+16
|
//64+32+16
|
||||||
|
|
||||||
// mode controlling column alignments
|
// Mode controlling column alignments
|
||||||
/**
|
/**
|
||||||
* <table BORDER COLS=4 WIDTH="100%" >
|
* <table BORDER COLS=4 WIDTH="100%" >
|
||||||
* <tr><td>#fragment1A</td> <td>#fragment2A</td> <td>#fragment3A</td> <td>#very-long-fragment4A</td></tr>
|
* <tr><td>#fragment1A</td> <td>#fragment2A</td> <td>#fragment3A</td> <td>#very-long-fragment4A</td></tr>
|
||||||
|
@ -129,23 +135,24 @@ public class Alignment {
|
||||||
|
|
||||||
public static final int SPLIT_MASK = M_ONE_PER_LINE_SPLIT | M_NEXT_SHIFTED_SPLIT | M_COMPACT_SPLIT | M_COMPACT_FIRST_BREAK_SPLIT | M_NEXT_PER_LINE_SPLIT;
|
public static final int SPLIT_MASK = M_ONE_PER_LINE_SPLIT | M_NEXT_SHIFTED_SPLIT | M_COMPACT_SPLIT | M_COMPACT_FIRST_BREAK_SPLIT | M_NEXT_PER_LINE_SPLIT;
|
||||||
|
|
||||||
// alignment tie-break rules - when split is needed, will decide whether innermost/outermost alignment is to be chosen
|
// Alignment tie-break rules - when split is needed, will decide whether innermost/outermost alignment is to be chosen
|
||||||
public static final int R_OUTERMOST = 1;
|
public static final int R_OUTERMOST = 1;
|
||||||
public static final int R_INNERMOST = 2;
|
public static final int R_INNERMOST = 2;
|
||||||
public int tieBreakRule;
|
public int tieBreakRule;
|
||||||
|
|
||||||
// alignment effects on a per fragment basis
|
// Alignment effects on a per fragment basis
|
||||||
public static int NONE = 0;
|
public static int NONE = 0;
|
||||||
public static int BREAK = 1;
|
public static int BREAK = 1;
|
||||||
|
|
||||||
// chunk kind
|
// Chunk kind
|
||||||
public static final int CHUNK_FIELD = 1;
|
public static final int CHUNK_FIELD = 1;
|
||||||
public static final int CHUNK_METHOD = 2;
|
public static final int CHUNK_METHOD = 2;
|
||||||
public static final int CHUNK_TYPE = 3;
|
public static final int CHUNK_TYPE = 3;
|
||||||
public static final int CHUNK_ENUM = 4;
|
public static final int CHUNK_ENUM = 4;
|
||||||
|
|
||||||
// location to align and break on.
|
// Location to align and break on.
|
||||||
public Alignment(String name, int mode, int tieBreakRule, Scribe scribe, int fragmentCount, int sourceRestart, int continuationIndent) {
|
public Alignment(String name, int mode, int tieBreakRule, Scribe scribe, int fragmentCount,
|
||||||
|
int sourceRestart, int continuationIndent) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.location = new Location(scribe, sourceRestart);
|
this.location = new Location(scribe, sourceRestart);
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
|
|
|
@ -44,8 +44,8 @@ int foo(int bar) const {
|
||||||
/*
|
/*
|
||||||
* Line Wrapping
|
* Line Wrapping
|
||||||
*/
|
*/
|
||||||
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
|
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 1000,
|
||||||
1000, 2000, 3000, 4000, 5000 };
|
2000, 3000, 4000, 5000 };
|
||||||
int compare(int argument, int otherArg) {
|
int compare(int argument, int otherArg) {
|
||||||
return argument + otherArg > argument * otherArg + 1000000 ? 100000 + 50000
|
return argument + otherArg > argument * otherArg + 1000000 ? 100000 + 50000
|
||||||
: 200000 - 30000;
|
: 200000 - 30000;
|
||||||
|
|
|
@ -953,6 +953,59 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
assertFormatterResult();
|
assertFormatterResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void f1(const char* long_parameter_name, int very_looooooooooong_parameter_name, int another_parameter_name );
|
||||||
|
//void f2(const char* long_parameter_name,int very_loooooooooooong_parameter_name, int another_parameter_name ) ;
|
||||||
|
//void f3(const char* long_parameter_name,int very_loooooooooooong_parameter_name,int very_loong_parameter_name) ;
|
||||||
|
//void f4(const char* long_parameter_name, int very_loooooooooooong_parameter_name,int very_looong_parameter_name) ;
|
||||||
|
|
||||||
|
//void f1(const char* long_parameter_name, int very_looooooooooong_parameter_name,
|
||||||
|
// int another_parameter_name);
|
||||||
|
//void f2(const char* long_parameter_name,
|
||||||
|
// int very_loooooooooooong_parameter_name, int another_parameter_name);
|
||||||
|
//void f3(const char* long_parameter_name,
|
||||||
|
// int very_loooooooooooong_parameter_name, int very_loong_parameter_name);
|
||||||
|
//void f4(const char* long_parameter_name,
|
||||||
|
// int very_loooooooooooong_parameter_name,
|
||||||
|
// int very_looong_parameter_name);
|
||||||
|
public void testFunctionDeclaration() throws Exception {
|
||||||
|
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE);
|
||||||
|
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
|
||||||
|
Integer.toString(Alignment.M_NEXT_PER_LINE_SPLIT | Alignment.M_INDENT_ON_COLUMN));
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
//int f1(int a, int b, int c, int d, int e, int f, int g);
|
||||||
|
//int f2(int a, int b, int c, int d, int e, int f, int g);
|
||||||
|
//
|
||||||
|
//void test() {
|
||||||
|
//f1(100000000,200000000,300000000,400000000,500000000,600000000,70000);
|
||||||
|
//f1(100000000,200000000,300000000,400000000,500000000,600000000,700000);
|
||||||
|
//f1(100000,200000,300000,400000,500000,600000,f2(1,2,3,4,5,6,7));
|
||||||
|
//f1(100000,200000,300000,400000,500000,600000,f2(1,2,3,4,5,6,70));
|
||||||
|
//f1(100000,200000,300000,400000,500000,f2(10,20,30,40,50,60,7000),700000);
|
||||||
|
//f1(100000,200000,300000,400000,500000,f2(10,20,30,40,50,60,70000),700000);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//int f1(int a, int b, int c, int d, int e, int f, int g);
|
||||||
|
//int f2(int a, int b, int c, int d, int e, int f, int g);
|
||||||
|
//
|
||||||
|
//void test() {
|
||||||
|
// f1(100000000, 200000000, 300000000, 400000000, 500000000, 600000000, 70000);
|
||||||
|
// f1(100000000, 200000000, 300000000, 400000000, 500000000, 600000000,
|
||||||
|
// 700000);
|
||||||
|
// f1(100000, 200000, 300000, 400000, 500000, 600000, f2(1, 2, 3, 4, 5, 6, 7));
|
||||||
|
// f1(100000, 200000, 300000, 400000, 500000, 600000,
|
||||||
|
// f2(1, 2, 3, 4, 5, 6, 70));
|
||||||
|
// f1(100000, 200000, 300000, 400000, 500000, f2(10, 20, 30, 40, 50, 60, 7000),
|
||||||
|
// 700000);
|
||||||
|
// f1(100000, 200000, 300000, 400000, 500000,
|
||||||
|
// f2(10, 20, 30, 40, 50, 60, 70000), 700000);
|
||||||
|
//}
|
||||||
|
public void testFunctionCall() throws Exception {
|
||||||
|
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE);
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
//#define MY_MACRO int a; \
|
//#define MY_MACRO int a; \
|
||||||
// int b; \
|
// int b; \
|
||||||
// int c();
|
// int c();
|
||||||
|
|
Loading…
Add table
Reference in a new issue