mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
Bug 397496 - Formatter does not wrap long macro arguments
This commit is contained in:
parent
fdbafed3f3
commit
e2a18cf6c2
3 changed files with 208 additions and 133 deletions
|
@ -418,6 +418,14 @@ public class MacroExpander {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addImageLocationInfo(int offset, Token t) {
|
||||||
|
ImageLocationInfo info= createImageLocationInfo(t);
|
||||||
|
if (info != null) {
|
||||||
|
info.fTokenOffsetInExpansion= offset;
|
||||||
|
fImageLocationInfos.add(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ImageLocationInfo createImageLocationInfo(Token t) {
|
private ImageLocationInfo createImageLocationInfo(Token t) {
|
||||||
if (fLocationMap != null) {
|
if (fLocationMap != null) {
|
||||||
final Object s= t.fSource;
|
final Object s= t.fSource;
|
||||||
|
@ -950,20 +958,12 @@ public class MacroExpander {
|
||||||
case CPreprocessor.tEXPANDED_IDENTIFIER:
|
case CPreprocessor.tEXPANDED_IDENTIFIER:
|
||||||
t.setType(IToken.tIDENTIFIER);
|
t.setType(IToken.tIDENTIFIER);
|
||||||
if (createImageLocations) {
|
if (createImageLocations) {
|
||||||
ImageLocationInfo info= createImageLocationInfo(t);
|
addImageLocationInfo(offset, t);
|
||||||
if (info != null) {
|
|
||||||
info.fTokenOffsetInExpansion= offset;
|
|
||||||
fImageLocationInfos.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IToken.tIDENTIFIER:
|
case IToken.tIDENTIFIER:
|
||||||
if (createImageLocations) {
|
if (createImageLocations) {
|
||||||
ImageLocationInfo info= createImageLocationInfo(t);
|
addImageLocationInfo(offset, t);
|
||||||
if (info != null) {
|
|
||||||
info.fTokenOffsetInExpansion= offset;
|
|
||||||
fImageLocationInfos.add(info);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -978,6 +978,12 @@ public class MacroExpander {
|
||||||
t.setOffset(offset, offset + t.getLength());
|
t.setOffset(offset, offset + t.getLength());
|
||||||
t.setNext(null);
|
t.setNext(null);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (createImageLocations && t.fSource instanceof CPreprocessor) {
|
||||||
|
addImageLocationInfo(offset, t);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
t.setOffset(offset, ++offset);
|
t.setOffset(offset, ++offset);
|
||||||
l= t;
|
l= t;
|
||||||
|
|
|
@ -66,6 +66,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
|
@ -143,6 +144,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
||||||
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
|
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
|
||||||
|
@ -232,6 +234,28 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class TokenRange {
|
||||||
|
private int offset;
|
||||||
|
private int endOffset;
|
||||||
|
|
||||||
|
TokenRange(int offset, int endOffset) {
|
||||||
|
this.offset = offset;
|
||||||
|
this.endOffset = endOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getEndOffset() {
|
||||||
|
return endOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getLength() {
|
||||||
|
return endOffset - offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a trailing semicolon.
|
* Formats a trailing semicolon.
|
||||||
* @see #formatList(List, ListOptions, boolean, boolean, Runnable)
|
* @see #formatList(List, ListOptions, boolean, boolean, Runnable)
|
||||||
|
@ -360,6 +384,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
private final Scribe scribe;
|
private final Scribe scribe;
|
||||||
|
|
||||||
private boolean fInsideFor;
|
private boolean fInsideFor;
|
||||||
|
private boolean fInsideMacroArguments;
|
||||||
private boolean fExpectSemicolonAfterDeclaration= true;
|
private boolean fExpectSemicolonAfterDeclaration= true;
|
||||||
|
|
||||||
private MultiStatus fStatus;
|
private MultiStatus fStatus;
|
||||||
|
@ -540,97 +565,79 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
if (fileLocation != null) {
|
if (fileLocation != null) {
|
||||||
scribe.printRaw(fileLocation.getNodeOffset(), fileLocation.getNodeLength());
|
scribe.printRaw(fileLocation.getNodeOffset(), fileLocation.getNodeLength());
|
||||||
}
|
}
|
||||||
fileLocation = macroExpansion.getFileLocation();
|
|
||||||
scribe.printNextToken(Token.tLPAREN);
|
|
||||||
IMacroBinding binding = (IMacroBinding) name.resolveBinding();
|
IMacroBinding binding = (IMacroBinding) name.resolveBinding();
|
||||||
if (preferences.insert_space_after_opening_paren_in_method_invocation) {
|
List<Object> arguments = getMacroArguments(binding.getParameterList().length);
|
||||||
scribe.space();
|
|
||||||
|
final ListOptions options= new ListOptions(preferences.alignment_for_arguments_in_method_invocation);
|
||||||
|
options.fSeparatorToken = Token.tCOMMA;
|
||||||
|
options.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_invocation;
|
||||||
|
options.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_invocation;
|
||||||
|
options.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_invocation;
|
||||||
|
options.fSpaceBeforeSeparator= preferences.insert_space_before_comma_in_method_invocation_arguments;
|
||||||
|
options.fSpaceAfterSeparator= preferences.insert_space_after_comma_in_method_invocation_arguments;
|
||||||
|
options.fTieBreakRule = Alignment.R_OUTERMOST;
|
||||||
|
fInsideMacroArguments = true;
|
||||||
|
try {
|
||||||
|
formatList(arguments, options, true, false, scribe.takeTailFormatter());
|
||||||
|
} finally {
|
||||||
|
fInsideMacroArguments = false;
|
||||||
}
|
}
|
||||||
final int continuationIndentation = preferences.continuation_indentation;
|
}
|
||||||
Alignment listAlignment = scribe.createAlignment(
|
|
||||||
Alignment.MACRO_ARGUMENTS,
|
/**
|
||||||
preferences.alignment_for_arguments_in_method_invocation,
|
* Scans macro expansion arguments starting from the current position and returns a list of
|
||||||
Alignment.R_OUTERMOST,
|
* arguments where each argument is represented either by a {@link IASTNode} or, if not
|
||||||
binding.getParameterList().length,
|
* possible, by a {@link TokenRange}.
|
||||||
getCurrentPosition(),
|
*/
|
||||||
continuationIndentation,
|
private List<Object> getMacroArguments(int expectedNumberOfArguments) {
|
||||||
false);
|
List<TokenRange> argumentRanges = new ArrayList<TokenRange>(expectedNumberOfArguments);
|
||||||
scribe.enterAlignment(listAlignment);
|
TokenRange currentArgument = null;
|
||||||
boolean ok = false;
|
localScanner.resetTo(getCurrentPosition(), scribe.scannerEndPosition);
|
||||||
do {
|
localScanner.getNextToken(); // Skip the opening parenthesis.
|
||||||
try {
|
int parenLevel = 0;
|
||||||
int fragment = 0;
|
int token;
|
||||||
scribe.alignFragment(listAlignment, fragment);
|
while ((token = localScanner.getNextToken()) != Token.tBADCHAR) {
|
||||||
int parenLevel= 0;
|
int tokenOffset = localScanner.getCurrentTokenStartPosition();
|
||||||
boolean done = false;
|
if (parenLevel == 0 && (token == Token.tCOMMA || token == Token.tRPAREN)) {
|
||||||
while (!done) {
|
if (currentArgument != null) {
|
||||||
boolean hasWhitespace= scribe.printComment();
|
argumentRanges.add(currentArgument);
|
||||||
int token = peekNextToken();
|
currentArgument = null;
|
||||||
switch (token) {
|
} else {
|
||||||
case Token.tLPAREN:
|
argumentRanges.add(new TokenRange(tokenOffset, tokenOffset));
|
||||||
++parenLevel;
|
|
||||||
scribe.printNextToken(token, hasWhitespace);
|
|
||||||
break;
|
|
||||||
case Token.tRPAREN:
|
|
||||||
if (parenLevel > 0) {
|
|
||||||
--parenLevel;
|
|
||||||
scribe.printNextToken(token, hasWhitespace);
|
|
||||||
} else {
|
|
||||||
if (preferences.insert_space_before_closing_paren_in_method_invocation) {
|
|
||||||
scribe.space();
|
|
||||||
}
|
|
||||||
scribe.printNextToken(token);
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Token.tCOMMA:
|
|
||||||
if (parenLevel == 0 && preferences.insert_space_before_comma_in_method_invocation_arguments) {
|
|
||||||
scribe.space();
|
|
||||||
}
|
|
||||||
scribe.printNextToken(token);
|
|
||||||
if (parenLevel == 0) {
|
|
||||||
if (preferences.insert_space_after_comma_in_method_invocation_arguments) {
|
|
||||||
scribe.space();
|
|
||||||
}
|
|
||||||
scribe.printComment();
|
|
||||||
++fragment;
|
|
||||||
if (fragment < listAlignment.fragmentCount) {
|
|
||||||
scribe.alignFragment(listAlignment, fragment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Token.tSTRING:
|
|
||||||
case Token.tLSTRING:
|
|
||||||
case Token.tRSTRING:
|
|
||||||
boolean needSpace= hasWhitespace;
|
|
||||||
while (true) {
|
|
||||||
scribe.printNextToken(token, needSpace);
|
|
||||||
if (peekNextToken() != token) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
scribe.printCommentPreservingNewLines();
|
|
||||||
needSpace= true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Token.tBADCHAR:
|
|
||||||
// Avoid infinite loop if something bad happened.
|
|
||||||
scribe.exitAlignment(listAlignment, true);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
scribe.printNextToken(token, hasWhitespace);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int token = peekNextToken();
|
if (token == Token.tRPAREN)
|
||||||
if (token == Token.tSEMI) {
|
break;
|
||||||
scribe.printNextToken(token);
|
} else {
|
||||||
scribe.startNewLine();
|
int tokenEndOffset = localScanner.getCurrentPosition();
|
||||||
|
if (currentArgument == null) {
|
||||||
|
currentArgument = new TokenRange(tokenOffset, tokenEndOffset);
|
||||||
|
} else {
|
||||||
|
currentArgument.endOffset = tokenEndOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (token) {
|
||||||
|
case Token.tLPAREN:
|
||||||
|
++parenLevel;
|
||||||
|
break;
|
||||||
|
case Token.tRPAREN:
|
||||||
|
if (parenLevel > 0)
|
||||||
|
--parenLevel;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ok = true;
|
|
||||||
} catch (AlignmentException e) {
|
|
||||||
scribe.redoAlignment(e);
|
|
||||||
}
|
}
|
||||||
} while (!ok);
|
}
|
||||||
scribe.exitAlignment(listAlignment, true);
|
|
||||||
|
List<Object> arguments = new ArrayList<Object>(argumentRanges.size());
|
||||||
|
IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
|
||||||
|
for (TokenRange argument : argumentRanges) {
|
||||||
|
IASTNode node = nodeSelector.findNodeInExpansion(argument.getOffset(), argument.getLength());
|
||||||
|
if (node != null) {
|
||||||
|
arguments.add(node);
|
||||||
|
} else {
|
||||||
|
arguments.add(argument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2077,15 +2084,16 @@ 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 the elements to format
|
* @param elements the elements to format, which can be either {@link IASTNode}s or
|
||||||
|
* {@link TokenRange}s.
|
||||||
* @param options formatting options
|
* @param options formatting options
|
||||||
* @param encloseInParen indicates whether the list should be enclosed in parentheses
|
* @param encloseInParen indicates whether the list should be enclosed in parentheses
|
||||||
* @param addEllipsis indicates whether ellipsis should be added after the last element
|
* @param addEllipsis indicates whether ellipsis should be added after the last element
|
||||||
* @param tailFormatter formatter for the trailing text that should be kept together with
|
* @param tailFormatter formatter for the trailing text that should be kept together with
|
||||||
* the last element of the list.
|
* the last element of the list.
|
||||||
*/
|
*/
|
||||||
private void formatList(List<? extends IASTNode> elements, ListOptions options,
|
private void formatList(List<?> elements, ListOptions options, boolean encloseInParen,
|
||||||
boolean encloseInParen, boolean addEllipsis, Runnable tailFormatter) {
|
boolean addEllipsis, Runnable tailFormatter) {
|
||||||
if (encloseInParen)
|
if (encloseInParen)
|
||||||
scribe.printNextToken(Token.tLPAREN, options.fSpaceBeforeOpeningParen);
|
scribe.printNextToken(Token.tLPAREN, options.fSpaceBeforeOpeningParen);
|
||||||
|
|
||||||
|
@ -2118,22 +2126,26 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
try {
|
try {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < elementsLength; i++) {
|
for (i = 0; i < elementsLength; i++) {
|
||||||
final IASTNode node= elements.get(i);
|
final Object element = elements.get(i);
|
||||||
if (i < elementsLength - 1) {
|
if (i < elementsLength - 1) {
|
||||||
scribe.setTailFormatter(
|
scribe.setTailFormatter(
|
||||||
new TrailingTokenFormatter(options.fSeparatorToken,
|
new TrailingTokenFormatter(options.fSeparatorToken,
|
||||||
findTokenAfterNode(options.fSeparatorToken, node),
|
findTokenAfterNodeOrTokenRange(options.fSeparatorToken, element),
|
||||||
options.fSpaceBeforeSeparator,
|
options.fSpaceBeforeSeparator,
|
||||||
options.fSpaceAfterSeparator));
|
options.fSpaceAfterSeparator));
|
||||||
} else {
|
} else {
|
||||||
scribe.setTailFormatter(tailFormatter);
|
scribe.setTailFormatter(tailFormatter);
|
||||||
}
|
}
|
||||||
scribe.alignFragment(alignment, i);
|
scribe.alignFragment(alignment, i);
|
||||||
if (node instanceof ICPPASTConstructorChainInitializer) {
|
if (element instanceof IASTNode) {
|
||||||
// Constructor chain initializer is a special case.
|
if (element instanceof ICPPASTConstructorChainInitializer) {
|
||||||
visit((ICPPASTConstructorChainInitializer) node);
|
// Constructor chain initializer is a special case.
|
||||||
|
visit((ICPPASTConstructorChainInitializer) element);
|
||||||
|
} else {
|
||||||
|
((IASTNode) element).accept(this);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
node.accept(this);
|
formatTokenRange((TokenRange) element);
|
||||||
}
|
}
|
||||||
if (i < elementsLength - 1) {
|
if (i < elementsLength - 1) {
|
||||||
scribe.runTailFormatter();
|
scribe.runTailFormatter();
|
||||||
|
@ -2163,6 +2175,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void formatTokenRange(TokenRange tokenRange) {
|
||||||
|
scribe.restartAtOffset(tokenRange.getOffset());
|
||||||
|
while (getCurrentPosition() < tokenRange.getEndOffset()) {
|
||||||
|
boolean hasWhitespace= scribe.printComment();
|
||||||
|
int token = peekNextToken();
|
||||||
|
scribe.printNextToken(token, hasWhitespace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int visit(ICPPASTTryBlockStatement node) {
|
private int visit(ICPPASTTryBlockStatement node) {
|
||||||
scribe.printNextToken(Token.t_try, scribe.printComment());
|
scribe.printNextToken(Token.t_try, scribe.printComment());
|
||||||
final IASTStatement tryBody= node.getTryBody();
|
final IASTStatement tryBody= node.getTryBody();
|
||||||
|
@ -3782,18 +3803,23 @@ 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 (locations[0] instanceof IASTMacroExpansionLocation) {
|
} else if (!fInsideMacroArguments && locations[0] instanceof IASTMacroExpansionLocation) {
|
||||||
IASTMacroExpansionLocation location = (IASTMacroExpansionLocation) locations[0];
|
IASTMacroExpansionLocation location = (IASTMacroExpansionLocation) locations[0];
|
||||||
if (locations.length <= 2 && node instanceof IASTStatement) {
|
if (locations.length <= 2 && node instanceof IASTStatement) {
|
||||||
IASTPreprocessorMacroExpansion macroExpansion = location.getExpansion();
|
IASTPreprocessorMacroExpansion macroExpansion = location.getExpansion();
|
||||||
IASTFileLocation macroLocation = macroExpansion.getFileLocation();
|
IASTFileLocation macroLocation = macroExpansion.getFileLocation();
|
||||||
IASTFileLocation nodeLocation = node.getFileLocation();
|
IASTFileLocation nodeLocation = getFileLocation(node);
|
||||||
if (macroLocation.getNodeOffset() >= getCurrentPosition() &&
|
if (macroLocation.getNodeOffset() >= getCurrentPosition() &&
|
||||||
!scribe.shouldSkip(macroLocation.getNodeOffset()) &&
|
!scribe.shouldSkip(macroLocation.getNodeOffset()) &&
|
||||||
(nodeLocation.getNodeOffset() + nodeLocation.getNodeLength() ==
|
(nodeLocation.getNodeOffset() + nodeLocation.getNodeLength() ==
|
||||||
macroLocation.getNodeOffset() + macroLocation.getNodeLength() ||
|
macroLocation.getNodeOffset() + macroLocation.getNodeLength() ||
|
||||||
locations.length == 2 && isSemicolonLocation(locations[1])) &&
|
locations.length == 2 && isSemicolonLocation(locations[1])) &&
|
||||||
isFunctionStyleMacroExpansion(macroExpansion)) {
|
isFunctionStyleMacroExpansion(macroExpansion)) {
|
||||||
|
if (locations.length == 2 && isSemicolonLocation(locations[1])) {
|
||||||
|
scribe.setTailFormatter(
|
||||||
|
new TrailingTokenFormatter(Token.tSEMI, locations[1].getNodeOffset(),
|
||||||
|
preferences.insert_space_before_semicolon, false));
|
||||||
|
}
|
||||||
formatFunctionStyleMacroExpansion(macroExpansion);
|
formatFunctionStyleMacroExpansion(macroExpansion);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3808,12 +3834,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IASTFileLocation fileLocation= node.getFileLocation();
|
IASTFileLocation fileLocation= getFileLocation(node);
|
||||||
scribe.restartAtOffset(fileLocation.getNodeOffset());
|
scribe.restartAtOffset(fileLocation.getNodeOffset());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IASTFileLocation getFileLocation(IASTNode node) {
|
||||||
|
return fInsideMacroArguments ? ((ASTNode) node).getImageLocation() : node.getFileLocation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formatting of node is complete. Undo skip region if any.
|
* Formatting of node is complete. Undo skip region if any.
|
||||||
*
|
*
|
||||||
|
@ -3824,7 +3854,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (scribe.skipRange()) {
|
if (scribe.skipRange()) {
|
||||||
IASTFileLocation fileLocation= node.getFileLocation();
|
IASTFileLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation != null) {
|
if (fileLocation != null) {
|
||||||
int nodeEndOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
|
int nodeEndOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
|
||||||
scribe.restartAtOffset(nodeEndOffset);
|
scribe.restartAtOffset(nodeEndOffset);
|
||||||
|
@ -3845,7 +3875,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
if (node instanceof IASTProblemHolder || node instanceof IASTTranslationUnit) {
|
if (node instanceof IASTProblemHolder || node instanceof IASTTranslationUnit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IASTFileLocation fileLocation= node.getFileLocation();
|
IASTFileLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation == null) {
|
if (fileLocation == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3881,7 +3911,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void skipNode(IASTNode node) {
|
private void skipNode(IASTNode node) {
|
||||||
final IASTNodeLocation fileLocation= node.getFileLocation();
|
final IASTNodeLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation != null && fileLocation.getNodeLength() > 0) {
|
if (fileLocation != null && fileLocation.getNodeLength() > 0) {
|
||||||
final int endOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
|
final int endOffset= fileLocation.getNodeOffset() + fileLocation.getNodeLength();
|
||||||
final int currentOffset= getCurrentPosition();
|
final int currentOffset= getCurrentPosition();
|
||||||
|
@ -3893,7 +3923,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void skipToNode(IASTNode node) {
|
private void skipToNode(IASTNode node) {
|
||||||
final IASTNodeLocation fileLocation= node.getFileLocation();
|
final IASTNodeLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation != null) {
|
if (fileLocation != null) {
|
||||||
final int startOffset= fileLocation.getNodeOffset();
|
final int startOffset= fileLocation.getNodeOffset();
|
||||||
final int currentOffset= getCurrentPosition();
|
final int currentOffset= getCurrentPosition();
|
||||||
|
@ -3905,7 +3935,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private void skipNonWhitespaceToNode(IASTNode node) {
|
private void skipNonWhitespaceToNode(IASTNode node) {
|
||||||
final IASTNodeLocation fileLocation= node.getFileLocation();
|
final IASTNodeLocation fileLocation= getFileLocation(node);
|
||||||
if (fileLocation != null) {
|
if (fileLocation != null) {
|
||||||
final int startOffset= fileLocation.getNodeOffset();
|
final int startOffset= fileLocation.getNodeOffset();
|
||||||
final int nextTokenOffset= getNextTokenOffset();
|
final int nextTokenOffset= getNextTokenOffset();
|
||||||
|
@ -3985,18 +4015,22 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean startsWithMacroExpansion(IASTNode node) {
|
private boolean startsWithMacroExpansion(IASTNode node) {
|
||||||
|
if (fInsideMacroArguments)
|
||||||
|
return false;
|
||||||
IASTNodeLocation[] locations= node.getNodeLocations();
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
|
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
|
||||||
locations[0] instanceof IASTMacroExpansionLocation) {
|
locations[0] instanceof IASTMacroExpansionLocation) {
|
||||||
IASTFileLocation expansionLocation= locations[0].asFileLocation();
|
IASTFileLocation expansionLocation= locations[0].asFileLocation();
|
||||||
IASTFileLocation fileLocation= node.getFileLocation();
|
IASTFileLocation fileLocation= getFileLocation(node);
|
||||||
return expansionLocation.getNodeOffset() == fileLocation.getNodeOffset();
|
return expansionLocation.getNodeOffset() == fileLocation.getNodeOffset();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean endsWithMacroExpansion(IASTNode node) {
|
private boolean endsWithMacroExpansion(IASTNode node) {
|
||||||
|
if (fInsideMacroArguments)
|
||||||
|
return false;
|
||||||
IASTNodeLocation[] locations= node.getNodeLocations();
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
|
if (!(node instanceof IASTProblemHolder) && locations.length != 0 &&
|
||||||
locations[locations.length - 1] instanceof IASTMacroExpansionLocation) {
|
locations[locations.length - 1] instanceof IASTMacroExpansionLocation) {
|
||||||
|
@ -4005,13 +4039,17 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean enclosedInMacroExpansion(IASTNode node) {
|
private boolean enclosedInMacroExpansion(IASTNode node) {
|
||||||
|
if (fInsideMacroArguments)
|
||||||
|
return false;
|
||||||
IASTNodeLocation[] locations= node.getNodeLocations();
|
IASTNodeLocation[] locations= node.getNodeLocations();
|
||||||
return locations.length == 1 && locations[0] instanceof IASTMacroExpansionLocation;
|
return locations.length == 1 && locations[0] instanceof IASTMacroExpansionLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean withinMacroExpansion(IASTNode node, int offset) {
|
private boolean withinMacroExpansion(IASTNode node, int offset) {
|
||||||
IASTFileLocation loc = node.getFileLocation();
|
if (fInsideMacroArguments)
|
||||||
|
return false;
|
||||||
|
IASTFileLocation loc = getFileLocation(node);
|
||||||
if (loc == null || offset < loc.getNodeOffset() || offset >= loc.getNodeOffset() + loc.getNodeLength()) {
|
if (loc == null || offset < loc.getNodeOffset() || offset >= loc.getNodeOffset() + loc.getNodeLength()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4061,9 +4099,9 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
* normally separated by other tokens this is an indication that they were produced by the same
|
* normally separated by other tokens this is an indication that they were produced by the same
|
||||||
* macro expansion.
|
* macro expansion.
|
||||||
*/
|
*/
|
||||||
private static boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
|
private boolean doNodeLocationsOverlap(IASTNode node1, IASTNode node2) {
|
||||||
IASTFileLocation loc1 = node1.getFileLocation();
|
IASTFileLocation loc1 = getFileLocation(node1);
|
||||||
IASTFileLocation loc2 = node2.getFileLocation();
|
IASTFileLocation loc2 = getFileLocation(node2);
|
||||||
return loc1.getNodeOffset() + loc1.getNodeLength() > loc2.getNodeOffset() &&
|
return loc1.getNodeOffset() + loc1.getNodeLength() > loc2.getNodeOffset() &&
|
||||||
loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength();
|
loc1.getNodeOffset() < loc2.getNodeOffset() + loc2.getNodeLength();
|
||||||
}
|
}
|
||||||
|
@ -4073,16 +4111,16 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
* separated by other tokens this is an indication that they were produced by the same macro
|
* separated by other tokens this is an indication that they were produced by the same macro
|
||||||
* expansion.
|
* expansion.
|
||||||
*/
|
*/
|
||||||
private static boolean doNodesHaveSameOffset(IASTNode node1, IASTNode node2) {
|
private boolean doNodesHaveSameOffset(IASTNode node1, IASTNode node2) {
|
||||||
return nodeOffset(node1) == nodeOffset(node2);
|
return nodeOffset(node1) == nodeOffset(node2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int nodeOffset(IASTNode node) {
|
private int nodeOffset(IASTNode node) {
|
||||||
return node.getFileLocation().getNodeOffset();
|
return getFileLocation(node).getNodeOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int nodeEndOffset(IASTNode node) {
|
private int nodeEndOffset(IASTNode node) {
|
||||||
IASTFileLocation loc = node.getFileLocation();
|
IASTFileLocation loc = getFileLocation(node);
|
||||||
return loc.getNodeOffset() + loc.getNodeLength();
|
return loc.getNodeOffset() + loc.getNodeLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4407,14 +4445,19 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
private int findTokenWithinNode(int tokenType, IASTNode node) {
|
private int findTokenWithinNode(int tokenType, IASTNode node) {
|
||||||
IASTFileLocation location = node.getFileLocation();
|
IASTFileLocation location = getFileLocation(node);
|
||||||
int endOffset = location.getNodeOffset() + location.getNodeLength();
|
int endOffset = location.getNodeOffset() + location.getNodeLength();
|
||||||
return scribe.findToken(tokenType, endOffset);
|
return scribe.findToken(tokenType, endOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int findTokenAfterNode(int tokenType, IASTNode node) {
|
private int findTokenAfterNodeOrTokenRange(int tokenType, Object nodeOrTokenRange) {
|
||||||
IASTFileLocation location = node.getFileLocation();
|
int startOffset;
|
||||||
int startOffset = location.getNodeOffset() + location.getNodeLength();
|
if (nodeOrTokenRange instanceof IASTNode) {
|
||||||
|
IASTFileLocation location = getFileLocation((IASTNode) nodeOrTokenRange);
|
||||||
|
startOffset = location.getNodeOffset() + location.getNodeLength();
|
||||||
|
} else {
|
||||||
|
startOffset = ((TokenRange) nodeOrTokenRange).getEndOffset();
|
||||||
|
}
|
||||||
return scribe.findToken(tokenType, startOffset, scribe.scannerEndPosition - 1);
|
return scribe.findToken(tokenType, startOffset, scribe.scannerEndPosition - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1765,7 +1765,6 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
// }
|
// }
|
||||||
//#endif
|
//#endif
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public void testMacroAsFunctionArguments_Bug253039() throws Exception {
|
public void testMacroAsFunctionArguments_Bug253039() throws Exception {
|
||||||
assertFormatterResult();
|
assertFormatterResult();
|
||||||
}
|
}
|
||||||
|
@ -1901,6 +1900,33 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
assertFormatterResult();
|
assertFormatterResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define MACRO(a,b) f(a,b)
|
||||||
|
//void f(bool b, int i);
|
||||||
|
//int function_with_loooooooooooooooong_name();
|
||||||
|
//int another_function_with_loooooong_name();
|
||||||
|
//
|
||||||
|
//void test(){
|
||||||
|
// MACRO("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"=="bbbbbbbbbbbbbbbbbbbbbbbbbbb",function_with_loooooooooooooooong_name()+another_function_with_loooooong_name());
|
||||||
|
//}
|
||||||
|
|
||||||
|
//#define MACRO(a,b) f(a,b)
|
||||||
|
//void f(bool b, int i);
|
||||||
|
//int function_with_loooooooooooooooong_name();
|
||||||
|
//int another_function_with_loooooong_name();
|
||||||
|
//
|
||||||
|
//void test() {
|
||||||
|
// MACRO("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
|
// == "bbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||||
|
// function_with_loooooooooooooooong_name()
|
||||||
|
// + another_function_with_loooooong_name());
|
||||||
|
//}
|
||||||
|
public void testMacroArguments() throws Exception {
|
||||||
|
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.SPACE);
|
||||||
|
fOptions.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
|
||||||
|
Integer.toString(Alignment.M_COMPACT_SPLIT | Alignment.M_INDENT_ON_COLUMN));
|
||||||
|
assertFormatterResult();
|
||||||
|
}
|
||||||
|
|
||||||
//bool member __attribute__ ((__unused__)) = false;
|
//bool member __attribute__ ((__unused__)) = false;
|
||||||
|
|
||||||
//bool member __attribute__ ((__unused__)) = false;
|
//bool member __attribute__ ((__unused__)) = false;
|
||||||
|
@ -2892,7 +2918,7 @@ public class CodeFormatterTest extends BaseUITestCase {
|
||||||
//void f() {
|
//void f() {
|
||||||
// if (1) {
|
// if (1) {
|
||||||
// }
|
// }
|
||||||
// IF(1>0);
|
// IF(1 > 0);
|
||||||
//}
|
//}
|
||||||
public void testMacroAfterCompoundStatement_Bug356690() throws Exception {
|
public void testMacroAfterCompoundStatement_Bug356690() throws Exception {
|
||||||
assertFormatterResult();
|
assertFormatterResult();
|
||||||
|
|
Loading…
Add table
Reference in a new issue