diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index 50acfbe3b29..bb2f36d83fe 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -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(); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommentTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommentTests.java new file mode 100644 index 00000000000..534c5be879a --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CommentTests.java @@ -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(); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java index 6443534bdd1..5bd6bc1a083 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/AbstractLanguage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/AbstractLanguage.java index 233feb3454b..fd82caf7a52 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/AbstractLanguage.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/AbstractLanguage.java @@ -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 0. + * @param options A combination of + * {@link #OPTION_SKIP_FUNCTION_BODIES} and {@link #OPTION_ADD_COMMENTS} or 0. * @param log logger * @return an AST for the source code provided by reader. * @throws CoreException diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java index 3064a87cdc0..50976c90aa4 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java @@ -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 null * @param style 0 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 null * @throws CoreException * @since 4.0 diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index 8d23bc99268..5a448b34fb7 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -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()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java index 555da638d2b..5ede1617801 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTComment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTComment.java new file mode 100644 index 00000000000..d3e91101ac3 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTComment.java @@ -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(); + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java index e38e72410a4..4d1b0a093eb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java @@ -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 IASTComment[] + * @since 4.0 + */ + public IASTComment[] getComments(); + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/AbstractCLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/AbstractCLanguage.java index 24c1fd3c147..40ba0f24603 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/AbstractCLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/c/AbstractCLanguage.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/AbstractCPPLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/AbstractCPPLanguage.java index 2d2b22322fb..7130c2e1545 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/AbstractCPPLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/AbstractCPPLanguage.java @@ -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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScanner.java index 9b6e3a8745b..302537597a1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScanner.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IToken.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IToken.java index 13c7261fbbf..014ed3731f5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IToken.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IToken.java @@ -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; + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java index 2e99007fc99..f7b8ef9434b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java @@ -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= 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) diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/CDOM.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/CDOM.java index ba3c8e96ca4..cfde8a94032 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/CDOM.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/CDOM.java @@ -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); + } + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/IASTServiceProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/IASTServiceProvider.java index 98151954c1f..27b0b42d6c4 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/IASTServiceProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/IASTServiceProvider.java @@ -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. * diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java index 2132734bd5d..264e16c1f5b 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java @@ -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); + } }