diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index e8207e08630..6d25bb28016 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -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()); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LocationMapTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LocationMapTests.java index 2c177dd0a6b..661231fea6f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LocationMapTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/LocationMapTests.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java index c3d79aa6247..4d45e26519a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java @@ -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); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java index 555666df72b..d438bd47cac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java @@ -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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java index 0e6fab5dcb3..e797ca97f7c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/LocationMap.java @@ -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) {