From 452e82cb3d7129bd42a54ef8c9f7124c20ccbfbb Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Wed, 16 Apr 2003 12:30:47 +0000 Subject: [PATCH] Patch for John Camelon: CORE Fixed bug36434 - Broken outline in winbase.h Partial Fix for bug36379 - The parser to set Line informations when scanning. Fixed CModelManager to include header files with .H extension as C++ headers. Fixed bug36448 - Parser fails for C programs containing C++ keywords as identifiers TESTS Added ScannerTestCase::testBug36434(). Added ScannerTestCase::testMultipleLines(). Added ParserTestSuite. Added LineNumberTest. Updated CModelElementsTests to set the Nature of the C++ project appropriately. --- .../cdt/internal/core/dom/ClassSpecifier.java | 29 ++ .../cdt/internal/core/dom/DOMBuilder.java | 41 ++- .../core/dom/EnumerationSpecifier.java | 32 ++ .../core/dom/EnumeratorDefinition.java | 30 ++ .../cdt/internal/core/dom/IOffsetable.java | 6 + .../core/dom/NamespaceDefinition.java | 28 ++ .../core/dom/PreprocessorStatement.java | 29 ++ .../internal/core/dom/SimpleDeclaration.java | 29 ++ .../core/dom/TemplateDeclaration.java | 30 ++ .../internal/core/model/CModelManager.java | 2 +- core/org.eclipse.cdt.core/parser/ChangeLog | 6 + .../internal/core/model/CModelBuilder.java | 13 +- .../internal/core/parser/ContextStack.java | 34 +- .../core/parser/ExpressionEvaluator.java | 6 + .../cdt/internal/core/parser/IParser.java | 29 ++ .../internal/core/parser/IParserCallback.java | 2 + .../cdt/internal/core/parser/IScanner.java | 3 +- .../internal/core/parser/IScannerContext.java | 1 - .../core/parser/NullParserCallback.java | 6 + .../internal/core/parser/OffsetMapping.java | 75 +++++ .../cdt/internal/core/parser/Parser.java | 22 +- .../cdt/internal/core/parser/Scanner.java | 301 +++++++++++------- .../internal/core/parser/ScannerContext.java | 1 + .../cdt/internal/core/parser/Token.java | 6 +- core/org.eclipse.cdt.ui.tests/ChangeLog | 7 + .../core/model/tests/CModelElementsTests.java | 18 +- .../cdt/core/parser/resources/OffsetTest.h | 43 +++ .../cdt/core/parser/tests/DOMTests.java | 3 +- .../cdt/core/parser/tests/ExprEvalTest.java | 3 +- .../cdt/core/parser/tests/LineNumberTest.java | 151 +++++++++ .../core/parser/tests/ParserTestSuite.java | 39 +++ .../core/parser/tests/ScannerTestCase.java | 24 ++ 32 files changed, 915 insertions(+), 134 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParser.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/OffsetMapping.java create mode 100644 core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/resources/OffsetTest.h create mode 100644 core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/LineNumberTest.java create mode 100644 core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/ClassSpecifier.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/ClassSpecifier.java index c0ec0b6e566..33b1339bad6 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/ClassSpecifier.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/ClassSpecifier.java @@ -11,6 +11,7 @@ public class ClassSpecifier extends TypeSpecifier implements IScope, IOffsetable private AccessSpecifier access = new AccessSpecifier( AccessSpecifier.v_private ); private ClassKey key = new ClassKey(); private int startingOffset = 0, totalLength = 0; + private int topLine = 0, bottomLine = 0; private Token classKeyToken = null; public int getClassKey() { return key.getClassKey(); } @@ -98,4 +99,32 @@ public class ClassSpecifier extends TypeSpecifier implements IScope, IOffsetable this.classKeyToken = classKeyToken; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int) + */ + public void setTopLine(int lineNumber) { + topLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int) + */ + public void setBottomLine(int lineNumber) { + bottomLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine() + */ + public int getTopLine() { + return topLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine() + */ + public int getBottomLine() { + return bottomLine; + } + } diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/DOMBuilder.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/DOMBuilder.java index 27d6ded71a7..ae7157f5297 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/DOMBuilder.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/DOMBuilder.java @@ -1,6 +1,7 @@ package org.eclipse.cdt.internal.core.dom; +import org.eclipse.cdt.internal.core.parser.IParser; import org.eclipse.cdt.internal.core.parser.IParserCallback; import org.eclipse.cdt.internal.core.parser.Token; @@ -55,6 +56,7 @@ public class DOMBuilder implements IParserCallback ClassSpecifier classSpecifier = new ClassSpecifier(kind, decl); classSpecifier.setVisibility( visibility ); classSpecifier.setStartingOffset( classKey.getOffset() ); + classSpecifier.setTopLine( parser.getLineNumberForOffset(classKey.getOffset()) ); classSpecifier.setClassKeyToken( classKey ); decl.setTypeSpecifier(classSpecifier); return classSpecifier; @@ -73,6 +75,7 @@ public class DOMBuilder implements IParserCallback public void classSpecifierEnd(Object classSpecifier, Token closingBrace) { ClassSpecifier c = (ClassSpecifier)classSpecifier; c.setTotalLength( closingBrace.getOffset() + closingBrace.getLength() - c.getStartingOffset() ); + c.setBottomLine( parser.getLineNumberForOffset(closingBrace.getOffset()) ); } /** @@ -158,7 +161,11 @@ public class DOMBuilder implements IParserCallback * @see org.eclipse.cdt.internal.core.newparser.IParserCallback#inclusionBegin(java.lang.String) */ public void inclusionBegin(String includeFile, int offset, int inclusionBeginOffset) { - translationUnit.addInclusion( new Inclusion( includeFile, offset, inclusionBeginOffset, offset - inclusionBeginOffset + includeFile.length() + 1 ) ); + Inclusion inclusion = new Inclusion( includeFile, offset, inclusionBeginOffset, offset - inclusionBeginOffset + includeFile.length() + 1 ); + int lineNo = parser.getLineNumberForOffset(offset); + inclusion.setTopLine(lineNo); + inclusion.setBottomLine( lineNo ); + translationUnit.addInclusion( inclusion ); } /** @@ -171,7 +178,10 @@ public class DOMBuilder implements IParserCallback * @see org.eclipse.cdt.internal.core.newparser.IParserCallback#macro(java.lang.String) */ public void macro(String macroName, int offset, int macroBeginOffset, int macroEndOffset) { - translationUnit.addMacro( new Macro( macroName, offset, macroBeginOffset, macroEndOffset - macroBeginOffset)); + Macro macro = new Macro( macroName, offset, macroBeginOffset, macroEndOffset - macroBeginOffset); + macro.setTopLine( parser.getLineNumberForOffset(macroBeginOffset)); + macro.setBottomLine( parser.getLineNumberForOffset(macroEndOffset)); + translationUnit.addMacro( macro ); } /** @@ -182,6 +192,7 @@ public class DOMBuilder implements IParserCallback if( container instanceof IAccessable ) decl.setAccessSpecifier(new AccessSpecifier( ((IAccessable)container).getVisibility() )); ((IOffsetable)decl).setStartingOffset( firstToken.getOffset() ); + ((IOffsetable)decl).setTopLine( parser.getLineNumberForOffset(firstToken.getOffset()) ); return decl; } @@ -191,11 +202,8 @@ public class DOMBuilder implements IParserCallback public void simpleDeclarationEnd(Object declaration, Token lastToken) { SimpleDeclaration decl = (SimpleDeclaration)declaration; IOffsetable offsetable = (IOffsetable)decl; - // TODO Kludge solve me! - if( lastToken != null ) - offsetable.setTotalLength( lastToken.getOffset() + lastToken.getLength() - offsetable.getStartingOffset()); - else - offsetable.setTotalLength( 0 ); + offsetable.setTotalLength( lastToken.getOffset() + lastToken.getLength() - offsetable.getStartingOffset()); + offsetable.setBottomLine( parser.getLineNumberForOffset(lastToken.getOffset() ) ); decl.getOwnerScope().addDeclaration(decl); } @@ -511,6 +519,7 @@ public class DOMBuilder implements IParserCallback NamespaceDefinition namespaceDef = new NamespaceDefinition(ownerScope); namespaceDef.setStartToken(namespace); ((IOffsetable)namespaceDef).setStartingOffset( namespace.getOffset() ); + ((IOffsetable)namespaceDef).setTopLine( parser.getLineNumberForOffset(namespace.getOffset()) ); return namespaceDef; } @@ -535,6 +544,7 @@ public class DOMBuilder implements IParserCallback public void namespaceDefinitionEnd(Object namespace, Token closingBrace) { NamespaceDefinition ns = (NamespaceDefinition)namespace; ns.setTotalLength( closingBrace.getOffset() + closingBrace.getLength() - ns.getStartingOffset() ); + ns.setBottomLine( parser.getLineNumberForOffset(closingBrace.getOffset())); ns.getOwnerScope().addDeclaration(ns); } @@ -626,7 +636,8 @@ public class DOMBuilder implements IParserCallback EnumerationSpecifier es = new EnumerationSpecifier( decl ); es.setStartToken(enumKey); decl.setTypeSpecifier(es); - ((IOffsetable)es).setStartingOffset( enumKey.getOffset() ); + ((IOffsetable)es).setStartingOffset( enumKey.getOffset() ); + ((IOffsetable)es).setStartingOffset( parser.getLineNumberForOffset(enumKey.getOffset()) ); return es; } @@ -652,6 +663,7 @@ public class DOMBuilder implements IParserCallback public void enumSpecifierEnd(Object enumSpec, Token closingBrace) { IOffsetable offsetable = (IOffsetable)enumSpec; offsetable.setTotalLength( closingBrace.getOffset() + closingBrace.getLength() - offsetable.getStartingOffset()); + offsetable.setBottomLine( parser.getLineNumberForOffset(closingBrace.getOffset()) ); } /* (non-Javadoc) @@ -671,6 +683,7 @@ public class DOMBuilder implements IParserCallback EnumeratorDefinition definition = (EnumeratorDefinition)enumDefn; definition.setName( currName ); ((IOffsetable)enumDefn).setStartingOffset( currName.getStartOffset() ); + ((IOffsetable)enumDefn).setTopLine(parser.getLineNumberForOffset(currName.getStartOffset())); } /* (non-Javadoc) @@ -679,6 +692,7 @@ public class DOMBuilder implements IParserCallback public void enumeratorEnd(Object enumDefn, Token lastToken) { IOffsetable offsetable = (IOffsetable)enumDefn; offsetable.setTotalLength( lastToken.getOffset() + lastToken.getLength() - offsetable.getStartingOffset()); + offsetable.setBottomLine(parser.getLineNumberForOffset(lastToken.getOffset() )); } /* (non-Javadoc) @@ -799,6 +813,7 @@ public class DOMBuilder implements IParserCallback */ public Object templateDeclarationBegin(Object container, Token exported) { TemplateDeclaration d = new TemplateDeclaration( (IScope)container, exported ); + d.setTopLine( parser.getLineNumberForOffset(exported.getOffset()) ); if( container instanceof IAccessable ) d.setVisibility( ((IAccessable)container).getVisibility() ); return d; @@ -817,6 +832,7 @@ public class DOMBuilder implements IParserCallback public void templateDeclarationEnd(Object templateDecl, Token lastToken) { TemplateDeclaration decl = (TemplateDeclaration)templateDecl; decl.setLastToken(lastToken); + decl.setBottomLine( parser.getLineNumberForOffset(lastToken.getOffset()) ); decl.getOwnerScope().addDeclaration(decl); } @@ -895,4 +911,13 @@ public class DOMBuilder implements IParserCallback */ public void templateParameterListEnd(Object parameterList) { } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.IParserCallback#setParser(org.eclipse.cdt.internal.core.parser.IParser) + */ + public void setParser(IParser parser) { + this.parser = parser; + } + + private IParser parser = null; } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/EnumerationSpecifier.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/EnumerationSpecifier.java index 72f9872ff2f..0b16aa0f2de 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/EnumerationSpecifier.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/EnumerationSpecifier.java @@ -105,4 +105,36 @@ public class EnumerationSpecifier extends TypeSpecifier implements IOffsetable { this.startToken = startToken; } + private int topLine = 0, bottomLine = 0; + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int) + */ + public void setTopLine(int lineNumber) { + topLine = lineNumber; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int) + */ + public void setBottomLine(int lineNumber) { + bottomLine = lineNumber; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine() + */ + public int getTopLine() { + return topLine; + } + + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine() + */ + public int getBottomLine() { + return bottomLine; + } + } diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/EnumeratorDefinition.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/EnumeratorDefinition.java index badccc44f12..a40fae91553 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/EnumeratorDefinition.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/EnumeratorDefinition.java @@ -80,4 +80,34 @@ public class EnumeratorDefinition implements IExpressionOwner, IOffsetable { totalLength = i; } + int bottomLine = 0, topLine = 0; + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int) + */ + public void setTopLine(int lineNumber) { + topLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int) + */ + public void setBottomLine(int lineNumber) { + bottomLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine() + */ + public int getTopLine() { + return topLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine() + */ + public int getBottomLine() { + return bottomLine; + } + } diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/IOffsetable.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/IOffsetable.java index a836493e6e2..a6b6f4ee55c 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/IOffsetable.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/IOffsetable.java @@ -35,4 +35,10 @@ public interface IOffsetable { * @param i */ public abstract void setTotalLength(int i); + + public abstract void setTopLine( int lineNumber ); + public abstract void setBottomLine( int lineNumber ); + public abstract int getTopLine(); + public abstract int getBottomLine(); + } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/NamespaceDefinition.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/NamespaceDefinition.java index c2ad8204ceb..9db66df2db9 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/NamespaceDefinition.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/NamespaceDefinition.java @@ -109,4 +109,32 @@ public class NamespaceDefinition extends Declaration implements IScope, IOffseta this.startToken = startToken; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int) + */ + public void setTopLine(int lineNumber) { + topLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int) + */ + public void setBottomLine(int lineNumber) { + bottomLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine() + */ + public int getTopLine() { + return topLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine() + */ + public int getBottomLine() { + return bottomLine; + } + private int topLine = 0, bottomLine = 0; } diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/PreprocessorStatement.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/PreprocessorStatement.java index 089dff537f8..c9927b430a3 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/PreprocessorStatement.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/PreprocessorStatement.java @@ -75,4 +75,33 @@ public class PreprocessorStatement implements IOffsetable { totalLength = i; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int) + */ + public void setTopLine(int lineNumber) { + topLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int) + */ + public void setBottomLine(int lineNumber) { + bottomLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine() + */ + public int getTopLine() { + return topLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine() + */ + public int getBottomLine() { + return bottomLine; + } + private int topLine = 0, bottomLine = 0; + } diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/SimpleDeclaration.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/SimpleDeclaration.java index 8d564e4dddc..da3c78f0c41 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/SimpleDeclaration.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/SimpleDeclaration.java @@ -114,4 +114,33 @@ public class SimpleDeclaration extends Declaration implements DeclSpecifier.ICon totalLength = i; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int) + */ + public void setTopLine(int lineNumber) { + topLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int) + */ + public void setBottomLine(int lineNumber) { + bottomLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine() + */ + public int getTopLine() { + return topLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine() + */ + public int getBottomLine() { + return bottomLine; + } + private int topLine = 0, bottomLine = 0; + } diff --git a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/TemplateDeclaration.java b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/TemplateDeclaration.java index f71a30029fd..41cfe7900b6 100644 --- a/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/TemplateDeclaration.java +++ b/core/org.eclipse.cdt.core/dom/org/eclipse/cdt/internal/core/dom/TemplateDeclaration.java @@ -144,4 +144,34 @@ public class TemplateDeclaration extends Declaration implements IScope, IAccessa else this.visibility.setAccess(visibility); } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setTopLine(int) + */ + public void setTopLine(int lineNumber) { + topLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#setBottomLine(int) + */ + public void setBottomLine(int lineNumber) { + bottomLine = lineNumber; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getTopLine() + */ + public int getTopLine() { + return topLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.IOffsetable#getBottomLine() + */ + public int getBottomLine() { + return bottomLine; + } + private int topLine = 0, bottomLine = 0; + + } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java index 81f77f13279..57712d2a9fa 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java @@ -101,7 +101,7 @@ public class CModelManager implements IResourceChangeListener { public static final String [] sourceExtensions = {"c", "cxx", "cc", "C", "cpp"}; - public static final String [] headerExtensions = {"h", "hh", "hpp"}; + public static final String [] headerExtensions = {"h", "hh", "hpp", "H"}; static CModelManager factory = null; diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog b/core/org.eclipse.cdt.core/parser/ChangeLog index 804314b57fd..bf7079bdee4 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog +++ b/core/org.eclipse.cdt.core/parser/ChangeLog @@ -1,3 +1,9 @@ +2003-04-15 John Camelon + Fixed bug36434 - Broken outline in winbase.h + Partial Fix for bug36379 - The parser to set Line informations when scanning. + Fixed CModelManager to include header files with .H extension as C++ headers. + Fixed bug36448 - Parser fails for C programs containing C++ keywords as identifiers + 2003-04-15 Andrew Niefer Added scanner support to fix Bug36047 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/model/CModelBuilder.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/model/CModelBuilder.java index f0e3dbb240b..530261a8c10 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/model/CModelBuilder.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/model/CModelBuilder.java @@ -46,6 +46,7 @@ import org.eclipse.cdt.internal.core.dom.TemplateDeclaration; import org.eclipse.cdt.internal.core.dom.TemplateParameter; import org.eclipse.cdt.internal.core.dom.TranslationUnit; import org.eclipse.cdt.internal.core.dom.TypeSpecifier; +import org.eclipse.cdt.internal.core.parser.IParser; import org.eclipse.cdt.internal.core.parser.Parser; import org.eclipse.core.resources.IProject; @@ -62,14 +63,22 @@ public class CModelBuilder { public Map parse() throws Exception { DOMBuilder domBuilder = new DOMBuilder(); String code = translationUnit.getBuffer().getContents(); - Parser parser = new Parser(code, domBuilder, true); + IParser parser = new Parser(code, domBuilder, true); if( translationUnit.getCProject() != null ) { IProject currentProject = translationUnit.getCProject().getProject(); boolean hasCppNature = CoreModel.getDefault().hasCCNature(currentProject); parser.setCppNature(hasCppNature); } - parser.parse(); + try + { + parser.parse(); + } + catch( Exception e ) + { + System.out.println( "Parse Exception in Outline View" ); + e.printStackTrace(); + } long startTime = System.currentTimeMillis(); generateModelElements(domBuilder.getTranslationUnit()); System.out.println("CModel build: "+ ( System.currentTimeMillis() - startTime ) + "ms" ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ContextStack.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ContextStack.java index d989fb40406..a174eeac7ec 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ContextStack.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ContextStack.java @@ -51,7 +51,9 @@ public class ContextStack { if( currentContext != null ) contextStack.push(currentContext); - currentContext = context; + currentContext = context; + if( context.getKind() == IScannerContext.TOP ) + topContext = context; } public boolean rollbackContext() { @@ -118,13 +120,35 @@ public class ContextStack { return currentContext; } - private IScannerContext currentContext; - + private IScannerContext currentContext, topContext; private Stack contextStack = new Stack(); private LinkedList undoStack = new LinkedList(); - - private Set inclusions = new HashSet(); private Set defines = new HashSet(); + private OffsetMapping offsetLineMap = new OffsetMapping(); + /** + * @return + */ + public IScannerContext getTopContext() { + return topContext; + } + + public int mapOffsetToLineNumber( int offset ) + { + return offsetLineMap.getLineNo(offset); + } + + public void newLine() + { + if( currentContext == topContext ) + offsetLineMap.newLine( topContext.getOffset() ); + } + + public void recantNewline() + { + if( currentContext == topContext ) + offsetLineMap.recantLastNewLine(); + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionEvaluator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionEvaluator.java index 2b335c0100e..c8ca9e0ad6d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionEvaluator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ExpressionEvaluator.java @@ -693,4 +693,10 @@ public class ExpressionEvaluator implements IParserCallback { */ public void templateParameterListEnd(Object parameterList) { } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.IParserCallback#setParser(org.eclipse.cdt.internal.core.parser.IParser) + */ + public void setParser(IParser parser) { + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParser.java new file mode 100644 index 00000000000..73a90959423 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParser.java @@ -0,0 +1,29 @@ +/* + * Created on Apr 14, 2003 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package org.eclipse.cdt.internal.core.parser; + +import org.eclipse.cdt.internal.core.parser.Parser.Backtrack; + +/** + * @author jcamelon + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public interface IParser { + public abstract boolean parse() throws Backtrack; + public abstract void expression(Object expression) throws Backtrack; + /** + * @return + */ + public abstract boolean isCppNature(); + /** + * @param b + */ + public abstract void setCppNature(boolean b); + public abstract int getLineNumberForOffset(int offset); +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserCallback.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserCallback.java index 326a78ebac5..df04f91e4a7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserCallback.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IParserCallback.java @@ -12,6 +12,8 @@ package org.eclipse.cdt.internal.core.parser; public interface IParserCallback { + public void setParser( IParser parser ); + public Object translationUnitBegin(); public void translationUnitEnd(Object unit); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IScanner.java index f3f089b3b3c..9b88ff90a22 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IScanner.java @@ -28,7 +28,8 @@ public interface IScanner { public void overwriteIncludePath( List newIncludePaths ); public Token nextToken() throws ScannerException, Parser.EndOfFile; - + public int getLineNumberForOffset(int offset); + public void setCppNature( boolean value ); public void setQuickScan(boolean qs); public void setCallback(IParserCallback c); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IScannerContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IScannerContext.java index 2b0ec9b24ac..b14d140a9f5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IScannerContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/IScannerContext.java @@ -28,7 +28,6 @@ public interface IScannerContext { int popUndo(); void pushUndo(int undo); - int getKind(); void setKind( int kind ); } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/NullParserCallback.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/NullParserCallback.java index 01117329717..0ae19105412 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/NullParserCallback.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/NullParserCallback.java @@ -608,4 +608,10 @@ public class NullParserCallback implements IParserCallback { public void templateParameterListEnd(Object parameterList) { } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.IParserCallback#setParser(org.eclipse.cdt.internal.core.parser.IParser) + */ + public void setParser(IParser parser) { + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/OffsetMapping.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/OffsetMapping.java new file mode 100644 index 00000000000..240049fa9c3 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/OffsetMapping.java @@ -0,0 +1,75 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.internal.core.parser; + +import java.util.Iterator; +import java.util.SortedMap; +import java.util.TreeMap; + + + +/** + * @author jcamelon + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class OffsetMapping { + + public OffsetMapping() + { + } + + public void newLine( int offset ) + { + lastOffset = offset; + store.put( new Integer( offset ), new Integer( ++lineCounter ) ); + } + + public void recantLastNewLine() + { + if( store.remove( new Integer( lastOffset ) ) != null ) + { + --lineCounter; + lastOffset = -1; + } + } + + public int getLineNo( int offset ) + { + Iterator iter = store.keySet().iterator(); + int first = -1, second = -1; + if( ! iter.hasNext() ) return 1; + first = ((Integer)iter.next()).intValue(); + if( ( offset <= first ) || ! iter.hasNext() ) + return ((Integer)store.get( new Integer( first ))).intValue(); + + while( true ) + { + second = ((Integer)iter.next()).intValue(); + if( offset > first && offset <= second ) + return ((Integer)store.get( new Integer( second ))).intValue(); + if( ! iter.hasNext() ) break; + first = second; + } + + return lineCounter; + } + + public int getCurrentLineNumber() + { + return lineCounter; + } + + private int lineCounter = 1; + private int lastOffset = -1; + private SortedMap store = new TreeMap(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index 5c8d0bc30d5..7d743013be3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -17,13 +17,18 @@ import java.io.StringReader; import java.util.HashMap; import java.util.Map; -public class Parser { +public class Parser implements IParser { private IParserCallback callback; private boolean quickParse = false; private boolean parsePassed = true; private boolean cppNature = true; + protected void failParse() + { + parsePassed = false; + } + // TO DO: convert to a real symbol table private Map currRegion = new HashMap(); @@ -83,6 +88,7 @@ c, quick); * */ protected void translationUnit() throws Backtrack { + try { callback.setParser( this ); } catch( Exception e) {} Object translationUnit = null; try{ translationUnit = callback.translationUnitBegin();} catch( Exception e ) {} Token lastBacktrack = null; @@ -98,7 +104,7 @@ c, quick); break; } catch (Backtrack b) { // Mark as failure and try to reach a recovery point - parsePassed = false; + failParse(); if (lastBacktrack != null && lastBacktrack == LA(1)) { // we haven't progressed from the last backtrack @@ -109,12 +115,16 @@ c, quick); lastBacktrack = LA(1); } } + catch( Exception e ) + { + failParse(); + } } try{ callback.translationUnitEnd(translationUnit);} catch( Exception e ) {} } protected void consumeToNextSemicolon() throws EndOfFile { - parsePassed = false; + failParse(); consume(); // TODO - we should really check for matching braces too while (LT(1) != Token.tSEMI) { @@ -2252,6 +2262,12 @@ c, quick); */ public void setCppNature(boolean b) { cppNature = b; + if( scanner != null ) + scanner.setCppNature( b ); } + public int getLineNumberForOffset(int offset) + { + return scanner.getLineNumberForOffset(offset); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Scanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Scanner.java index 1cd0b62bc23..47f89912a1e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Scanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Scanner.java @@ -295,7 +295,8 @@ public class Scanner implements IScanner { private StringBuffer storageBuffer = null; private int count = 0; - private static HashMap keywords = new HashMap(); + private static HashMap cppKeywords = new HashMap(); + private static HashMap cKeywords = new HashMap(); private static HashMap ppDirectives = new HashMap(); private Token currentToken = null; @@ -378,18 +379,30 @@ public class Scanner implements IScanner { if (c == '\r') { c = getChar(false); if (c == '\n') + { c = getChar(false); + } } else if (c == '\n') + { + contextStack.newLine(); c = getChar(false); + if( c == '\n') + contextStack.newLine(); + } } + else if( c == '\n' ) + contextStack.newLine(); + } + else if( c == '\n' ) + contextStack.newLine(); + return c; } private void ungetChar(int c) throws ScannerException{ - // Should really check whether there already is a char there - // If so, we should be using a buffer, instead of a single char contextStack.getCurrentContext().pushUndo(c); + if( c == '\n' ) contextStack.recantNewline(); contextStack.undoRollback( lastContext ); } @@ -544,7 +557,13 @@ public class Scanner implements IScanner { } } - Object tokenTypeObject = keywords.get(ident); + Object tokenTypeObject; + + if( cppNature ) + tokenTypeObject = cppKeywords.get(ident); + else + tokenTypeObject = cKeywords.get(ident); + int tokenType = Token.tIDENTIFIER; if (tokenTypeObject != null) tokenType = ((Integer) tokenTypeObject).intValue(); @@ -1241,85 +1260,83 @@ public class Scanner implements IScanner { } static { - keywords.put("and", new Integer(Token.t_and)); - keywords.put("and_eq", new Integer(Token.t_and_eq)); - keywords.put("asm", new Integer(Token.t_asm)); - keywords.put("auto", new Integer(Token.t_auto)); - keywords.put("bitand", new Integer(Token.t_bitand)); - keywords.put("bitor", new Integer(Token.t_bitor)); - keywords.put("bool", new Integer(Token.t_bool)); - keywords.put("break", new Integer(Token.t_break)); - keywords.put("case", new Integer(Token.t_case)); - keywords.put("catch", new Integer(Token.t_catch)); - keywords.put("char", new Integer(Token.t_char)); - keywords.put("class", new Integer(Token.t_class)); - keywords.put("compl", new Integer(Token.t_compl)); - keywords.put("const", new Integer(Token.t_const)); - keywords.put("const_cast", new Integer(Token.t_const_cast)); - keywords.put("continue", new Integer(Token.t_continue)); - keywords.put("default", new Integer(Token.t_default)); - keywords.put("delete", new Integer(Token.t_delete)); - keywords.put("do", new Integer(Token.t_do)); - keywords.put("double", new Integer(Token.t_double)); - keywords.put("dynamic_cast", new Integer(Token.t_dynamic_cast)); - keywords.put("else", new Integer(Token.t_else)); - keywords.put("enum", new Integer(Token.t_enum)); - keywords.put("explicit", new Integer(Token.t_explicit)); - keywords.put("export", new Integer(Token.t_export)); - keywords.put("extern", new Integer(Token.t_extern)); - keywords.put("false", new Integer(Token.t_false)); - keywords.put("float", new Integer(Token.t_float)); - keywords.put("for", new Integer(Token.t_for)); - keywords.put("friend", new Integer(Token.t_friend)); - keywords.put("goto", new Integer(Token.t_goto)); - keywords.put("if", new Integer(Token.t_if)); - keywords.put("inline", new Integer(Token.t_inline)); - keywords.put("int", new Integer(Token.t_int)); - keywords.put("long", new Integer(Token.t_long)); - keywords.put("mutable", new Integer(Token.t_mutable)); - keywords.put("namespace", new Integer(Token.t_namespace)); - keywords.put("new", new Integer(Token.t_new)); - keywords.put("not", new Integer(Token.t_not)); - keywords.put("not_eq", new Integer(Token.t_not_eq)); - keywords.put("operator", new Integer(Token.t_operator)); - keywords.put("or", new Integer(Token.t_or)); - keywords.put("or_eq", new Integer(Token.t_or_eq)); - keywords.put("private", new Integer(Token.t_private)); - keywords.put("protected", new Integer(Token.t_protected)); - keywords.put("public", new Integer(Token.t_public)); - keywords.put("register", new Integer(Token.t_register)); - keywords.put("reinterpret_cast", new Integer(Token.t_reinterpret_cast)); - keywords.put("return", new Integer(Token.t_return)); - keywords.put("short", new Integer(Token.t_short)); - keywords.put("signed", new Integer(Token.t_signed)); - keywords.put("sizeof", new Integer(Token.t_sizeof)); - keywords.put("static", new Integer(Token.t_static)); - keywords.put("static_cast", new Integer(Token.t_static_cast)); - keywords.put("struct", new Integer(Token.t_struct)); - keywords.put("switch", new Integer(Token.t_switch)); - keywords.put("template", new Integer(Token.t_template)); - keywords.put("this", new Integer(Token.t_this)); - keywords.put("throw", new Integer(Token.t_throw)); - keywords.put("true", new Integer(Token.t_true)); - keywords.put("try", new Integer(Token.t_try)); - keywords.put("typedef", new Integer(Token.t_typedef)); - keywords.put("typeid", new Integer(Token.t_typeid)); - keywords.put("typename", new Integer(Token.t_typename)); - keywords.put("union", new Integer(Token.t_union)); - keywords.put("unsigned", new Integer(Token.t_unsigned)); - keywords.put("using", new Integer(Token.t_using)); - keywords.put("virtual", new Integer(Token.t_virtual)); - keywords.put("void", new Integer(Token.t_void)); - keywords.put("volatile", new Integer(Token.t_volatile)); - keywords.put("wchar_t", new Integer(Token.t_wchar_t)); - keywords.put("while", new Integer(Token.t_while)); - keywords.put("xor", new Integer(Token.t_xor)); - keywords.put("xor_eq", new Integer(Token.t_xor_eq)); + cppKeywords.put("and", new Integer(Token.t_and)); + cppKeywords.put("and_eq", new Integer(Token.t_and_eq)); + cppKeywords.put("asm", new Integer(Token.t_asm)); + cppKeywords.put("auto", new Integer(Token.t_auto)); + cppKeywords.put("bitand", new Integer(Token.t_bitand)); + cppKeywords.put("bitor", new Integer(Token.t_bitor)); + cppKeywords.put("bool", new Integer(Token.t_bool)); + cppKeywords.put("break", new Integer(Token.t_break)); + cppKeywords.put("case", new Integer(Token.t_case)); + cppKeywords.put("catch", new Integer(Token.t_catch)); + cppKeywords.put("char", new Integer(Token.t_char)); + cppKeywords.put("class", new Integer(Token.t_class)); + cppKeywords.put("compl", new Integer(Token.t_compl)); + cppKeywords.put("const", new Integer(Token.t_const)); + cppKeywords.put("const_cast", new Integer(Token.t_const_cast)); + cppKeywords.put("continue", new Integer(Token.t_continue)); + cppKeywords.put("default", new Integer(Token.t_default)); + cppKeywords.put("delete", new Integer(Token.t_delete)); + cppKeywords.put("do", new Integer(Token.t_do)); + cppKeywords.put("double", new Integer(Token.t_double)); + cppKeywords.put("dynamic_cast", new Integer(Token.t_dynamic_cast)); + cppKeywords.put("else", new Integer(Token.t_else)); + cppKeywords.put("enum", new Integer(Token.t_enum)); + cppKeywords.put("explicit", new Integer(Token.t_explicit)); + cppKeywords.put("export", new Integer(Token.t_export)); + cppKeywords.put("extern", new Integer(Token.t_extern)); + cppKeywords.put("false", new Integer(Token.t_false)); + cppKeywords.put("float", new Integer(Token.t_float)); + cppKeywords.put("for", new Integer(Token.t_for)); + cppKeywords.put("friend", new Integer(Token.t_friend)); + cppKeywords.put("goto", new Integer(Token.t_goto)); + cppKeywords.put("if", new Integer(Token.t_if)); + cppKeywords.put("inline", new Integer(Token.t_inline)); + cppKeywords.put("int", new Integer(Token.t_int)); + cppKeywords.put("long", new Integer(Token.t_long)); + cppKeywords.put("mutable", new Integer(Token.t_mutable)); + cppKeywords.put("namespace", new Integer(Token.t_namespace)); + cppKeywords.put("new", new Integer(Token.t_new)); + cppKeywords.put("not", new Integer(Token.t_not)); + cppKeywords.put("not_eq", new Integer(Token.t_not_eq)); + cppKeywords.put("operator", new Integer(Token.t_operator)); + cppKeywords.put("or", new Integer(Token.t_or)); + cppKeywords.put("or_eq", new Integer(Token.t_or_eq)); + cppKeywords.put("private", new Integer(Token.t_private)); + cppKeywords.put("protected", new Integer(Token.t_protected)); + cppKeywords.put("public", new Integer(Token.t_public)); + cppKeywords.put("register", new Integer(Token.t_register)); + cppKeywords.put("reinterpret_cast", new Integer(Token.t_reinterpret_cast)); + cppKeywords.put("return", new Integer(Token.t_return)); + cppKeywords.put("short", new Integer(Token.t_short)); + cppKeywords.put("signed", new Integer(Token.t_signed)); + cppKeywords.put("sizeof", new Integer(Token.t_sizeof)); + cppKeywords.put("static", new Integer(Token.t_static)); + cppKeywords.put("static_cast", new Integer(Token.t_static_cast)); + cppKeywords.put("struct", new Integer(Token.t_struct)); + cppKeywords.put("switch", new Integer(Token.t_switch)); + cppKeywords.put("template", new Integer(Token.t_template)); + cppKeywords.put("this", new Integer(Token.t_this)); + cppKeywords.put("throw", new Integer(Token.t_throw)); + cppKeywords.put("true", new Integer(Token.t_true)); + cppKeywords.put("try", new Integer(Token.t_try)); + cppKeywords.put("typedef", new Integer(Token.t_typedef)); + cppKeywords.put("typeid", new Integer(Token.t_typeid)); + cppKeywords.put("typename", new Integer(Token.t_typename)); + cppKeywords.put("union", new Integer(Token.t_union)); + cppKeywords.put("unsigned", new Integer(Token.t_unsigned)); + cppKeywords.put("using", new Integer(Token.t_using)); + cppKeywords.put("virtual", new Integer(Token.t_virtual)); + cppKeywords.put("void", new Integer(Token.t_void)); + cppKeywords.put("volatile", new Integer(Token.t_volatile)); + cppKeywords.put("wchar_t", new Integer(Token.t_wchar_t)); + cppKeywords.put("while", new Integer(Token.t_while)); + cppKeywords.put("xor", new Integer(Token.t_xor)); + cppKeywords.put("xor_eq", new Integer(Token.t_xor_eq)); ppDirectives.put("#define", new Integer(PreprocessorDirectives.DEFINE)); - ppDirectives.put( - "#undef", - new Integer(PreprocessorDirectives.UNDEFINE)); + ppDirectives.put("#undef",new Integer(PreprocessorDirectives.UNDEFINE)); ppDirectives.put("#if", new Integer(PreprocessorDirectives.IF)); ppDirectives.put("#ifdef", new Integer(PreprocessorDirectives.IFDEF)); ppDirectives.put("#ifndef", new Integer(PreprocessorDirectives.IFNDEF)); @@ -1334,6 +1351,45 @@ public class Scanner implements IScanner { ppDirectives.put("#elif", new Integer(PreprocessorDirectives.ELIF)); ppDirectives.put("#", new Integer(PreprocessorDirectives.BLANK)); + cKeywords.put("auto", new Integer(Token.t_auto)); + cKeywords.put("break", new Integer(Token.t_break)); + cKeywords.put("case", new Integer(Token.t_case)); + cKeywords.put("char", new Integer(Token.t_char)); + cKeywords.put("const", new Integer(Token.t_const)); + cKeywords.put("continue", new Integer(Token.t_continue)); + cKeywords.put("default", new Integer(Token.t_default)); + cKeywords.put("delete", new Integer(Token.t_delete)); + cKeywords.put("do", new Integer(Token.t_do)); + cKeywords.put("double", new Integer(Token.t_double)); + cKeywords.put("else", new Integer(Token.t_else)); + cKeywords.put("enum", new Integer(Token.t_enum)); + cKeywords.put("extern", new Integer(Token.t_extern)); + cKeywords.put("float", new Integer(Token.t_float)); + cKeywords.put("for", new Integer(Token.t_for)); + cKeywords.put("goto", new Integer(Token.t_goto)); + cKeywords.put("if", new Integer(Token.t_if)); + cKeywords.put("inline", new Integer(Token.t_inline)); + cKeywords.put("int", new Integer(Token.t_int)); + cKeywords.put("long", new Integer(Token.t_long)); + cKeywords.put("register", new Integer(Token.t_register)); + cKeywords.put("restrict", new Integer(Token.t_restrict)); + cKeywords.put("return", new Integer(Token.t_return)); + cKeywords.put("short", new Integer(Token.t_short)); + cKeywords.put("signed", new Integer(Token.t_signed)); + cKeywords.put("sizeof", new Integer(Token.t_sizeof)); + cKeywords.put("static", new Integer(Token.t_static)); + cKeywords.put("struct", new Integer(Token.t_struct)); + cKeywords.put("switch", new Integer(Token.t_switch)); + cKeywords.put("typedef", new Integer(Token.t_typedef)); + cKeywords.put("union", new Integer(Token.t_union)); + cKeywords.put("unsigned", new Integer(Token.t_unsigned)); + cKeywords.put("void", new Integer(Token.t_void)); + cKeywords.put("volatile", new Integer(Token.t_volatile)); + cKeywords.put("while", new Integer(Token.t_while)); + cKeywords.put("_Bool", new Integer(Token.t__Bool)); + cKeywords.put("_Complex", new Integer(Token.t__Complex)); + cKeywords.put("_Imaginary", new Integer(Token.t__Imaginary)); + } static public class PreprocessorDirectives { @@ -1380,7 +1436,7 @@ public class Scanner implements IScanner { new StringReader(expression + ";"), EXPRESSION, definitions); - Parser parser = new Parser(trial, evaluator); + IParser parser = new Parser(trial, evaluator); parser.expression(null); expressionEvalResult = evaluator.getResult(); @@ -1541,35 +1597,41 @@ public class Scanner implements IScanner { ArrayList macroReplacementTokens = new ArrayList(); String replacementString = getRestOfPreprocessorLine(); - Scanner helperScanner = new Scanner(); - helperScanner.initialize( - new StringReader(replacementString), - null); - helperScanner.setTokenizingMacroReplacementList( true ); - Token t = helperScanner.nextToken(false); - - try { - while (true) { - //each # preprocessing token in the replacement list shall be followed - //by a parameter as the next reprocessing token in the list - if( t.type == tPOUND ){ - macroReplacementTokens.add( t ); - t = helperScanner.nextToken(false); - int index = parameterIdentifiers.indexOf(t.image); - if (index == -1 ) { - //not found - if (throwExceptionOnBadPreprocessorSyntax) - throw new ScannerException( - BAD_PP + contextStack.getCurrentContext().getOffset()); - return; + + if( ! replacementString.equals( "" ) ) + { + Scanner helperScanner = new Scanner(); + helperScanner.initialize( + new StringReader(replacementString), + null); + helperScanner.setTokenizingMacroReplacementList( true ); + Token t = helperScanner.nextToken(false); + + try { + while (true) { + //each # preprocessing token in the replacement list shall be followed + //by a parameter as the next reprocessing token in the list + if( t.type == tPOUND ){ + macroReplacementTokens.add( t ); + t = helperScanner.nextToken(false); + int index = parameterIdentifiers.indexOf(t.image); + if (index == -1 ) { + //not found + if (throwExceptionOnBadPreprocessorSyntax) + throw new ScannerException( + BAD_PP + contextStack.getCurrentContext().getOffset()); + return; + } } + + macroReplacementTokens.add(t); + t = helperScanner.nextToken(false); } - - macroReplacementTokens.add(t); - t = helperScanner.nextToken(false); } - } catch (Parser.EndOfFile e) { - // Good + catch( Parser.EndOfFile eof ) + { + // good + } } IMacroDescriptor descriptor = new MacroDescriptor(); @@ -1580,7 +1642,12 @@ public class Scanner implements IScanner { key + "(" + parameters + ")"); addDefinition(key, descriptor); - } else if ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r')) { + } + else if ((c == '\n') || (c == '\r')) + { + addDefinition( key, "" ); + } + else if ((c == ' ') || (c == '\t') ) { // this is a simple definition skipOverWhitespace(); @@ -1805,4 +1872,20 @@ public class Scanner implements IScanner { return "0"; } + + /** + * @return + */ + public int getLineNumberForOffset(int offset) { + return contextStack.mapOffsetToLineNumber(offset); + } + + private boolean cppNature = true; + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser.IScanner#setCppNature(boolean) + */ + public void setCppNature(boolean value) { + cppNature = value; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ScannerContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ScannerContext.java index c2c61937dbc..d5c6f18acba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ScannerContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ScannerContext.java @@ -104,4 +104,5 @@ public class ScannerContext implements IScannerContext this.kind = kind; } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Token.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Token.java index d29cd49f367..79fc894e7d6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Token.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Token.java @@ -251,5 +251,9 @@ public class Token { static public final int tFLOATINGPT = 130; static public final int tLSTRING = 131; static public final int tCHAR = 132; - static public final int tLAST = tCHAR; + static public final int t__Bool = 133; + static public final int t__Complex = 134; + static public final int t__Imaginary = 135; + static public final int t_restrict = 136; + static public final int tLAST = t_restrict; } diff --git a/core/org.eclipse.cdt.ui.tests/ChangeLog b/core/org.eclipse.cdt.ui.tests/ChangeLog index e29642b5acb..2f597cc62c0 100644 --- a/core/org.eclipse.cdt.ui.tests/ChangeLog +++ b/core/org.eclipse.cdt.ui.tests/ChangeLog @@ -1,3 +1,10 @@ +2003-04-15 John Camelon + Added ScannerTestCase::testBug36434(). + Added ScannerTestCase::testMultipleLines(). + Added ParserTestSuite. + Added LineNumberTest. + Updated CModelElementsTests to set the Nature of the C++ project appropriately. + 2003-04-15 Andrew Niefer Moved ScannerFailedTest::testBug36047 to ScannerTestCase::testBug36047 Added ScannerFailedTest::testBug36475 diff --git a/core/org.eclipse.cdt.ui.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java b/core/org.eclipse.cdt.ui.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java index f00c22e37e2..7597a32da50 100644 --- a/core/org.eclipse.cdt.ui.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java +++ b/core/org.eclipse.cdt.ui.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java @@ -17,6 +17,7 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; @@ -29,7 +30,10 @@ import org.eclipse.cdt.internal.core.model.TranslationUnit; import org.eclipse.cdt.testplugin.CProjectHelper; import org.eclipse.cdt.testplugin.TestPluginLauncher; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; @@ -66,6 +70,10 @@ public class CModelElementsTests extends TestCase { e.printStackTrace(); } } + if (!fCProject.getProject().hasNature(CCProjectNature.CC_NATURE_ID)) { + addNatureToProject(fCProject.getProject(), CCProjectNature.CC_NATURE_ID, null); + } + CCorePlugin.getDefault().setUseNewParser(true); } @@ -109,5 +117,13 @@ public class CModelElementsTests extends TestCase { String firstParamType = setXParamTypes[0]; assertEquals(firstParamType, new String("int")); } - + private static void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException { + IProjectDescription description = proj.getDescription(); + String[] prevNatures= description.getNatureIds(); + String[] newNatures= new String[prevNatures.length + 1]; + System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length); + newNatures[prevNatures.length]= natureId; + description.setNatureIds(newNatures); + proj.setDescription(description, monitor); + } } diff --git a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/resources/OffsetTest.h b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/resources/OffsetTest.h new file mode 100644 index 00000000000..6660b4e9898 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/resources/OffsetTest.h @@ -0,0 +1,43 @@ +// inclusion begins and ends on line 2 +#include + +// simple macro begins and ends on line 5; ANOTHER on line 6 +#define SIMPLE_MACRO simple +#define ANOTHER +// namespace begins on line 7, ends on line 22 +namespace MyPackage{ + // class specification begins on line 10, ends on line 21 + class Hello{ + protected: + // simple declaration begins and ends on line 13 + int x; + // simple declaration begins and ends on line 15 + void setX(int X); + public: + // simple declaration begins on line 18 and ends on line 20 + Hello( void ) : x + ( 5 ) { + } + }; +} + +// simple declaration begins on line 25 and ends on line 27 +int * + y = + 0; + +// complex macro begins on line 30 and ends on line 31 +#define COMPLEX_MACRO 33 \ + + 44 + +// template declaration begins on line 34 and ends on line 35 +template + A createA( void ); + +// enumeration begins on line 38 and ends on line 43 +enum { + one, // enumerator begins and ends on line 39 + two, // enumerator begins and ends on line 40 + three // enumerator begins on line 41, ends on line 42 + = 4 +}; \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java index b8d6e298426..51e9e7d4606 100644 --- a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java +++ b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java @@ -39,6 +39,7 @@ import org.eclipse.cdt.internal.core.dom.TemplateParameter; import org.eclipse.cdt.internal.core.dom.TranslationUnit; import org.eclipse.cdt.internal.core.dom.UsingDeclaration; import org.eclipse.cdt.internal.core.dom.UsingDirective; +import org.eclipse.cdt.internal.core.parser.IParser; import org.eclipse.cdt.internal.core.parser.Parser; import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.core.parser.Token; @@ -57,7 +58,7 @@ public class DOMTests extends TestCase { public TranslationUnit parse(String code, boolean quickParse ) throws Exception { DOMBuilder domBuilder = new DOMBuilder(); - Parser parser = new Parser(code, domBuilder, quickParse ); + IParser parser = new Parser(code, domBuilder, quickParse ); if( ! parser.parse() ) throw new ParserException( "Parse failure" ); return domBuilder.getTranslationUnit(); diff --git a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java index af8c46e973e..d08115a8d03 100644 --- a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java +++ b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java @@ -5,6 +5,7 @@ import junit.framework.TestCase; import junit.framework.TestSuite; import org.eclipse.cdt.internal.core.parser.ExpressionEvaluator; +import org.eclipse.cdt.internal.core.parser.IParser; import org.eclipse.cdt.internal.core.parser.Parser; public class ExprEvalTest extends TestCase { @@ -19,7 +20,7 @@ public class ExprEvalTest extends TestCase { public void runTest(String code, int expectedValue) throws Exception { ExpressionEvaluator evaluator = new ExpressionEvaluator(); - Parser parser = new Parser(code, evaluator); + IParser parser = new Parser(code, evaluator); parser.expression(null); assertEquals(expectedValue, ((Integer)evaluator.getResult()).intValue()); } diff --git a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/LineNumberTest.java b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/LineNumberTest.java new file mode 100644 index 00000000000..dbfe35cb1e1 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/LineNumberTest.java @@ -0,0 +1,151 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.core.parser.tests; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import junit.framework.TestCase; + +import org.eclipse.cdt.internal.core.dom.ClassSpecifier; +import org.eclipse.cdt.internal.core.dom.DOMBuilder; +import org.eclipse.cdt.internal.core.dom.IOffsetable; +import org.eclipse.cdt.internal.core.dom.NamespaceDefinition; +import org.eclipse.cdt.internal.core.dom.SimpleDeclaration; +import org.eclipse.cdt.internal.core.dom.TemplateDeclaration; +import org.eclipse.cdt.internal.core.parser.IParser; +import org.eclipse.cdt.internal.core.parser.Parser; +import org.eclipse.cdt.internal.core.parser.Scanner; +import org.eclipse.cdt.internal.core.parser.Token; +import org.eclipse.core.runtime.Path; + +/** + * @author jcamelon + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class LineNumberTest extends TestCase { + + public LineNumberTest( String arg ) + { + super( arg ); + } + private InputStream fileIn; + + protected void setUp() throws Exception { + String fileName =org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.ui.tests").find(new Path("/")).getFile() + "parser/org/eclipse/cdt/core/parser/resources/OffsetTest.h"; + fileIn = new FileInputStream(fileName); + } + + public void testLineNos() throws Exception + { + Scanner scanner = new Scanner(); + Reader reader = new StringReader( "int x = 3;\n foo\nfire\nfoe "); + scanner.initialize( reader, "string"); + Token t = scanner.nextToken(); + assertEquals( t.getType(), Token.t_int ); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + t = scanner.nextToken(); + assertEquals( t.getImage(), "x"); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + t = scanner.nextToken(); + assertEquals( t.getType(), Token.tASSIGN ); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + t = scanner.nextToken(); + assertEquals( t.getImage(), "3" ); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + t = scanner.nextToken(); + assertEquals( t.getType(), Token.tSEMI); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + for( int i = 2; i < 5; ++i ) + { + t = scanner.nextToken(); + assertEquals( t.getType(), Token.tIDENTIFIER); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), i ); + } + + try { + t = scanner.nextToken(); + fail( "EOF"); + } + catch (Parser.EndOfFile e) { + assertEquals( scanner.getLineNumberForOffset(29), 4 ); + } + + } + + public void testDOMLineNos() throws Exception + { + DOMBuilder domBuilder = new DOMBuilder(); + IParser parser = new Parser( fileIn, domBuilder, true ); + if( ! parser.parse() ) fail( "Parse of file failed"); + + List macros = domBuilder.getTranslationUnit().getMacros(); + List inclusions = domBuilder.getTranslationUnit().getInclusions(); + List declarations = domBuilder.getTranslationUnit().getDeclarations(); + + assertEquals( 3, macros.size() ); + assertEquals( 1, inclusions.size() ); + assertEquals( declarations.size(), 4 ); + validateLineNumbers( (IOffsetable)inclusions.get(0), 2, 2 ); + validateLineNumbers( (IOffsetable)macros.get(0), 5, 5 ); + validateLineNumbers( (IOffsetable)macros.get(1), 6, 6 ); + validateLineNumbers( (IOffsetable)macros.get(2), 30, 31 ); + + NamespaceDefinition namespaceDecl = (NamespaceDefinition)declarations.get(0); + validateLineNumbers( namespaceDecl, 8, 22 ); + List namespaceMembers = namespaceDecl.getDeclarations(); + assertEquals( namespaceMembers.size(), 1 ); + ClassSpecifier Hello = (ClassSpecifier)((SimpleDeclaration)namespaceMembers.get(0)).getTypeSpecifier(); + validateLineNumbers( Hello, 10, 21); + List classMembers = Hello.getDeclarations(); + assertEquals( classMembers.size(), 3 ); + for( int i = 0; i < 3; ++i ) + { + SimpleDeclaration memberDeclaration = (SimpleDeclaration)Hello.getDeclarations().get(i); + switch( i ) + { + case 0: + validateLineNumbers(memberDeclaration, 13, 13 ); + break; + case 1: + validateLineNumbers(memberDeclaration, 15, 15 ); + break; + case 2: + validateLineNumbers(memberDeclaration, 18, 20 ); + break; + default: + break; + } + } + + validateLineNumbers( (SimpleDeclaration)declarations.get(1), 25, 27); + validateLineNumbers( (TemplateDeclaration)declarations.get(2), 34, 35); + validateLineNumbers( (SimpleDeclaration)declarations.get(3), 38, 43); + + } + + protected void tearDown() throws Exception { + if( fileIn != null ) fileIn.close(); + } + + protected void validateLineNumbers( IOffsetable offsetable, int top, int bottom ) + { + assertNotNull( offsetable ); + assertEquals( offsetable.getTopLine(), top ); + assertEquals( offsetable.getBottomLine(), bottom ); + } +} diff --git a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java new file mode 100644 index 00000000000..da25517ad0d --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java @@ -0,0 +1,39 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.parser.tests; + +import org.eclipse.cdt.core.model.tests.CModelElementsTests; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * @author jcamelon + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class ParserTestSuite extends TestCase { + public static Test suite() { + TestSuite suite= new TestSuite(); + suite.addTestSuite(BranchTrackerTest.class); + suite.addTestSuite(ScannerTestCase.class); + suite.addTestSuite(ExprEvalTest.class); + suite.addTestSuite(DOMTests.class); + suite.addTestSuite(ParserSymbolTableTest.class); + suite.addTestSuite(LineNumberTest.class); + suite.addTestSuite(CModelElementsTests.class); + return suite; + } + + +} diff --git a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java index 69f45694781..855d02079e8 100644 --- a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java +++ b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java @@ -2,6 +2,7 @@ package org.eclipse.cdt.core.parser.tests; import java.io.StringReader; import java.io.StringWriter; +import java.io.Writer; import java.util.List; import junit.framework.Test; @@ -523,6 +524,17 @@ public class ScannerTestCase extends TestCase } } + public void testMultipleLines() throws Exception + { + Writer code = new StringWriter(); + code.write( "#define COMPLEX_MACRO 33 \\\n"); + code.write( " + 44\n\nCOMPLEX_MACRO"); + initializeScanner( code.toString() ); + validateInteger( "33" ); + validateToken( Token.tPLUS ); + validateInteger( "44" ); + } + public void testSlightlyComplexIfdefStructure() { try @@ -1304,6 +1316,17 @@ public class ScannerTestCase extends TestCase validateEOF(); } + public void testBug36434() throws Exception + { + initializeScanner( "#define X(Y)"); + validateEOF(); + IMacroDescriptor macro = (IMacroDescriptor)scanner.getDefinition( "X" ); + assertNotNull( macro ); + assertEquals( macro.getParameters().size(), 1 ); + assertEquals( (String)macro.getParameters().get(0), "Y" ); + assertEquals( macro.getTokenizedExpansion().size(), 0 ); + } + public void testBug36047() throws Exception { StringWriter writer = new StringWriter(); @@ -1330,4 +1353,5 @@ public class ScannerTestCase extends TestCase validateEOF(); } + }