1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Fix for 148360 by Emanuel Graf, adding comments to the AST.

This commit is contained in:
Markus Schorn 2007-04-23 08:54:31 +00:00
parent 252c41a134
commit b06161edc1
24 changed files with 693 additions and 62 deletions

View file

@ -98,7 +98,11 @@ public class AST2BaseTest extends BaseTestCase {
* @return
* @throws ParserException
*/
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems ) throws ParserException {
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems ) throws ParserException{
return parse(code, lang, useGNUExtensions, expectNoProblems, false);
}
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems , boolean parseComments) throws ParserException {
CodeReader codeReader = new CodeReader(code
.toCharArray());
ScannerInfo scannerInfo = new ScannerInfo();
@ -108,6 +112,7 @@ public class AST2BaseTest extends BaseTestCase {
else
configuration = new GPPScannerExtensionConfiguration();
IScanner scanner = new DOMScanner( codeReader, scannerInfo, ParserMode.COMPLETE_PARSE, lang, NULL_LOG, configuration, FileCodeReaderFactory.getInstance() );
scanner.setScanComments(parseComments);
ISourceCodeParser parser2 = null;
if( lang == ParserLanguage.CPP )
@ -117,9 +122,7 @@ public class AST2BaseTest extends BaseTestCase {
config = new GPPParserExtensionConfiguration();
else
config = new ANSICPPParserExtensionConfiguration();
parser2 = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE,
NULL_LOG,
config );
parser2 = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG,config, null);
}
else
{
@ -130,8 +133,7 @@ public class AST2BaseTest extends BaseTestCase {
else
config = new ANSICParserExtensionConfiguration();
parser2 = new GNUCSourceParser( scanner, ParserMode.COMPLETE_PARSE,
NULL_LOG, config );
parser2 = new GNUCSourceParser( scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config, null);
}
IASTTranslationUnit tu = parser2.parse();
@ -224,7 +226,7 @@ public class AST2BaseTest extends BaseTestCase {
* @throws ParserException
*/
protected void validateSimpleBinaryExpressionC( String code, int operand ) throws ParserException {
IASTBinaryExpression e = (IASTBinaryExpression) getExpressionFromStatementInCode( code, ParserLanguage.C ); //$NON-NLS-1$
IASTBinaryExpression e = (IASTBinaryExpression) getExpressionFromStatementInCode( code, ParserLanguage.C );
assertNotNull( e );
assertEquals( e.getOperator(), operand );
IASTIdExpression x = (IASTIdExpression) e.getOperand1();

View file

@ -0,0 +1,191 @@
/*******************************************************************************
* Copyright (c) 2007 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Emanuel Graf & Guido Zgraggen - initial API and implementation
******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.parser.ParserException;
/**
* @author Guido Zgraggen
*
*/
public class CommentTests extends AST2BaseTest {
public void testCountCommentsInHeaderFile() throws ParserException{
IASTTranslationUnit tu = parse(getHSource(), ParserLanguage.CPP, false, true, true);
IASTComment[] comments = tu.getComments();
assertEquals(9, comments.length);
}
public void testCommentsInHeaderFile() throws ParserException{
IASTTranslationUnit tu = parse(getHSource(), ParserLanguage.CPP, false, true, true);
IASTComment[] comments = tu.getComments();
assertEquals("/* A very cool class\n * isn't it?\n */", new String(comments[0].getComment()));
assertEquals("//the Hallo", new String(comments[1].getComment()));
assertEquals("// the 2. Hallo", new String(comments[2].getComment()));
assertEquals("// comment im h", new String(comments[3].getComment()));
assertEquals("// comment before ", new String(comments[4].getComment()));
assertEquals("//Great", new String(comments[5].getComment()));
assertEquals("//once more", new String(comments[6].getComment()));
assertEquals("//value field", new String(comments[7].getComment()));
assertEquals("//Endcomment h", new String(comments[8].getComment()));
}
public void testCountCommentsInCPPFile() throws ParserException{
IASTTranslationUnit tu = parse(getCppSource(), ParserLanguage.CPP, false, true, true);
IASTComment[] comments = tu.getComments();
assertEquals(10, comments.length);
}
public void testCommentsInCPPFile() throws ParserException{
IASTTranslationUnit tu = parse(getCppSource(), ParserLanguage.CPP, false, true, true);
IASTComment[] comments = tu.getComments();
assertEquals("// Comment in cpp", new String(comments[0].getComment()));
assertEquals("/*The magic 5 */", new String(comments[1].getComment()));
assertEquals("// Another comment", new String(comments[2].getComment()));
assertEquals("/* A blockcomment \n* over multiple lines */", new String(comments[3].getComment()));
assertEquals("//Toplevel comment", new String(comments[4].getComment()));
assertEquals("//A little bit code", new String(comments[5].getComment()));
assertEquals("//Trailing comment", new String(comments[6].getComment()));
assertEquals("//Comment on newline", new String(comments[7].getComment()));
assertEquals("//Last comment in cpp", new String(comments[8].getComment()));
assertEquals("//An integer", new String(comments[9].getComment()));
}
public void testCountCommentsInCFile() throws ParserException{
IASTTranslationUnit tu = parse(getCSource(), ParserLanguage.C, false, true, true);
IASTComment[] comments = tu.getComments();
assertEquals(4, comments.length);
}
public void testCommentsInCFile() throws ParserException{
IASTTranslationUnit tu = parse(getCSource(), ParserLanguage.C, false, true, true);
IASTComment[] comments = tu.getComments();
assertEquals("//A little input/output programm", new String(comments[0].getComment()));
assertEquals("//Read the number", new String(comments[1].getComment()));
assertEquals("/*\n * That is the answer ;-)\n */", new String(comments[2].getComment()));
assertEquals("//The end", new String(comments[3].getComment()));
}
private String getHSource() {
StringBuffer buffer = new StringBuffer();
buffer.append("#ifndef CPPCLASS_H_\n");
buffer.append("#define CPPCLASS_H_\n");
buffer.append("/* A very cool class\n");
buffer.append(" * isn't it?\n");
buffer.append(" */\n");
buffer.append("class CppClass\n");
buffer.append("{\n");
buffer.append("public:\n");
buffer.append(" CppClass(int hallo, //the Hallo\n");
buffer.append(" int hallo2) // the 2. Hallo\n");
buffer.append(" const;\n");
buffer.append(" // comment im h\n");
buffer.append(" virtual ~CppClass();\n");
buffer.append(" // comment before \n");
buffer.append(" void doIrgendwas(); //Great\n");
buffer.append("private:\n");
buffer.append(" void privateMethode(); //once more\n");
buffer.append(" //value field\n");
buffer.append(" int value;\n");
buffer.append(" //Endcomment h\n");
buffer.append("};\n");
buffer.append("#endif\n");
return buffer.toString();
}
private String getCppSource() {
StringBuffer buffer = new StringBuffer();
buffer.append("CppClass()\n");
buffer.append("{\n");
buffer.append(" // Comment in cpp\n");
buffer.append(" value = 1 + /*The magic 5 */5 * 6;\n");
buffer.append(" // Another comment\n");
buffer.append(" value++;\n");
buffer.append("}\n");
buffer.append("/* A blockcomment \n");
buffer.append("* over multiple lines */\n");
buffer.append("//Toplevel comment\n");
buffer.append("doIrgendwas(){\n");
buffer.append(" //A little bit code\n");
buffer.append(" int i = 3; //Trailing comment\n");
buffer.append(" ;\n");
buffer.append(" switch(i){\n");
buffer.append(" case 1:\n");
buffer.append(" ++i;\n");
buffer.append(" break;\n");
buffer.append(" default:\n");
buffer.append(" ++i;\n");
buffer.append(" break;\n");
buffer.append(" }\n");
buffer.append(" do {\n");
buffer.append(" ++i;\n");
buffer.append(" } while (i < 10);\n");
buffer.append(" while (i < 20){\n");
buffer.append(" ++i;\n");
buffer.append(" }\n");
buffer.append(" //Comment on newline\n");
buffer.append(" int n = i++ +5;\n");
buffer.append(" //Last comment in cpp\n");
buffer.append("}\n");
buffer.append("globaleFuntktion(){\n");
buffer.append("//An integer\n");
buffer.append("int i;\n");
buffer.append("}\n");
buffer.append("enum hue { red, blue, green };\n");
buffer.append("enum hue col, *cp;\n");
buffer.append("void f() {\n");
buffer.append(" col = blue;\n");
buffer.append(" cp = &col;\n");
buffer.append(" if( *cp != red )\n");
buffer.append(" return;\n");
buffer.append("}\n");
return buffer.toString();
}
private String getCSource() {
StringBuffer buffer = new StringBuffer();
buffer.append("//A little input/output programm\n");
buffer.append("int main(void){\n");
buffer.append(" int number = -1;\n");
buffer.append("\n");
buffer.append(" printf(\"Please enter a number: \");\n");
buffer.append(" scanf(\"%d\", &number); //Read the number\n");
buffer.append("\n");
buffer.append(" if(number < 10){\n");
buffer.append(" printf(\"You aren't a fan of big things? :-)\");\n");
buffer.append(" }\n");
buffer.append(" else{\n");
buffer.append(" if(number == 42){\n");
buffer.append(" /*\n");
buffer.append(" * That is the answer ;-)\n");
buffer.append(" */\n");
buffer.append(" printf(\"Great!!! Thats the answer!!!\");\n");
buffer.append(" }\n");
buffer.append(" else{\n");
buffer.append(" printf(\"You tipped: %d\", number);\n");
buffer.append(" }\n");
buffer.append(" }\n");
buffer.append(" return 0; //The end\n");
buffer.append("}\n");
return buffer.toString();
}
}

View file

@ -47,6 +47,7 @@ public class DOMParserTestSuite extends TestCase {
suite.addTestSuite( DOMSelectionParseTest.class );
suite.addTestSuite( GCCCompleteParseExtensionsTest.class );
suite.addTestSuite(DOMPreprocessorInformationTest.class);
suite.addTestSuite(CommentTests.class);
suite.addTest( CompletionTestSuite.suite() );
return suite;
}

View file

@ -30,7 +30,13 @@ public abstract class AbstractLanguage extends PlatformObject implements ILangua
* Instructs the parser to skip function and method bodies.
*/
public final static int OPTION_SKIP_FUNCTION_BODIES= 1;
/**
* Option for {@link #getASTTranslationUnit(CodeReader, IScannerInfo, ICodeReaderFactory, IIndex, int, IParserLogService)}
* Instructs the parser to add comment nodes to the ast.
*/
public final static int OPTION_ADD_COMMENTS= 2;
/**
* @deprecated, throws an UnsupportedOperationException
*/
@ -55,7 +61,8 @@ public abstract class AbstractLanguage extends PlatformObject implements ILangua
* by the source code being parsed.
* @param index (optional) index to use to provide support for ambiguity
* resolution.
* @param options {@link #OPTION_SKIP_FUNCTION_BODIES} or <code>0</code>.
* @param options A combination of
* {@link #OPTION_SKIP_FUNCTION_BODIES} and {@link #OPTION_ADD_COMMENTS} or <code>0</code>.
* @param log logger
* @return an AST for the source code provided by reader.
* @throws CoreException

View file

@ -61,6 +61,13 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
*/
public static final int AST_SKIP_IF_NO_BUILD_INFO = 8;
/**
* Style constant for {@link #getAST(IIndex, int)}.
* Meaning: Add nodes for comments to the ast.
* @since 4.0
*/
public static final int AST_CREATE_COMMENT_NODES = 16;
/**
* Creates and returns an include declaration in this translation unit
* with the given name.
@ -463,7 +470,7 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
* translation unit does not support ASTs.
* @param index index to back up the parsing of the AST, may be <code>null</code>
* @param style <code>0</code> or a combination of {@link #AST_SKIP_ALL_HEADERS},
* {@link #AST_SKIP_IF_NO_BUILD_INFO} and {@link #AST_SKIP_INDEXED_HEADERS}
* {@link #AST_SKIP_IF_NO_BUILD_INFO}, {@link #AST_SKIP_INDEXED_HEADERS} and {@value #AST_CREATE_COMMENT_NODES}.
* @return the AST requested or <code>null</code>
* @throws CoreException
* @since 4.0

View file

@ -746,7 +746,11 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
ILanguage language= getLanguage();
if (language != null) {
if (language instanceof AbstractLanguage) {
return ((AbstractLanguage)language).getASTTranslationUnit(reader, scanInfo, codeReaderFactory, index, style, ParserUtil.getParserLogService());
int options= 0;
if ((style & AST_CREATE_COMMENT_NODES) != 0) {
options |= AbstractLanguage.OPTION_ADD_COMMENTS;
}
return ((AbstractLanguage)language).getASTTranslationUnit(reader, scanInfo, codeReaderFactory, index, options, ParserUtil.getParserLogService());
}
return language.getASTTranslationUnit(reader, scanInfo, codeReaderFactory, index, ParserUtil.getParserLogService());
}

View file

@ -51,6 +51,8 @@ public abstract class ASTVisitor {
public boolean shouldVisitTranslationUnit = false;
public boolean shouldVisitProblems = false;
public boolean shouldVisitComments = false;
/**
* @return continue to continue visiting, abort to stop, skip to not descend
@ -115,6 +117,10 @@ public abstract class ASTVisitor {
return PROCESS_CONTINUE;
}
public int visit( IASTComment comment){
return PROCESS_CONTINUE;
}
/**
* leave methods - implement a bottom-up traversal
*/
@ -165,4 +171,8 @@ public abstract class ASTVisitor {
public int leave(IASTProblem problem){
return PROCESS_CONTINUE;
}
public int leave( IASTComment comment){
return PROCESS_CONTINUE;
}
}

View file

@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2007 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Emanuel Graf & Leo Buettiker - initial API and implementation
******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* This class represents a comment.
*
* @author Emanuel Graf
*
*/
public interface IASTComment extends IASTNode {
/**
* Set the comment.
*
* @param comment
*/
public void setComment(char[] comment);
/**
* Return a char array representation of the comment.
*
* @return char array representation of the comment
*/
public char[] getComment();
/**
* Return true if this is a blockcomment.
*
* @return true if this is a blockcomment
*/
public boolean isBlockComment();
}

View file

@ -235,4 +235,21 @@ public interface IASTTranslationUnit extends IASTNode {
*/
public void setIndex(IIndex index);
/**
* Set comments to translation unit.
*
* @param comment
*/
public void setComments(IASTComment[] comments);
/**
* In case the ast was created in a way that supports comment parsing,
* all comments of the translation unit are returned. Otherwise an
* empty array will be supplied.
*
* @return <code>IASTComment[]</code>
* @since 4.0
*/
public IASTComment[] getComments();
}

View file

@ -97,8 +97,9 @@ public abstract class AbstractCLanguage extends AbstractLanguage implements ICLa
ICodeReaderFactory codeReaderFactory, IIndex index, int options, IParserLogService log) throws CoreException {
IScanner scanner= createScanner(reader, scanInfo, codeReaderFactory, log);
scanner.setScanComments((options & OPTION_ADD_COMMENTS) != 0);
ISourceCodeParser parser= createParser(scanner, log, index, false, options);
// Parse
IASTTranslationUnit ast= parser.parse();
return ast;

View file

@ -96,6 +96,7 @@ public abstract class AbstractCPPLanguage extends AbstractLanguage implements IC
ICodeReaderFactory codeReaderFactory, IIndex index, int options, IParserLogService log) throws CoreException {
IScanner scanner= createScanner(reader, scanInfo, codeReaderFactory, log);
scanner.setScanComments((options & OPTION_ADD_COMMENTS) != 0);
ISourceCodeParser parser= createParser(scanner, log, index, false, options);
// Parse

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2003, 2006 IBM Corporation and others.
* Copyright (c) 2003, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -36,6 +36,11 @@ public interface IScanner extends IMacroCollector {
public void setOffsetBoundary( int offset );
public void setContentAssistMode( int offset );
public void setASTFactory( IASTFactory f );
/**
* Turns on/off comment parsing.
* @since 4.0
*/
public void setScanComments(boolean val);
public IMacro addDefinition(char[] key, char[] value);
public IMacro addDefinition(char[] name, char[][] params, char[] expansion);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2005 IBM Corporation and others.
* Copyright (c) 2002, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -316,6 +316,12 @@ public interface IToken {
static public final int tCOMPLETION = 140;
static public final int tEOC = 141; // End of Completion
static public final int tCOMMENT = 142;
static public final int tBLOCKCOMMENT = 143;
static public final int tLAST = 141;
static public final int tLAST = 143;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* Copyright (c) 2004, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -214,6 +214,39 @@ public class ArrayUtil {
}
return result;
}
/**
* Assumes that array contains nulls at the end, only.
* Returns whether the specified array contains the specified object. Comparison is by
* object identity.
* @param array the array to search
* @param obj the object to search for
* @return true if the specified array contains the specified object, or the specified array is null
*/
public static boolean containsEqual( Object [] array, Object obj ){
return indexOfEqual(array, obj)!=-1;
}
/**
* Assumes that array contains nulls at the end, only.
* Returns the index into the specified array of the specified object, or -1 if the array does not
* contain the object, or if the array is null. Comparison is by equals().
* @param array the array to search
* @param obj the object to search for
* @return the index into the specified array of the specified object, or -1 if the array does not
* contain an equal object, or if the array is null
*/
public static int indexOfEqual(Object[] comments, Object comment) {
int result = -1;
if(comments!=null) {
for(int i=0; (i<comments.length) && (comments[i]!=null); i++) {
if(comments[i].equals(comment))
return i;
}
}
return result;
}
/**
* Note that this should only be used when the placement of

View file

@ -0,0 +1,99 @@
/*******************************************************************************
* Copyright (c) 2007 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Emanuel Graf & Leo Buettiker - initial API and implementation
* Guido Zgraggen
******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
/**
* @author egraf
*
*/
public class ASTComment extends ASTNode implements IASTComment {
private char[] comment;
private boolean blockComment;
public ASTComment(IToken commentTocken){
switch(commentTocken.getType()){
case IToken.tCOMMENT:
blockComment = false;
break;
case IToken.tBLOCKCOMMENT:
blockComment = true;
break;
default:
throw new IllegalArgumentException("No Comment Token"); //$NON-NLS-1$
}
comment = commentTocken.getImage().toCharArray();
setOffsetAndLength(commentTocken.getOffset(), commentTocken.getLength());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.ASTNode#accept(org.eclipse.cdt.core.dom.ast.ASTVisitor)
*/
public boolean accept(ASTVisitor visitor) {
if (visitor.shouldVisitComments) {
switch (visitor.visit(this)) {
case ASTVisitor.PROCESS_ABORT:
return false;
case ASTVisitor.PROCESS_SKIP:
return true;
default:
break;
}
}
return true;
}
/**
* @return the comment
*/
public char[] getComment() {
return comment;
}
/**
* @param comment the comment to set
*/
public void setComment(char[] comment) {
this.comment = comment;
}
public boolean isBlockComment() {
return blockComment;
}
public boolean equals(Object obj) {
if(! (obj instanceof ASTComment))
return false;
ASTComment com2 = (ASTComment)obj;
if(getOffset() == com2.getOffset() && getLength() == com2.getLength()){
return true;
}else{
return false;
}
}
public static IASTComment[] addComment(IASTComment[] comments, IASTComment comment) {
if(!ArrayUtil.contains(comments, comment)){
comments = (IASTComment[]) ArrayUtil.append(IASTComment.class, comments, comment);
}
return comments;
}
}

View file

@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
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.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
@ -92,6 +93,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected final boolean supportAlignOfUnaries;
protected final boolean supportKnRC;
protected IASTComment[] comments = new ASTComment[0];
protected final boolean supportAttributeSpecifiers;
@ -252,6 +255,14 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IToken fetchToken() throws EndOfFileException {
try {
IToken value = scanner.nextToken();
// Put the Comments in the Array for later processing
int type = value.getType();
while(type == IToken.tCOMMENT || type == IToken.tBLOCKCOMMENT){
IASTComment comment = createComment(value);
comments = ASTComment.addComment(comments, comment);
value = scanner.nextToken();
type= value.getType();
}
return value;
} catch (OffsetLimitReachedException olre) {
handleOffsetLimitException(olre);
@ -2363,4 +2374,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
return false;
}
/**
* Creates the ast node for a comment.
* @since 4.0
*/
protected abstract IASTComment createComment(IToken commentToken) throws EndOfFileException;
}

View file

@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
@ -44,6 +45,7 @@ import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ast.IASTEnumerator;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTComment;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTPreprocessorSelectionResult;
import org.eclipse.cdt.internal.core.dom.parser.IRequiresLocationInformation;
@ -80,6 +82,8 @@ public class CASTTranslationUnit extends CASTNode implements
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
private static final IASTName[] EMPTY_NAME_ARRAY = new IASTName[0];
private IASTComment[] comments = new ASTComment[0];
public IASTTranslationUnit getTranslationUnit() {
return this;
@ -582,5 +586,13 @@ public class CASTTranslationUnit extends CASTNode implements
public void setIndex(IIndex index) {
this.index = index;
}
public IASTComment[] getComments() {
return comments;
}
public void setComments(IASTComment[] comments) {
this.comments = comments;
}
}

View file

@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
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;
@ -106,6 +107,7 @@ import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTComment;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
@ -679,6 +681,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
}
}
}
translationUnit.setComments((IASTComment[]) ArrayUtil.trim(IASTComment.class, comments));
// compilationUnit.exitScope( requestor );
}
@ -3022,5 +3025,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return for_statement;
}
protected IASTComment createComment(IToken commentToken)
throws EndOfFileException {
return new ASTComment(commentToken);
}
}

View file

@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
@ -58,6 +59,7 @@ import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ast.IASTEnumerator;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTComment;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTPreprocessorSelectionResult;
@ -95,6 +97,8 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
private static final IASTName[] EMPTY_NAME_ARRAY = new IASTName[0];
private IASTComment[] comments = new ASTComment[0];
public IASTTranslationUnit getTranslationUnit() {
return this;
}
@ -625,5 +629,13 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
public void setIndex(IIndex pdom) {
this.index = pdom;
}
public IASTComment[] getComments() {
return comments;
}
public void setComments(IASTComment[] comments) {
this.comments = comments;
}
}

