1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00
Fixed Bug 44838 : exception when resolving parameter references in a constructor 
	Fixed Bug 46165 : fields referenced in constructor chains are not called back upon 
	Fixed Bug 45551 : Macro replacement in #include <file.h> directives 

TESTS
	Added CompleteParseASTTest::testBug44838().  
	Added CompleteParseASTTest::testBug46165().  
	Added ScannerTestCase::testBug45551().
This commit is contained in:
John Camelon 2003-11-06 04:57:38 +00:00
parent 97e203468e
commit 13b7aeb128
8 changed files with 224 additions and 10 deletions

View file

@ -1,3 +1,8 @@
2003-11-05 John Camelon
Added CompleteParseASTTest::testBug44838().
Added CompleteParseASTTest::testBug46165().
Added ScannerTestCase::testBug45551().
2003-11-05 John Camelon 2003-11-05 John Camelon
Updated parser clients to use new ParserFactory (stand-alone parser work item). Updated parser clients to use new ParserFactory (stand-alone parser work item).

View file

@ -17,6 +17,7 @@ import junit.framework.TestCase;
import org.eclipse.cdt.core.parser.EndOfFile; import org.eclipse.cdt.core.parser.EndOfFile;
import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.NullSourceElementRequestor; import org.eclipse.cdt.core.parser.NullSourceElementRequestor;
import org.eclipse.cdt.core.parser.ParserFactory; import org.eclipse.cdt.core.parser.ParserFactory;
@ -41,14 +42,20 @@ public class BaseScannerTest extends TestCase {
protected void initializeScanner( String input, ParserMode mode ) throws ParserFactoryException protected void initializeScanner( String input, ParserMode mode ) throws ParserFactoryException
{ {
scanner= ParserFactory.createScanner( new StringReader(input),"TEXT", new ScannerInfo(), mode, ParserLanguage.CPP, new NullSourceElementRequestor( mode ), null ); initializeScanner( input, mode, new NullSourceElementRequestor( mode ));
} }
protected void initializeScanner( String input, ParserMode mode, ISourceElementRequestor requestor ) throws ParserFactoryException
{
scanner= ParserFactory.createScanner( new StringReader(input),"TEXT", new ScannerInfo(), mode, ParserLanguage.CPP, requestor, null );
}
protected void initializeScanner(String input) throws ParserFactoryException protected void initializeScanner(String input) throws ParserFactoryException
{ {
initializeScanner( input, ParserMode.COMPLETE_PARSE ); initializeScanner( input, ParserMode.COMPLETE_PARSE );
} }
public int fullyTokenize() throws Exception public int fullyTokenize() throws Exception
{ {

View file

@ -32,6 +32,7 @@ import org.eclipse.cdt.core.parser.ast.IASTFunction;
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification; import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
import org.eclipse.cdt.core.parser.ast.IASTMethod; import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition; import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTReference; import org.eclipse.cdt.core.parser.ast.IASTReference;
import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier; import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier;
@ -1011,4 +1012,34 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
assertAllReferences( 2, createTaskList( new Task( MyClass ), new Task( MyEnum ) ) ); assertAllReferences( 2, createTaskList( new Task( MyClass ), new Task( MyEnum ) ) );
} }
public void testBug44838() throws Exception
{
StringBuffer buffer = new StringBuffer();
buffer.append( "class A { int myX; A( int x ); };\n");
buffer.append( "A::A( int x ) : myX( x ) { if( x == 5 ) myX++; }\n");
Iterator i = parse( buffer.toString() ).getDeclarations();
IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTField myX = (IASTField)getDeclarations( classA ).next();
IASTMethod constructor = (IASTMethod)i.next();
IASTParameterDeclaration parmX = (IASTParameterDeclaration)constructor.getParameters().next();
assertTrue( constructor.isConstructor());
assertFalse(i.hasNext());
}
public void testBug46165() throws Exception
{
StringBuffer buffer = new StringBuffer();
buffer.append( "class A { int myX; A( int x ); };\n");
buffer.append( "A::A( int x ) : myX( x ) { if( x == 5 ) myX++; }\n");
Iterator i = parse( buffer.toString() ).getDeclarations();
IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTField myX = (IASTField)getDeclarations( classA ).next();
IASTMethod constructor = (IASTMethod)i.next();
IASTParameterDeclaration parmX = (IASTParameterDeclaration)constructor.getParameters().next();
assertTrue( constructor.isConstructor());
assertAllReferences( 4, createTaskList( new Task( classA ), new Task( myX, 2 ), new Task( parmX )));
assertFalse(i.hasNext());
}
} }

