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:
parent
772ea31915
commit
452e82cb3d
32 changed files with 915 additions and 134 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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" );
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ public interface IScannerContext {
|
|||
int popUndo();
|
||||
void pushUndo(int undo);
|
||||
|
||||
|
||||
int getKind();
|
||||
void setKind( int kind );
|
||||
}
|
|
@ -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) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -104,4 +104,5 @@ public class ScannerContext implements IScannerContext
|
|||
this.kind = kind;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue