1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

IScannerInfo enhancements.

- Definition of IExtendedScannerInfo
	- Scanner2 implementation for bulk of this
	- added support to core model builder to ignore implicit inclusions/macros
	- JUnit
This commit is contained in:
John Camelon 2004-11-17 19:39:17 +00:00
parent 71be97ba3e
commit 6c0f439c6c
12 changed files with 322 additions and 21 deletions

View file

@ -0,0 +1,123 @@
/**********************************************************************
* Copyright (c) 2002-2004 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.InputStream;
import java.util.Collections;
import java.util.Iterator;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.NullLogService;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.tests.CompleteParseBaseTest.Scope;
import org.eclipse.cdt.internal.core.parser.Parser;
import org.eclipse.cdt.internal.core.parser.ParserException;
import org.eclipse.core.resources.IFile;
/**
* @author jcamelon
*
*/
public class IScannerInfoPluginTest extends FileBasePluginTest {
private static final String [] EMPTY_STRING_ARRAY = new String[0];
/**
* @param name
* @param className
*/
public IScannerInfoPluginTest(String name) {
super(name, IScannerInfoPluginTest.class);
}
public static Test suite() {
TestSuite suite = new TestSuite( IScannerInfoPluginTest.class );
suite.addTest( new CompleteParsePluginTest("cleanupProject") ); //$NON-NLS-1$
return suite;
}
protected Iterator getDeclarations(IASTScope scope)
{
Scope s = c.lookup( scope );
if( s != null )
return s.getDeclarations();
return null;
}
CompleteParseBaseTest.FullParseCallback c;
protected IASTScope parse(IFile code, ParserLanguage language, IScannerInfo scannerInfo ) throws Exception
{
c = new CompleteParseBaseTest.FullParseCallback();
InputStream stream = code.getContents();
IParser parser = ParserFactory.createParser(
ParserFactory.createScanner( new CodeReader( code.getLocation().toOSString(), stream ), scannerInfo, //$NON-NLS-1$
ParserMode.COMPLETE_PARSE, language, c, new NullLogService(), null ), c, ParserMode.COMPLETE_PARSE, language, null
);
stream.close();
boolean parseResult = parser.parse();
// throw exception if there are generated IProblems
if( !parseResult ) throw new ParserException( "FAILURE"); //$NON-NLS-1$
assertTrue( ((Parser)parser).validateCaches());
return c.getCompilationUnit();
}
public void testMacroFileLoading() throws Exception
{
String imacroContent = "#define ONE 1\n"; //$NON-NLS-1$
IFile imacroFile = importFile( "imacros.h", imacroContent ); //$NON-NLS-1$
String code = "int x = ONE;\n"; //$NON-NLS-1$
IFile sourceCode = importFile( "source.cpp", code ); //$NON-NLS-1$
String [] imacroz = new String[1];
imacroz[0] = imacroFile.getFullPath().toOSString();
IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, EMPTY_STRING_ARRAY, imacroz, EMPTY_STRING_ARRAY );
Iterator i = parse( sourceCode, ParserLanguage.C, scannerInfo ).getDeclarations();
assertTrue( i.hasNext() );
IASTVariable x = (IASTVariable) i.next();
assertFalse( i.hasNext() );
assertEquals( x.getName(), "x" ); //$NON-NLS-1$
assertNotNull( x.getInitializerClause() );
assertNotNull( x.getInitializerClause().getAssigmentExpression() );
assertEquals( x.getInitializerClause().getAssigmentExpression().toString(), "1"); //$NON-NLS-1$
}
public void testIncludeFileLoading() throws Exception
{
String inclContent = "int x = 4;\n\n"; //$NON-NLS-1$
IFile inclFile = importFile( "includeMe.h", inclContent ); //$NON-NLS-1$
String code = "int y = x;\n"; //$NON-NLS-1$
IFile sourceCode = importFile( "source.cpp", code ); //$NON-NLS-1$
String [] includez = new String[1];
includez[0] = inclFile.getFullPath().toOSString();
IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, EMPTY_STRING_ARRAY, EMPTY_STRING_ARRAY, includez );
Iterator i = parse( sourceCode, ParserLanguage.C, scannerInfo ).getDeclarations();
assertTrue( i.hasNext() );
assertTrue(i.next() instanceof IASTVariable );
IASTVariable y = (IASTVariable) i.next();
assertFalse( i.hasNext() );
assertEquals( y.getName(), "y" ); //$NON-NLS-1$
assertNotNull( y.getInitializerClause() );
assertNotNull( y.getInitializerClause().getAssigmentExpression() );
assertEquals( y.getInitializerClause().getAssigmentExpression().toString(), "x"); //$NON-NLS-1$
}
}

View file