View file

@ -2,15 +2,19 @@ package org.eclipse.cdt.core.parser.tests;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.parser.EndOfFile; import org.eclipse.cdt.core.parser.EndOfFile;
import org.eclipse.cdt.core.parser.IMacroDescriptor; import org.eclipse.cdt.core.parser.IMacroDescriptor;
import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.NullSourceElementRequestor;
import org.eclipse.cdt.core.parser.ParserFactoryException; import org.eclipse.cdt.core.parser.ParserFactoryException;
import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ScannerException; import org.eclipse.cdt.core.parser.ScannerException;
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
import org.eclipse.cdt.internal.core.parser.Token; import org.eclipse.cdt.internal.core.parser.Token;
/** /**
@ -1260,7 +1264,6 @@ public class ScannerTestCase extends BaseScannerTest
writer.write( "# define foo 2\n"); writer.write( "# define foo 2\n");
writer.write( "#endif\n"); writer.write( "#endif\n");
writer.write( "foo\n"); writer.write( "foo\n");
initializeScanner( writer.toString() ); initializeScanner( writer.toString() );
validateInteger( "2" ); validateInteger( "2" );
validateEOF(); validateEOF();
@ -1484,4 +1487,46 @@ public class ScannerTestCase extends BaseScannerTest
initializeScanner(buffer.toString()); initializeScanner(buffer.toString());
validateEOF(); validateEOF();
} }
protected static class Callback extends NullSourceElementRequestor implements ISourceElementRequestor
{
public List inclusions = new ArrayList();
public List problems = new ArrayList();
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterInclusion(org.eclipse.cdt.core.parser.ast.IASTInclusion)
*/
public void enterInclusion(IASTInclusion inclusion)
{
inclusions.add( inclusion.getName() );
}
public boolean acceptProblem( IProblem p )
{
problems.add( p );
return super.acceptProblem(p);
}
/**
* @param mode
*/
public Callback(ParserMode mode)
{
super( mode );
}
}
public void testBug45551() throws Exception
{
StringBuffer buffer = new StringBuffer();
buffer.append( "#define stdio someNonExistantIncludeFile\n" );
buffer.append( "#include <stdio.h>\n" );
Callback callback = new Callback( ParserMode.QUICK_PARSE );
initializeScanner( buffer.toString(), ParserMode.QUICK_PARSE, callback );
validateEOF();
assertEquals( callback.problems.size(), 0 );
assertEquals( callback.inclusions.size(), 1 );
assertEquals( callback.inclusions.get(0), "stdio.h");
}
} }

View file

@ -1,3 +1,8 @@
2003-11-05 John Camelon
Fixed Bug 44838 : exception when resolving parameter references in a constructor
Fixed Bug 46165 : fields referenced in constructor chains are not called back upon
Fixed Bug 45551 : Macro replacement in #include <file.h> directives
2003-11-05 John Camelon 2003-11-05 John Camelon
Cleaned up the ParserFactory interface to check for validity of input arguments. Cleaned up the ParserFactory interface to check for validity of input arguments.
Moved NullSourceElementRequestor and ScannerInfo to public interface as requested. Moved NullSourceElementRequestor and ScannerInfo to public interface as requested.

View file