View file

@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
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;
@ -146,6 +147,7 @@ import org.eclipse.cdt.core.parser.ITokenDuple;
import org.eclipse.cdt.core.parser.ParseError;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTComment;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
@ -182,7 +184,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
private int templateCount = 0;
protected CPPASTTranslationUnit translationUnit;
private static class ScopeStack {
private int[] stack;
@ -4761,6 +4763,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
}
}
translationUnit.setComments((IASTComment[]) ArrayUtil.trim(IASTComment.class, comments));
}
/**
@ -5590,4 +5593,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
return for_statement;
}
protected IASTComment createComment(IToken commentToken)
throws EndOfFileException {
return new ASTComment(commentToken);
}
}

View file

@ -196,6 +196,8 @@ abstract class BaseScanner implements IScanner {
protected final boolean supportMinAndMax;
protected boolean scanComments;
protected final CharArrayIntMap additionalKeywords;
protected final CharArrayIntMap additionalPPKeywords;
@ -203,11 +205,12 @@ abstract class BaseScanner implements IScanner {
public BaseScanner(CodeReader reader, IScannerInfo info,
ParserMode parserMode, ParserLanguage language,
IParserLogService log, IScannerExtensionConfiguration configuration) {
this.parserMode = parserMode;
this.language = language;
this.log = log;
this.scanComments = false;
if (configuration.supportAdditionalNumericLiteralSuffixes() != null)
suffixes = configuration.supportAdditionalNumericLiteralSuffixes();
else
@ -660,7 +663,7 @@ abstract class BaseScanner implements IScanner {
ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
// Find the first thing we would care about
skipOverWhiteSpace();
skipOverWhiteSpaceFetchToken();
if (++bufferPos[bufferStackPos] >= bufferLimit[bufferStackPos]) {
// We're at the end of a context, pop it off and try again
@ -894,12 +897,14 @@ abstract class BaseScanner implements IScanner {
case '/':
if (pos + 1 < limit) {
if (buffer[pos + 1] == '=') {
++bufferPos[bufferStackPos];
return newToken(IToken.tDIVASSIGN);
}
}
return newToken(IToken.tDIV);
if (buffer[pos + 1] == '=') {
++bufferPos[bufferStackPos];
return newToken(IToken.tDIVASSIGN);
} else if (buffer[pos + 1] == '/' || buffer[pos + 1] == '*') {
return scanComment();
}
}
return newToken(IToken.tDIV);
case '%':
if (pos + 1 < limit) {
@ -2210,8 +2215,15 @@ abstract class BaseScanner implements IScanner {
skipOverNonWhiteSpace();
}
textend = bufferPos[bufferStackPos];
if (skipOverWhiteSpace())
encounteredComment = true;
if(scanComments && (buffer[textend+1]=='/'
&& (buffer[textend+2]=='/'||buffer[textend+2]=='*'))) {
if (skipOverWhiteSpaceAndParseComments())
encounteredComment = true;
} else {
if (skipOverWhiteSpace())
encounteredComment = true;
}
}
int textlen = textend - textstart + 1;
@ -2668,13 +2680,15 @@ abstract class BaseScanner implements IScanner {
}
protected boolean skipOverWhiteSpace() {
return skipOverWhiteSpaceAndParseComments();
}
protected boolean skipOverWhiteSpaceFetchToken() {
char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
int pos = bufferPos[bufferStackPos];
// if( pos > 0 && pos < limit && buffer[pos] == '\n')
// return false;
int pos = bufferPos[bufferStackPos];
boolean encounteredComment = false;
while (++bufferPos[bufferStackPos] < limit) {
@ -2685,26 +2699,27 @@ abstract class BaseScanner implements IScanner {
case '\r':
continue;
case '/':
if (pos + 1 < limit) {
if (buffer[pos + 1] == '/') {
// C++ comment, skip rest of line
skipToNewLine(true);
encounteredComment = true;
return encounteredComment;
} else if (buffer[pos + 1] == '*') {
// C comment, find closing */
for (bufferPos[bufferStackPos] += 2; bufferPos[bufferStackPos] < limit; ++bufferPos[bufferStackPos]) {
pos = bufferPos[bufferStackPos];
if (buffer[pos] == '*' && pos + 1 < limit
&& buffer[pos + 1] == '/') {
++bufferPos[bufferStackPos];
encounteredComment = true;
break;
}
}
continue;
}
}
if (!scanComments) {
if (pos + 1 < limit) {
if (buffer[pos + 1] == '/') {
// C++ comment, skip rest of line
skipToNewLine(true);
return false;
} else if (buffer[pos + 1] == '*') {
// C comment, find closing */
for (bufferPos[bufferStackPos] += 2; bufferPos[bufferStackPos] < limit; ++bufferPos[bufferStackPos]) {
pos = bufferPos[bufferStackPos];
if (buffer[pos] == '*' && pos + 1 < limit
&& buffer[pos + 1] == '/') {
++bufferPos[bufferStackPos];
encounteredComment = true;
break;
}
}
continue;
}
}
}
break;
case '\\':
if (pos + 1 < limit && buffer[pos + 1] == '\n') {
@ -2728,6 +2743,54 @@ abstract class BaseScanner implements IScanner {
--bufferPos[bufferStackPos];
return encounteredComment;
}
protected boolean skipOverWhiteSpaceAndParseComments() {
char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
int pos = bufferPos[bufferStackPos];
// if( pos > 0 && pos < limit && buffer[pos] == '\n')
// return false;
boolean encounteredComment = false;
while (++bufferPos[bufferStackPos] < limit) {
pos = bufferPos[bufferStackPos];
switch (buffer[pos]) {
case ' ':
case '\t':
case '\r':
continue;
case '/':
if (pos + 1 < limit) {
if (buffer[pos + 1] == '/' || buffer[pos + 1] == '*') {
IToken comment = scanComment();
if(comment.getType() == IToken.tBLOCKCOMMENT){
encounteredComment=true;
}
continue;
}
}
break;
case '\\':
if (pos + 1 < limit && buffer[pos + 1] == '\n') {
// \n is a whitespace
++bufferPos[bufferStackPos];
continue;
}
if (pos + 1 < limit && buffer[pos + 1] == '\r') {
if (pos + 2 < limit && buffer[pos + 2] == '\n') {
bufferPos[bufferStackPos] += 2;
continue;
}
}
break;
}
// fell out of switch without continuing, we're done
--bufferPos[bufferStackPos];
return encounteredComment;
}
--bufferPos[bufferStackPos];
return encounteredComment;
}
protected int indexOfNextNonWhiteSpace(char[] buffer, int start, int limit) {
if (start < 0 || start >= buffer.length || limit > buffer.length)
@ -3862,6 +3925,14 @@ abstract class BaseScanner implements IScanner {
contentAssistMode = true;
}
/**
* Turns on/off comment parsing.
* @since 4.0
*/
public void setScanComments(boolean val) {
scanComments= val;
}
protected ParserLanguage getLanguage() {
return language;
}
@ -4095,6 +4166,43 @@ abstract class BaseScanner implements IScanner {
protected int getCurrentOffset() {
return bufferPos[bufferStackPos];
}
protected IToken scanComment() {
char[] buffer = bufferStack[bufferStackPos];
int limit = bufferLimit[bufferStackPos];
int pos = bufferPos[bufferStackPos];
if (pos + 1 < limit) {
if (buffer[pos + 1] == '/') {
// C++ comment
int commentLength = 0;
while (++bufferPos[bufferStackPos] < bufferLimit[bufferStackPos]) {
if (buffer[bufferPos[bufferStackPos]] == '\n'||buffer[bufferPos[bufferStackPos]] == '\r') {
break;
}
++commentLength;
}
// leave the new line there
--bufferPos[bufferStackPos];
return newToken(IToken.tCOMMENT, CharArrayUtils.extract(buffer,
pos, bufferPos[bufferStackPos] - pos + 1));
} else if (buffer[pos + 1] == '*') {
// C comment, find closing */
int start = pos;
for (bufferPos[bufferStackPos] += 2; bufferPos[bufferStackPos] < limit; ++bufferPos[bufferStackPos]) {
pos = bufferPos[bufferStackPos];
if (buffer[pos] == '*' && pos + 1 < limit
&& buffer[pos + 1] == '/') {
++bufferPos[bufferStackPos];
break;
}
}
return newToken(IToken.tBLOCKCOMMENT, CharArrayUtils.extract(
buffer, start, bufferPos[bufferStackPos] - start + 1));
}
}
return null;
}
/*
* (non-Javadoc)

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* Copyright (c) 2004, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -170,4 +170,12 @@ public class CDOM implements IASTServiceProvider {
return defaultService.getTranslationUnit( fileToParse, project );
}
public IASTTranslationUnit getTranslationUnit(IFile fileToParse, boolean parseComments) throws UnsupportedDialectException {
return defaultService.getTranslationUnit(fileToParse, parseComments);
}
public IASTTranslationUnit getTranslationUnit(IFile fileToParse, ICodeReaderFactory fileCreator, boolean parseComments) throws UnsupportedDialectException {
return defaultService.getTranslationUnit(fileToParse, fileCreator, parseComments);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2005 IBM Corporation and others.
* Copyright (c) 2004, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -45,6 +45,16 @@ public interface IASTServiceProvider {
*/
public IASTTranslationUnit getTranslationUnit( IFile fileToParse) throws UnsupportedDialectException;
/**
* Returns a parse tree that represents the content provided as parameters.
*
* @param fileToParse the file in question
* @param parseComments parse commtents flag
* @return syntactical parse tree
* @throws UnsupportedDialectException
*/
public IASTTranslationUnit getTranslationUnit( IFile fileToParse, boolean parseComments) throws UnsupportedDialectException;
/**
* Returns a parse tree that represents the content provided as parameters.
*
@ -75,6 +85,17 @@ public interface IASTServiceProvider {
*/
public IASTTranslationUnit getTranslationUnit( IFile fileToParse, ICodeReaderFactory fileCreator )throws UnsupportedDialectException;
/**
* Returns a parse tree that represents the content provided as parameters.
*
* @param fileToParse the file in question
* @param fileCreator @see CDOM#getCodeReaderFactory(int)
* @param parseComments parse commtents flag
* @return syntactical parse tree
* @throws UnsupportedDialectException
*/
public IASTTranslationUnit getTranslationUnit( IFile fileToParse, ICodeReaderFactory fileCreator, boolean parseComments)throws UnsupportedDialectException;
/**
* Returns a parse tree that represents the content provided as parameters.
*

View file

@ -70,14 +70,14 @@ public class InternalASTServiceProvider implements IASTServiceProvider {
* @see org.eclipse.cdt.core.dom.IASTServiceProvider#getTranslationUnit()
*/
public IASTTranslationUnit getTranslationUnit(IFile fileToParse) throws UnsupportedDialectException {
return getTranslationUnit( fileToParse.getLocation().toOSString(), fileToParse, SavedCodeReaderFactory.getInstance(), null );
return getTranslationUnit( fileToParse.getLocation().toOSString(), fileToParse, SavedCodeReaderFactory.getInstance(), null, false);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.IASTServiceProvider#getTranslationUnit(org.eclipse.cdt.core.dom.ICodeReaderFactory)
*/
public IASTTranslationUnit getTranslationUnit(IFile fileToParse, ICodeReaderFactory fileCreator) throws UnsupportedDialectException {
return getTranslationUnit( fileToParse.getLocation().toOSString(), fileToParse, fileCreator, null );
return getTranslationUnit( fileToParse.getLocation().toOSString(), fileToParse, fileCreator, null, false);
}
/* (non-Javadoc)
@ -85,11 +85,11 @@ public class InternalASTServiceProvider implements IASTServiceProvider {
*/
public IASTTranslationUnit getTranslationUnit(
IFile fileToParse, ICodeReaderFactory fileCreator, IParserConfiguration configuration) throws UnsupportedDialectException {
return getTranslationUnit( fileToParse.getLocation().toOSString(), fileToParse, fileCreator, configuration );
return getTranslationUnit( fileToParse.getLocation().toOSString(), fileToParse, fileCreator, configuration, false);
}
public IASTTranslationUnit getTranslationUnit(
String filename, IResource infoProvider, ICodeReaderFactory fileCreator, IParserConfiguration configuration ) throws UnsupportedDialectException
String filename, IResource infoProvider, ICodeReaderFactory fileCreator, IParserConfiguration configuration, boolean parseComment) throws UnsupportedDialectException
{
IProject project = infoProvider.getProject();
IScannerInfo scanInfo = null;
@ -125,7 +125,8 @@ public class InternalASTServiceProvider implements IASTServiceProvider {
scannerExtensionConfiguration = C_GNU_SCANNER_EXTENSION;
scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE,
l, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, fileCreator );
l, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, fileCreator);
scanner.setScanComments(parseComment);
//assume GCC
if( l == ParserLanguage.C )
parser = new GNUCSourceParser( scanner, ParserMode.COMPLETE_PARSE, ParserUtil.getParserLogService(), new GCCParserExtensionConfiguration() );
@ -138,14 +139,16 @@ public class InternalASTServiceProvider implements IASTServiceProvider {
if( dialect.equals( dialects[0]) || dialect.equals( dialects[2]))
scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE,
ParserLanguage.C,
ParserUtil.getScannerLogService(), C_GNU_SCANNER_EXTENSION, fileCreator );
ParserUtil.getScannerLogService(), C_GNU_SCANNER_EXTENSION, fileCreator);
else if( dialect.equals( dialects[1] ) || dialect.equals( dialects[3] ))
scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE,
ParserLanguage.CPP,
ParserUtil.getScannerLogService(), CPP_GNU_SCANNER_EXTENSION, fileCreator );
ParserUtil.getScannerLogService(), CPP_GNU_SCANNER_EXTENSION, fileCreator);
else
throw new UnsupportedDialectException();
scanner.setScanComments(parseComment);
if( dialect.equals( dialects[0]))
{
ICParserExtensionConfiguration config = new ANSICParserExtensionConfiguration();
@ -263,10 +266,18 @@ public class InternalASTServiceProvider implements IASTServiceProvider {
}
public IASTTranslationUnit getTranslationUnit(IStorage fileToParse, IProject project, ICodeReaderFactory fileCreator) throws UnsupportedDialectException{
return getTranslationUnit( fileToParse.getFullPath().toOSString(), project, fileCreator, null );
return getTranslationUnit( fileToParse.getFullPath().toOSString(), project, fileCreator, null, false);
}
public IASTTranslationUnit getTranslationUnit(IStorage fileToParse, IProject project) throws UnsupportedDialectException {
return getTranslationUnit( fileToParse.getFullPath().toOSString(), project, SavedCodeReaderFactory.getInstance(), null );
return getTranslationUnit( fileToParse.getFullPath().toOSString(), project, SavedCodeReaderFactory.getInstance(), null, false);
}
public IASTTranslationUnit getTranslationUnit(IFile fileToParse, boolean parseComments) throws UnsupportedDialectException {
return getTranslationUnit( fileToParse.getLocation().toOSString(), fileToParse, SavedCodeReaderFactory.getInstance(), null, parseComments);
}
public IASTTranslationUnit getTranslationUnit(IFile fileToParse, ICodeReaderFactory fileCreator, boolean parseComments) throws UnsupportedDialectException {
return getTranslationUnit( fileToParse.getLocation().toOSString(), fileToParse, fileCreator, null, parseComments);
}
}