@ -48,6 +48,7 @@ public class ParserTestSuite extends TestCase {
suite.addTestSuite( StructuralParseTest.class );
suite.addTestSuite( ObjectMapTest.class );
suite.addTest( CompleteParsePluginTest.suite() );
suite.addTest( IScannerInfoPluginTest.suite() );
suite.addTest( ScannerParserLoopTest.suite() );
suite.addTest( GCCParserExtensionTestSuite.suite() );
return suite;

View file

@ -237,10 +237,15 @@ public class CModelBuilder {
while (i.hasNext()){
IASTOffsetableElement offsetable = (IASTOffsetableElement)i.next();
if(offsetable instanceof IASTInclusion){
createInclusion(translationUnit, (IASTInclusion) offsetable);
IASTInclusion inc = (IASTInclusion) offsetable;
if( ! inc.isImplicit() )
createInclusion(translationUnit, inc );
}
else if(offsetable instanceof IASTMacro){
createMacro(translationUnit, (IASTMacro) offsetable);
IASTMacro macro = (IASTMacro) offsetable;
if( ! macro.isImplicit() )
createMacro(translationUnit, macro);
}else if(offsetable instanceof IASTDeclaration){
try{
generateModelElements (translationUnit, (IASTDeclaration) offsetable);

View file

@ -0,0 +1,64 @@
/**********************************************************************
* Copyright (c) 2002-2004 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;
import java.util.Map;
/**
* @author jcamelon
*
*/
public class ExtendedScannerInfo extends ScannerInfo implements IExtendedScannerInfo {
private static final String [] EMPTY_STRING_ARRAY = new String[ 0 ];
private String [] m, i;
public ExtendedScannerInfo()
{
}
public ExtendedScannerInfo( Map d, String [] incs )
{
super(d,incs);
}
public ExtendedScannerInfo( Map d, String [] incs, String [] macros, String [] includes )
{
super(d,incs);
m = macros;
i = includes;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IExtendedScannerInfo#getMacroFiles()
*/
public String[] getMacroFiles() {
if( m == null ) return EMPTY_STRING_ARRAY;
return m;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IExtendedScannerInfo#getIncludeFiles()
*/
public String[] getIncludeFiles() {
if( i == null ) return EMPTY_STRING_ARRAY;
return i;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IExtendedScannerInfo#getLocalIncludePath()
*/
public String[] getLocalIncludePath() {
return EMPTY_STRING_ARRAY; //TODO add impl
}
}

View file

@ -0,0 +1,30 @@
/**********************************************************************
* Copyright (c) 2002-2004 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;
/**
* @author jcamelon
*
*/
public interface IExtendedScannerInfo extends IScannerInfo {
/**
* @return
*/
public String [] getMacroFiles();
/**
* @return
*/
public String [] getIncludeFiles();
public String [] getLocalIncludePath();
}

View file

@ -27,7 +27,7 @@ public interface IASTFactory
char[] name,
int startingOffset,
int startingLine,
int nameOffset, int nameEndOffset, int nameLine, int endingOffset, int endingLine, char[] fn);
int nameOffset, int nameEndOffset, int nameLine, int endingOffset, int endingLine, char[] fn, boolean isImplicit);
public IASTInclusion createInclusion(
char[] name,
@ -35,7 +35,7 @@ public interface IASTFactory
boolean local,
int startingOffset,
int startingLine,
int nameOffset, int nameEndOffset, int nameLine, int endingOffset, int endingLine, char[] fn) ;
int nameOffset, int nameEndOffset, int nameLine, int endingOffset, int endingLine, char[] fn, boolean isImplicit) ;
public IASTUsingDirective createUsingDirective(
IASTScope scope,

View file

@ -25,4 +25,5 @@ public interface IASTInclusion extends IASTOffsetableNamedElement, ISourceElemen
public boolean isLocal();
public boolean isImplicit();
}

View file

@ -17,6 +17,11 @@ import org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate;
*
*/
public interface IASTMacro extends IASTOffsetableNamedElement, ISourceElementCallbackDelegate{
/**
* @return
*/
boolean isImplicit();
}

View file

@ -19,7 +19,7 @@ import org.eclipse.cdt.core.parser.ast.IASTInclusion;
*/
public class ASTInclusion implements IASTInclusion {
public ASTInclusion( char[] name, char[] fileName, boolean local, int startingOffset, int startLine, int nameOffset, int nameEndOffset, int nameLine, int endOffset, int endLine, char [] fn )
public ASTInclusion( char[] name, char[] fileName, boolean local, int startingOffset, int startLine, int nameOffset, int nameEndOffset, int nameLine, int endOffset, int endLine, char [] fn, boolean i )
{
this.name = name;
this.fileName = fileName;
@ -29,6 +29,7 @@ public class ASTInclusion implements IASTInclusion {
setNameEndOffsetAndLineNumber(nameEndOffset, nameLine);
setEndingOffsetAndLineNumber(endOffset, endLine);
this.filename = fn;
this.isImplicit = i;
}
private int nameEndOffset;
@ -183,6 +184,7 @@ public class ASTInclusion implements IASTInclusion {
private int fileIndex;
private final char[] filename;
private final boolean isImplicit;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getFileIndex()
*/
@ -203,4 +205,10 @@ public class ASTInclusion implements IASTInclusion {
public char[] getFilename() {
return filename;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTInclusion#isImplicit()
*/
public boolean isImplicit() {
return isImplicit;
}
}

View file

@ -24,7 +24,7 @@ public class ASTMacro implements IASTMacro {
private final char[] name;
private final char[] fn;
public ASTMacro( char[] name, int start, int startLine, int nameBeg, int nameEnd, int nameLine, int end, int endLine, char[] fn )
public ASTMacro( char[] name, int start, int startLine, int nameBeg, int nameEnd, int nameLine, int end, int endLine, char[] fn, boolean implicit )
{
this.name =name;
setStartingOffsetAndLineNumber(start, startLine);
@ -32,6 +32,7 @@ public class ASTMacro implements IASTMacro {
setNameEndOffsetAndLineNumber(nameEnd, nameLine);
setEndingOffsetAndLineNumber(end, endLine);
this.fn = fn;
this.isImplicit = implicit;
}
private int startingOffset = 0, endingOffset = 0, nameOffset = 0;
@ -149,6 +150,7 @@ public class ASTMacro implements IASTMacro {
private int fileIndex;
private final boolean isImplicit;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getFileIndex()
*/
@ -168,5 +170,11 @@ public class ASTMacro implements IASTMacro {
public char[] getFilename() {
return fn;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTMacro#isImplicit()
*/
public boolean isImplicit() {
return isImplicit;
}
}

View file

@ -43,16 +43,16 @@ public class BaseASTFactory {
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.ast.IASTFactory#createMacro(java.lang.String, int, int, int)
*/
public IASTMacro createMacro(char[] name, int startingOffset, int startingLine, int nameOffset, int nameEndOffset, int nameLine, int endingOffset, int endingLine, char[] fn) {
IASTMacro m = new ASTMacro( name, startingOffset, startingLine, nameOffset, nameEndOffset, nameLine, endingOffset, endingLine, fn );
public IASTMacro createMacro(char[] name, int startingOffset, int startingLine, int nameOffset, int nameEndOffset, int nameLine, int endingOffset, int endingLine, char[] fn, boolean isImplicit) {
IASTMacro m = new ASTMacro( name, startingOffset, startingLine, nameOffset, nameEndOffset, nameLine, endingOffset, endingLine, fn, isImplicit );
return m;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.ast.IASTFactory#createInclusion(java.lang.String, java.lang.String, boolean)
*/
public IASTInclusion createInclusion(char[] name, char[] fileName, boolean local, int startingOffset, int startingLine, int nameOffset, int nameEndOffset, int nameLine, int endingOffset, int endingLine, char[] fn) {
IASTInclusion inclusion = new ASTInclusion( name, fileName, local, startingOffset, startingLine, nameOffset, nameEndOffset, nameLine, endingOffset, endingLine, fn );
public IASTInclusion createInclusion(char[] name, char[] fileName, boolean local, int startingOffset, int startingLine, int nameOffset, int nameEndOffset, int nameLine, int endingOffset, int endingLine, char[] fn, boolean isImplicit) {
IASTInclusion inclusion = new ASTInclusion( name, fileName, local, startingOffset, startingLine, nameOffset, nameEndOffset, nameLine, endingOffset, endingLine, fn, isImplicit );
return inclusion;
}

View file

@ -21,6 +21,7 @@ import java.util.Map;
import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.EndOfFileException;
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IMacro;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IProblem;
@ -136,6 +137,9 @@ public class Scanner2 implements IScanner, IScannerData {
private ParserMode parserMode;
private List workingCopies;
private Iterator preIncludeFiles = EmptyIterator.EMPTY_ITERATOR;
private boolean isInitialized = false;
{
// try {
@ -169,8 +173,6 @@ public class Scanner2 implements IScanner, IScannerData {
if (reader.filename != null)
fileCache.put(reader.filename, reader);
pushContext(reader.buffer, reader);
setupBuiltInMacros();
@ -187,9 +189,45 @@ public class Scanner2 implements IScanner, IScannerData {
}
}
}
includePaths = info.getIncludePaths();
if( info instanceof IExtendedScannerInfo )
{
IExtendedScannerInfo einfo = (IExtendedScannerInfo) info;
if( einfo.getMacroFiles() != null )
for( int i = 0; i < einfo.getMacroFiles().length; ++i )
{
CodeReader r = ScannerUtility.createReaderDuple( einfo.getMacroFiles()[i], requestor, getWorkingCopies() );
if( r == null )
continue;
pushContext( r.buffer, r );
while( true )
{
try {
nextToken();
} catch (EndOfFileException e) {
finished = false;
break;
}
}
}
if( einfo.getIncludeFiles() != null && einfo.getIncludeFiles().length > 0 )
preIncludeFiles = Arrays.asList( einfo.getIncludeFiles() ).iterator();
pushContext(reader.buffer, reader);
if( preIncludeFiles.hasNext() )
pushForcedInclusion();
isInitialized = true;
}
else
{
pushContext(reader.buffer, reader);
isInitialized = true;
}
}
private void pushContext(char[] buffer) {
@ -280,15 +318,32 @@ public class Scanner2 implements IScanner, IScannerData {
buffer.append( ((InclusionData)bufferData[bufferStackPos]).reader.filename );
log.traceLog( buffer.toString() );
}
callbackManager.pushCallback( ((InclusionData) bufferData[bufferStackPos]).inclusion );
}
bufferData[bufferStackPos] = null;
--bufferStackPos;
if( preIncludeFiles.hasNext() )
pushForcedInclusion();
}
/**
*
*/
private void pushForcedInclusion() {
CodeReader r = null;
while( r == null )
{
if( preIncludeFiles.hasNext() )
r = ScannerUtility.createReaderDuple( (String)preIncludeFiles.next(), requestor, getWorkingCopies() );
else
break;
}
if( r == null ) return;
IASTInclusion i = getASTFactory().createInclusion( r.filename, r.filename, false, -1, -1, -1, -1, -1, -1, -1, EMPTY_STRING_CHAR_ARRAY, true );
InclusionData d = new InclusionData( r, i );
pushContext( r.buffer, d );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScanner#addDefinition(java.lang.String, java.lang.String)
*/
@ -361,6 +416,7 @@ public class Scanner2 implements IScanner, IScannerData {
private static final char[] EMPTY_STRING_CHAR_ARRAY = new char[0];
private boolean isCancelled = false;
public synchronized void cancel() {
isCancelled = true;
@ -1624,7 +1680,7 @@ public class Scanner2 implements IScanner, IScannerData {
if( parserMode == ParserMode.QUICK_PARSE )
{
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, EMPTY_STRING_CHAR_ARRAY, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename() );
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, EMPTY_STRING_CHAR_ARRAY, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename(), false );
callbackManager.pushCallback( new InclusionData( null, inclusion ) );
callbackManager.pushCallback( inclusion );
}
@ -1648,7 +1704,7 @@ public class Scanner2 implements IScanner, IScannerData {
}
if (reader != null) {
if (dlog != null) dlog.println("#include \"" + finalPath + "\""); //$NON-NLS-1$ //$NON-NLS-2$
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, reader.filename, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename() );
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, reader.filename, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename(), false );
pushContext(reader.buffer, new InclusionData( reader, inclusion ));
return;
}
@ -1676,7 +1732,7 @@ public class Scanner2 implements IScanner, IScannerData {
}
if (reader != null) {
if (dlog != null) dlog.println("#include <" + finalPath + ">"); //$NON-NLS-1$ //$NON-NLS-2$
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, reader.filename, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename() );
IASTInclusion inclusion = getASTFactory().createInclusion( fileNameArray, reader.filename, local, startOffset, startingLineNumber, nameOffset, nameEndOffset, nameLine, endOffset, endLine, getCurrentFilename(), false );
pushContext(reader.buffer, new InclusionData( reader, inclusion ));
return;
}
@ -1817,7 +1873,7 @@ public class Scanner2 implements IScanner, IScannerData {
if (usesVarArgInDefinition && definitions.get(name) instanceof FunctionStyleMacro && !((FunctionStyleMacro)definitions.get(name)).hasVarArgs())
handleProblem(IProblem.PREPROCESSOR_INVALID_VA_ARGS, varArgDefinitionInd, null);
callbackManager.pushCallback( getASTFactory().createMacro( name, startingOffset, startingLineNumber, idstart, idstart + idlen, nameLine, textstart + textlen, endingLine, getCurrentFilename() ) );
callbackManager.pushCallback( getASTFactory().createMacro( name, startingOffset, startingLineNumber, idstart, idstart + idlen, nameLine, textstart + textlen, endingLine, getCurrentFilename(), !isInitialized ) );
}
private char[][] extractMacroParameters( int idstart, char[] name, boolean reportProblems ){