1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

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.
This commit is contained in:
Doug Schaefer 2003-04-16 12:30:47 +00:00
parent 772ea31915
commit 452e82cb3d
32 changed files with 915 additions and 134 deletions

View file

@ -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;
}
}

View file

@ -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);
}
@ -627,6 +637,7 @@ public class DOMBuilder implements IParserCallback
es.setStartToken(enumKey);
decl.setTypeSpecifier(es);
((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;
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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" );

View file

@ -52,6 +52,8 @@ public class ContextStack {
contextStack.push(currentContext);
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();
}
}

View file

@ -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) {
}
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -28,7 +28,6 @@ public interface IScannerContext {
int popUndo();
void pushUndo(int undo);
int getKind();
void setKind( int kind );
}

View file

@ -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) {
}
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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 eof )
{
// good
}
} catch (Parser.EndOfFile e) {
// 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;
}
}

View file

@ -104,4 +104,5 @@ public class ScannerContext implements IScannerContext
this.kind = kind;
}
}

View file

@ -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;
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -0,0 +1,43 @@
// inclusion begins and ends on line 2
#include <stdio.h>
// 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 <class A >
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
};

View file

@ -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();

View file

@ -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());
}

View file

@ -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 );
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}