1
0
Fork 0
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:
Sergey Prigogin 2013-01-04 19:22:22 -08:00
parent fdbafed3f3
commit e2a18cf6c2
3 changed files with 208 additions and 133 deletions

View file

@ -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;

View file

@ -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);
final int continuationIndentation = preferences.continuation_indentation; options.fSeparatorToken = Token.tCOMMA;
Alignment listAlignment = scribe.createAlignment( options.fSpaceAfterOpeningParen= preferences.insert_space_after_opening_paren_in_method_invocation;
Alignment.MACRO_ARGUMENTS, options.fSpaceBeforeClosingParen= preferences.insert_space_before_closing_paren_in_method_invocation;
preferences.alignment_for_arguments_in_method_invocation, options.fSpaceBetweenEmptyParen= preferences.insert_space_between_empty_parens_in_method_invocation;
Alignment.R_OUTERMOST, options.fSpaceBeforeSeparator= preferences.insert_space_before_comma_in_method_invocation_arguments;
binding.getParameterList().length, options.fSpaceAfterSeparator= preferences.insert_space_after_comma_in_method_invocation_arguments;
getCurrentPosition(), options.fTieBreakRule = Alignment.R_OUTERMOST;
continuationIndentation, fInsideMacroArguments = true;
false);
scribe.enterAlignment(listAlignment);
boolean ok = false;
do {
try { try {
int fragment = 0; formatList(arguments, options, true, false, scribe.takeTailFormatter());
scribe.alignFragment(listAlignment, fragment); } finally {
fInsideMacroArguments = false;
}
}
/**
* Scans macro expansion arguments starting from the current position and returns a list of
* arguments where each argument is represented either by a {@link IASTNode} or, if not
* possible, by a {@link TokenRange}.
*/
private List<Object> getMacroArguments(int expectedNumberOfArguments) {
List<TokenRange> argumentRanges = new ArrayList<TokenRange>(expectedNumberOfArguments);
TokenRange currentArgument = null;
localScanner.resetTo(getCurrentPosition(), scribe.scannerEndPosition);
localScanner.getNextToken(); // Skip the opening parenthesis.
int parenLevel = 0; int parenLevel = 0;
boolean done = false; int token;
while (!done) { while ((token = localScanner.getNextToken()) != Token.tBADCHAR) {
boolean hasWhitespace= scribe.printComment(); int tokenOffset = localScanner.getCurrentTokenStartPosition();
int token = peekNextToken(); if (parenLevel == 0 && (token == Token.tCOMMA || token == Token.tRPAREN)) {
if (currentArgument != null) {
argumentRanges.add(currentArgument);
currentArgument = null;
} else {
argumentRanges.add(new TokenRange(tokenOffset, tokenOffset));
}
if (token == Token.tRPAREN)
break;
} else {
int tokenEndOffset = localScanner.getCurrentPosition();
if (currentArgument == null) {
currentArgument = new TokenRange(tokenOffset, tokenEndOffset);
} else {
currentArgument.endOffset = tokenEndOffset;
}
switch (token) { switch (token) {
case Token.tLPAREN: case Token.tLPAREN:
++parenLevel; ++parenLevel;
scribe.printNextToken(token, hasWhitespace);
break; break;
case Token.tRPAREN: case Token.tRPAREN:
if (parenLevel > 0) { if (parenLevel > 0)
--parenLevel; --parenLevel;
scribe.printNextToken(token, hasWhitespace); break;
}
}
}
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 { } else {
if (preferences.insert_space_before_closing_paren_in_method_invocation) { arguments.add(argument);
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; return arguments;
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.tSEMI) {
scribe.printNextToken(token);
scribe.startNewLine();
}
ok = true;
} catch (AlignmentException e) {
scribe.redoAlignment(e);
}
} while (!ok);
scribe.exitAlignment(listAlignment, true);
} }
@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) {
if (element instanceof ICPPASTConstructorChainInitializer) {
// Constructor chain initializer is a special case. // Constructor chain initializer is a special case.
visit((ICPPASTConstructorChainInitializer) node); visit((ICPPASTConstructorChainInitializer) element);
} else { } else {
node.accept(this); ((IASTNode) element).accept(this);
}
} else {
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);
} }
} }

View file

@ -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;