mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 367827: Wrong offset for comment directly after macro expansion.
This commit is contained in:
parent
ea56585a4c
commit
7d0d64393c
5 changed files with 69 additions and 29 deletions
|
@ -12,6 +12,8 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||
|
||||
import static org.eclipse.cdt.core.parser.ParserLanguage.CPP;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
@ -24,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTComment;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
|
||||
|
@ -7386,5 +7389,16 @@ public class AST2Tests extends AST2BaseTest {
|
|||
IValue v= at.getSize();
|
||||
assertTrue(v.numericalValue() == 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #define NULL_STATEMENT_MACRO ;;
|
||||
// void macro_test() {
|
||||
// NULL_STATEMENT_MACRO //comment
|
||||
// }
|
||||
public void testCommentAfterMacroExpansion_367827() throws Exception {
|
||||
IASTTranslationUnit tu= parse(getAboveComment(), CPP);
|
||||
IASTComment comment= tu.getComments()[0];
|
||||
assertEquals("//comment", new String(comment.getComment()));
|
||||
assertEquals("//comment", comment.getRawSignature());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -477,9 +477,14 @@ public class LocationMapTests extends BaseTestCase {
|
|||
fLocationMap.encounterPoundDefine(3, 13, 33, 63, 103, true, macro3);
|
||||
IASTName name1= fLocationMap.encounterImplicitMacroExpansion(macro1, null);
|
||||
IASTName name2= fLocationMap.encounterImplicitMacroExpansion(macro2, null);
|
||||
fLocationMap.pushMacroExpansion(110, 115, 125, 30, macro3, new IASTName[]{name1, name2}, new ImageLocationInfo[0]);
|
||||
fLocationMap.encounteredComment(12, 23, false);
|
||||
checkComment(fLocationMap.getComments()[0], new String(LONGDIGITS, 110, 15), false, FN, 110, 15, 2, 2);
|
||||
ILocationCtx me = fLocationMap.pushMacroExpansion(110, 115, 125, 30, macro3, new IASTName[]{name1, name2}, new ImageLocationInfo[0]);
|
||||
// Comment in expansion
|
||||
fLocationMap.encounteredComment(116, 120, false);
|
||||
// Comment right after expansion, reported before expansion completes.
|
||||
fLocationMap.encounteredComment(125, 140, false);
|
||||
fLocationMap.popContext(me);
|
||||
checkComment(fLocationMap.getComments()[0], new String(LONGDIGITS, 116, 4), false, FN, 116, 4, 2, 2);
|
||||
checkComment(fLocationMap.getComments()[1], new String(LONGDIGITS, 125, 15), false, FN, 125, 15, 2, 2);
|
||||
|
||||
IASTName[] refs= fLocationMap.getReferences(macro3);
|
||||
assertEquals(1, refs.length);
|
||||
|
@ -505,7 +510,6 @@ public class LocationMapTests extends BaseTestCase {
|
|||
// number: [0,6)[26,30)
|
||||
ILocationCtx pre2= fLocationMap.pushPreInclusion(new CharArray("a1a2a3a4a5"), 0, true);
|
||||
assertEquals(FN, fLocationMap.getCurrentFilePath());
|
||||
fLocationMap.encounteredComment(0,2,true);
|
||||
// number: [6,15)[25,26)
|
||||
ILocationCtx i1= fLocationMap.pushInclusion(0, 2, 4, 6, new CharArray("b1b2b3b4b5"), "pre1", "pre1".toCharArray(), false, false, false);
|
||||
assertEquals("pre1", fLocationMap.getCurrentFilePath());
|
||||
|
@ -533,11 +537,10 @@ public class LocationMapTests extends BaseTestCase {
|
|||
|
||||
|
||||
IASTComment[] comments= fLocationMap.getComments();
|
||||
checkComment(comments[0], "", true, FN, 0, 0, 1, 1);
|
||||
checkComment(comments[1], "b2", true, "pre1", 2, 2, 1, 1);
|
||||
checkComment(comments[2], "c2c3", true, "pre11", 2, 4, 1, 1);
|
||||
checkComment(comments[3], "b3", false, "pre1", 4, 2, 1, 1);
|
||||
checkComment(comments[4], "d1", true, "pre2", 0, 2, 1, 1);
|
||||
checkComment(comments[0], "b2", true, "pre1", 2, 2, 1, 1);
|
||||
checkComment(comments[1], "c2c3", true, "pre11", 2, 4, 1, 1);
|
||||
checkComment(comments[2], "b3", false, "pre1", 4, 2, 1, 1);
|
||||
checkComment(comments[3], "d1", true, "pre2", 0, 2, 1, 1);
|
||||
|
||||
checkLocation(fLocationMap.getMappedFileLocation(0, 6), FN, 0, 0, 1, 1);
|
||||
checkLocation(fLocationMap.getMappedFileLocation(6, 9), "pre1", 0, 9, 1, 1);
|
||||
|
|
|
@ -40,8 +40,12 @@ public abstract class ASTNode implements IASTNode {
|
|||
private IASTNode parent;
|
||||
private ASTNodeProperty property;
|
||||
|
||||
private int length;
|
||||
/**
|
||||
* The sequence number of the ast-node as calculated by the location map.
|
||||
* Do not access directly, because getOffset() may be overloaded for lazy calculations.
|
||||
*/
|
||||
private int offset;
|
||||
private int length;
|
||||
private IASTNodeLocation[] locations;
|
||||
private IASTFileLocation fileLocation;
|
||||
|
||||
|
@ -112,17 +116,20 @@ public abstract class ASTNode implements IASTNode {
|
|||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
this.locations = null;
|
||||
this.fileLocation = null;
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
this.locations = null;
|
||||
this.fileLocation = null;
|
||||
}
|
||||
|
||||
public void setOffsetAndLength(int offset, int length) {
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
this.locations = null;
|
||||
this.fileLocation = null;
|
||||
}
|
||||
|
||||
public void setOffsetAndLength(ASTNode node) {
|
||||
|
@ -140,7 +147,7 @@ public abstract class ASTNode implements IASTNode {
|
|||
if (tu != null) {
|
||||
ILocationResolver l= (ILocationResolver) tu.getAdapter(ILocationResolver.class);
|
||||
if (l != null) {
|
||||
locations= l.getLocations(offset, length);
|
||||
locations= l.getLocations(getOffset(), length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +159,7 @@ public abstract class ASTNode implements IASTNode {
|
|||
if (tu != null) {
|
||||
ILocationResolver l= (ILocationResolver) tu.getAdapter(ILocationResolver.class);
|
||||
if (l != null) {
|
||||
return l.getImageLocation(offset, length);
|
||||
return l.getImageLocation(getOffset(), length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -177,7 +184,8 @@ public abstract class ASTNode implements IASTNode {
|
|||
|
||||
@Override
|
||||
public String getContainingFilename() {
|
||||
if (offset <= 0 && (length == 0 || offset < 0)) {
|
||||
final int offset = getOffset();
|
||||
if (offset <= 0 && (length == 0 || offset < 0)) {
|
||||
final IASTNode parent = getParent();
|
||||
if (parent == null) {
|
||||
if (this instanceof IASTTranslationUnit) {
|
||||
|
@ -195,7 +203,8 @@ public abstract class ASTNode implements IASTNode {
|
|||
if (fileLocation != null)
|
||||
return fileLocation;
|
||||
// TODO(sprigogin): The purpose of offset == 0 && length == 0 condition is not clear to me.
|
||||
if (offset < 0 || (offset == 0 && length == 0 && !(this instanceof IASTTranslationUnit))) {
|
||||
final int offset = getOffset();
|
||||
if (offset < 0 || (offset == 0 && length == 0 && !(this instanceof IASTTranslationUnit))) {
|
||||
return null;
|
||||
}
|
||||
IASTTranslationUnit ast = getTranslationUnit();
|
||||
|
@ -217,7 +226,7 @@ public abstract class ASTNode implements IASTNode {
|
|||
if (ast != null) {
|
||||
ILocationResolver lr= (ILocationResolver) ast.getAdapter(ILocationResolver.class);
|
||||
if (lr != null) {
|
||||
return lr.isPartOfTranslationUnitFile(offset);
|
||||
return lr.isPartOfTranslationUnitFile(getOffset());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -228,7 +237,7 @@ public abstract class ASTNode implements IASTNode {
|
|||
if (ast != null) {
|
||||
ILocationResolver lr= (ILocationResolver) ast.getAdapter(ILocationResolver.class);
|
||||
if (lr != null) {
|
||||
return lr.isPartOfSourceFile(offset);
|
||||
return lr.isPartOfSourceFile(getOffset());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -248,27 +257,29 @@ public abstract class ASTNode implements IASTNode {
|
|||
public boolean contains(IASTNode node) {
|
||||
if (node instanceof ASTNode) {
|
||||
ASTNode astNode= (ASTNode) node;
|
||||
return offset <= astNode.offset &&
|
||||
astNode.offset+astNode.length <= offset+length;
|
||||
final int offset = getOffset();
|
||||
final int nodeOffset= astNode.getOffset();
|
||||
return offset <= nodeOffset && nodeOffset+astNode.length <= offset+length;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IToken getSyntax() throws ExpansionOverlapsBoundaryException {
|
||||
final int offset = getOffset();
|
||||
return getSyntax(offset, offset+length, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IToken getLeadingSyntax() throws ExpansionOverlapsBoundaryException {
|
||||
int left= getBoundary(-1);
|
||||
return getSyntax(left, offset, -1);
|
||||
return getSyntax(left, getOffset(), -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IToken getTrailingSyntax() throws ExpansionOverlapsBoundaryException {
|
||||
int right= getBoundary(1);
|
||||
return getSyntax(offset+length, right, 1);
|
||||
return getSyntax(getOffset()+length, right, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -105,21 +105,35 @@ abstract class ASTPreprocessorNode extends ASTNode {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(getSource(getOffset(), getLength()));
|
||||
return String.valueOf(getRawSignatureChars());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ASTComment extends ASTPreprocessorNode implements IASTComment {
|
||||
private final boolean fIsBlockComment;
|
||||
public ASTComment(IASTTranslationUnit parent, int startNumber, int endNumber, boolean isBlockComment) {
|
||||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
||||
private String fFilePath;
|
||||
public ASTComment(IASTTranslationUnit parent, String filePath, int offset, int endOffset, boolean isBlockComment) {
|
||||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, offset, endOffset);
|
||||
fIsBlockComment= isBlockComment;
|
||||
fFilePath= filePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
if (fFilePath != null) {
|
||||
// Perform lazy conversion to sequence number
|
||||
ILocationResolver lr= (ILocationResolver) getTranslationUnit().getAdapter(ILocationResolver.class);
|
||||
if (lr != null) {
|
||||
setOffset(lr.getSequenceNumberForFileOffset(fFilePath, super.getOffset()));
|
||||
fFilePath= null;
|
||||
}
|
||||
}
|
||||
return super.getOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getComment() {
|
||||
return getSource(getOffset(), getLength());
|
||||
return getRawSignatureChars();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -245,9 +245,7 @@ public class LocationMap implements ILocationResolver {
|
|||
}
|
||||
|
||||
public void encounteredComment(int offset, int endOffset, boolean isBlockComment) {
|
||||
offset= getSequenceNumberForOffset(offset);
|
||||
endOffset= getSequenceNumberForOffset(endOffset);
|
||||
fComments.add(new ASTComment(fTranslationUnit, offset, endOffset, isBlockComment));
|
||||
fComments.add(new ASTComment(fTranslationUnit, getCurrentFilePath(), offset, endOffset, isBlockComment));
|
||||
}
|
||||
|
||||
public void encounterProblem(int id, char[] arg, int offset, int endOffset) {
|
||||
|
|
Loading…
Add table
Reference in a new issue