@ -1473,6 +1473,8 @@ public class Scanner implements IScanner {
contextStack.getCurrentContext()); contextStack.getCurrentContext());
default : default :
ungetChar(c); ungetChar(c);
if( forInclusion )
temporarilyReplaceDefinitionsMap();
return newToken(IToken.tLT, "<", contextStack.getCurrentContext()); return newToken(IToken.tLT, "<", contextStack.getCurrentContext());
} }
case '>' : case '>' :
@ -1500,6 +1502,8 @@ public class Scanner implements IScanner {
contextStack.getCurrentContext()); contextStack.getCurrentContext());
default : default :
ungetChar(c); ungetChar(c);
if( forInclusion )
restoreDefinitionsMap();
return newToken(IToken.tGT, ">", contextStack.getCurrentContext()); return newToken(IToken.tGT, ">", contextStack.getCurrentContext());
} }
case '.' : case '.' :
@ -2000,6 +2004,7 @@ public class Scanner implements IScanner {
new NullSourceElementRequestor(), new NullSourceElementRequestor(),
mode, mode,
language, log ); language, log );
helperScanner.setForInclusion( true );
IToken t = null; IToken t = null;
try { try {
@ -2093,6 +2098,31 @@ public class Scanner implements IScanner {
handleInclusion(f.trim(), useIncludePath, startOffset, beginningOffset, endOffset); handleInclusion(f.trim(), useIncludePath, startOffset, beginningOffset, endOffset);
} }
protected static final Hashtable emptyMap = new Hashtable();
protected Hashtable holderMap = null;
protected void temporarilyReplaceDefinitionsMap()
{
holderMap = definitions;
definitions = emptyMap;
}
protected void restoreDefinitionsMap()
{
definitions = holderMap;
holderMap = null;
}
protected boolean forInclusion = false;
/**
* @param b
*/
protected void setForInclusion(boolean b)
{
forInclusion = b;
}
protected void poundDefine(int beginning) throws ScannerException, EndOfFile { protected void poundDefine(int beginning) throws ScannerException, EndOfFile {
skipOverWhitespace(); skipOverWhitespace();
// definition // definition

View file

@ -23,17 +23,21 @@ import org.eclipse.cdt.core.parser.ast.IASTExpression;
public class ASTConstructorMemberInitializer public class ASTConstructorMemberInitializer
implements IASTConstructorMemberInitializer implements IASTConstructorMemberInitializer
{ {
private final String name; private final int nameOffset;
private final boolean requireNameResolution;
private final String name;
private final IASTExpression expression; private final IASTExpression expression;
private final ASTReferenceStore store; private final List references;
/** /**
* *
*/ */
public ASTConstructorMemberInitializer( IASTExpression expression, String name, List references ) public ASTConstructorMemberInitializer( IASTExpression expression, String name, int nameOffset, List references, boolean requireNameResolution )
{ {
this.expression = expression; this.expression = expression;
this.name = name; this.name = name;
store = new ASTReferenceStore( references ); this.nameOffset = nameOffset;
this.references = references;
this.requireNameResolution = requireNameResolution;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTConstructorMemberInitializer#getExpressionList() * @see org.eclipse.cdt.core.parser.ast.IASTConstructorMemberInitializer#getExpressionList()
@ -54,6 +58,7 @@ public class ASTConstructorMemberInitializer
*/ */
public void acceptElement(ISourceElementRequestor requestor) public void acceptElement(ISourceElementRequestor requestor)
{ {
ASTReferenceStore store = new ASTReferenceStore( references );
store.processReferences( requestor ); store.processReferences( requestor );
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -68,4 +73,27 @@ public class ASTConstructorMemberInitializer
public void exitScope(ISourceElementRequestor requestor) public void exitScope(ISourceElementRequestor requestor)
{ {
} }
/**
* @return
*/
public boolean requiresNameResolution()
{
return requireNameResolution;
}
/**
* @return
*/
public List getReferences()
{
return references;
}
/**
* @return
*/
public int getNameOffset()
{
return nameOffset;
}
} }

View file

@ -666,7 +666,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
{ {
return new ASTFieldReference( offset, string, (IASTField)symbol.getASTExtension().getPrimaryDeclaration()); return new ASTFieldReference( offset, string, (IASTField)symbol.getASTExtension().getPrimaryDeclaration());
} }
else if( symbol.getContainingSymbol().getType() == TypeInfo.t_function && else if( ( symbol.getContainingSymbol().getType() == TypeInfo.t_function ||
symbol.getContainingSymbol().getType() == TypeInfo.t_constructor ) &&
symbol.getContainingSymbol() instanceof IParameterizedSymbol && symbol.getContainingSymbol() instanceof IParameterizedSymbol &&
((IParameterizedSymbol)symbol.getContainingSymbol()).getParameterList() != null && ((IParameterizedSymbol)symbol.getContainingSymbol()).getParameterList() != null &&
((IParameterizedSymbol)symbol.getContainingSymbol()).getParameterList().contains( symbol ) ) ((IParameterizedSymbol)symbol.getContainingSymbol()).getParameterList().contains( symbol ) )
@ -1327,11 +1328,25 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
List references = new ArrayList(); List references = new ArrayList();
IContainerSymbol scopeSymbol = scopeToSymbol(scope); IContainerSymbol scopeSymbol = scopeToSymbol(scope);
boolean requireReferenceResolution = false;
if( duple != null ) if( duple != null )
lookupQualifiedName( scopeSymbol, duple, references, false ); {
try
{
lookupQualifiedName( scopeSymbol, duple, references, true );
} catch( ASTSemanticException ase )
{
requireReferenceResolution = true;
}
}
getExpressionReferences( expressionList, references ); getExpressionReferences( expressionList, references );
return new ASTConstructorMemberInitializer( expressionList, duple == null ? "" : duple.toString(), references ); return new ASTConstructorMemberInitializer(
expressionList,
duple == null ? "" : duple.toString(),
duple == null ? 0 : duple.getFirstToken().getOffset(),
references, requireReferenceResolution );
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createSimpleTypeSpecifier(org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier.Type, org.eclipse.cdt.core.parser.ITokenDuple, boolean, boolean, boolean, boolean, boolean) * @see org.eclipse.cdt.core.parser.ast.IASTFactory#createSimpleTypeSpecifier(org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier.Type, org.eclipse.cdt.core.parser.ITokenDuple, boolean, boolean, boolean, boolean, boolean)
@ -1829,6 +1844,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
throw new ASTSemanticException(); throw new ASTSemanticException();
} }
resolveLeftoverConstructorInitializerMembers( symbol, constructorChain );
ASTMethod method = new ASTMethod( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, isConstructor, isDestructor, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock ); ASTMethod method = new ASTMethod( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, isConstructor, isDestructor, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock );
try try
@ -1842,6 +1858,53 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
return method; return method;
} }
/** /**
* @param symbol
* @param constructorChain
*/
protected void resolveLeftoverConstructorInitializerMembers(IParameterizedSymbol symbol, List constructorChain)
{
if( constructorChain != null )
{
Iterator initializers = constructorChain.iterator();
while( initializers.hasNext())
{
IASTConstructorMemberInitializer initializer = (IASTConstructorMemberInitializer)initializers.next();
if( !initializer.getName().equals( "") &&
initializer instanceof ASTConstructorMemberInitializer &&
((ASTConstructorMemberInitializer)initializer).requiresNameResolution() )
{
ASTConstructorMemberInitializer realInitializer = ((ASTConstructorMemberInitializer)initializer);
try
{
lookupQualifiedName( symbol, initializer.getName(), realInitializer.getNameOffset(), realInitializer.getReferences(), false );
}
catch( ASTSemanticException ase )
{
}
}
// TODO try and resolve parameter references now in the expression list
}
}
}
/**
* @param symbol
* @param string
* @param i
* @param list
* @param b
* @return
*/
protected ISymbol lookupQualifiedName(IParameterizedSymbol startingScope, String name, int nameOffset, List references, boolean throwOnError) throws ASTSemanticException
{
return lookupQualifiedName(startingScope, name, TypeInfo.t_any, null, nameOffset, references, throwOnError);
}
/**
* @param symbol * @param symbol
* @param isConst * @param isConst
* @param isVolatile * @param isVolatile