mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
fix bug 57513 - constructor references
This commit is contained in:
parent
54a17496c3
commit
4e2d61d298
2 changed files with 152 additions and 1 deletions
|
@ -1695,4 +1695,71 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
|
|||
Iterator references = callback.getReferences().iterator();
|
||||
assertEquals( ((IASTReference)references.next()).getReferencedElement(), iii );
|
||||
}
|
||||
|
||||
public void test57513_new() throws Exception
|
||||
{
|
||||
Writer writer = new StringWriter();
|
||||
writer.write( "class A{ A(); A( int ); }; \n" );
|
||||
writer.write( " void f() { \n" );
|
||||
writer.write( " A * a1 = new A; \n" );
|
||||
writer.write( " A * a2 = new(1)A(); \n" );
|
||||
writer.write( " A * a3 = new A( 1 ); \n" );
|
||||
writer.write( "} \n" );
|
||||
|
||||
Iterator i = parse( writer.toString() ).getDeclarations();
|
||||
|
||||
IASTClassSpecifier A = (IASTClassSpecifier) ((IASTAbstractTypeSpecifierDeclaration)i.next() ).getTypeSpecifier();
|
||||
IASTFunction f = (IASTFunction) i.next();
|
||||
assertFalse( i.hasNext() );
|
||||
|
||||
i = getDeclarations( A );
|
||||
IASTMethod constructor1 = (IASTMethod) i.next();
|
||||
IASTMethod constructor2 = (IASTMethod) i.next();
|
||||
assertFalse( i.hasNext() );
|
||||
|
||||
assertReferenceTask( new Task( constructor1, 2, false, false ) );
|
||||
assertReferenceTask( new Task( constructor2, 1, false, false ) );
|
||||
assertReferenceTask( new Task( A, 3, false, false ) );
|
||||
}
|
||||
|
||||
public void test57513_NoConstructor() throws Exception
|
||||
{
|
||||
Writer writer = new StringWriter();
|
||||
writer.write( "class A{ }; \n" );
|
||||
writer.write( " void f() { \n" );
|
||||
writer.write( " A * a1 = new A; \n" );
|
||||
writer.write( "} \n" );
|
||||
|
||||
Iterator i = parse( writer.toString() ).getDeclarations();
|
||||
|
||||
IASTClassSpecifier A = (IASTClassSpecifier) ((IASTAbstractTypeSpecifierDeclaration)i.next() ).getTypeSpecifier();
|
||||
IASTFunction f = (IASTFunction) i.next();
|
||||
assertFalse( i.hasNext() );
|
||||
|
||||
assertReferenceTask( new Task( A, 2, false, false ) );
|
||||
}
|
||||
|
||||
public void test57513_ctorinit() throws Exception
|
||||
{
|
||||
Writer writer = new StringWriter();
|
||||
writer.write( "class A{ A(); A( A * ); }; \n" );
|
||||
writer.write( "class B : public A { B(); }; \n" );
|
||||
writer.write( "B::B():A( new A ){} \n" );
|
||||
|
||||
Iterator i = parse( writer.toString() ).getDeclarations();
|
||||
|
||||
IASTClassSpecifier A = (IASTClassSpecifier) ((IASTAbstractTypeSpecifierDeclaration)i.next() ).getTypeSpecifier();
|
||||
IASTClassSpecifier B = (IASTClassSpecifier) ((IASTAbstractTypeSpecifierDeclaration)i.next() ).getTypeSpecifier();
|
||||
IASTMethod constructorB = (IASTMethod) i.next();
|
||||
assertFalse( i.hasNext() );
|
||||
|
||||
i = getDeclarations( A );
|
||||
IASTMethod constructor1 = (IASTMethod) i.next();
|
||||
IASTMethod constructor2 = (IASTMethod) i.next();
|
||||
assertFalse( i.hasNext() );
|
||||
|
||||
assertReferenceTask( new Task( constructor1, 1, false, false ) );
|
||||
assertReferenceTask( new Task( constructor2, 1, false, false ) );
|
||||
assertReferenceTask( new Task( A, 2, false, false ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1071,6 +1071,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
|
||||
// Try to figure out the result that this expression evaluates to
|
||||
ExpressionResult expressionResult = getExpressionResultType(scope, kind, lhs, rhs, thirdExpression, typeId, literal, symbol);
|
||||
|
||||
if( newDescriptor != null ){
|
||||
createConstructorReference( newDescriptor, typeId, references );
|
||||
}
|
||||
|
||||
if( symbol == null )
|
||||
purgeBadReferences( kind, rhs );
|
||||
|
@ -1086,6 +1090,77 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
|
||||
return expression;
|
||||
}
|
||||
|
||||
private void createConstructorReference( IASTNewExpressionDescriptor descriptor, IASTTypeId typeId, List references ){
|
||||
ISymbol symbol = null;
|
||||
try {
|
||||
symbol = typeId.getTypeSymbol();
|
||||
|
||||
if( symbol.isType( TypeInfo.t_type ) )
|
||||
symbol = symbol.getTypeSymbol();
|
||||
} catch (ASTNotImplementedException e) {
|
||||
return;
|
||||
}
|
||||
if( symbol == null || !( symbol instanceof IDerivableContainerSymbol ) )
|
||||
return;
|
||||
|
||||
Iterator i = descriptor.getNewInitializerExpressions();
|
||||
|
||||
ASTExpression exp = ( i.hasNext() )? (ASTExpression) i.next() : null;
|
||||
|
||||
ITokenDuple duple = ((ASTTypeId)typeId).getTokenDuple();
|
||||
|
||||
if( createConstructorReference( symbol, exp, duple, references ) ){
|
||||
//if we have a constructor reference, get rid of the class reference.
|
||||
i = ((ASTTypeId)typeId).getReferences().iterator();
|
||||
while( i.hasNext() )
|
||||
{
|
||||
ASTReference ref = (ASTReference) i.next();
|
||||
if( ref.getName().equals( duple.toString() ) &&
|
||||
ref.getOffset() == duple.getStartOffset() )
|
||||
{
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean createConstructorReference( ISymbol classSymbol, ASTExpression expressionList, ITokenDuple duple, List references ){
|
||||
if( classSymbol != null && classSymbol.getTypeInfo().checkBit( TypeInfo.isTypedef ) ){
|
||||
TypeInfo info = classSymbol.getTypeInfo().getFinalType();
|
||||
classSymbol = info.getTypeSymbol();
|
||||
}
|
||||
if( classSymbol == null || ! (classSymbol instanceof IDerivableContainerSymbol ) ){
|
||||
return false;
|
||||
}
|
||||
|
||||
List parameters = new LinkedList();
|
||||
while( expressionList != null ){
|
||||
parameters.add( expressionList.getResultType().getResult() );
|
||||
expressionList = (ASTExpression) expressionList.getRHSExpression();
|
||||
}
|
||||
|
||||
IParameterizedSymbol constructor = null;
|
||||
try {
|
||||
constructor = ((IDerivableContainerSymbol)classSymbol).lookupConstructor( parameters );
|
||||
} catch (ParserSymbolTableException e1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( constructor != null ){
|
||||
IASTReference reference = null;
|
||||
try {
|
||||
reference = createReference( constructor, duple.toString(), duple.getStartOffset() );
|
||||
} catch (ASTSemanticException e2) {
|
||||
return false;
|
||||
}
|
||||
if( reference != null ){
|
||||
addReference( references, reference );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @param kind
|
||||
* @param rhs
|
||||
|
@ -1730,6 +1805,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
if( expression != null )
|
||||
{
|
||||
references.addAll( ((ASTExpression)expression).getReferences() );
|
||||
if( expression.getLHSExpression() != null )
|
||||
getExpressionReferences( expression.getLHSExpression(), references );
|
||||
if( expression.getRHSExpression() != null )
|
||||
getExpressionReferences( expression.getRHSExpression(), references );
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
|
@ -1774,17 +1853,22 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
IContainerSymbol scopeSymbol = scopeToSymbol(scope);
|
||||
|
||||
boolean requireReferenceResolution = false;
|
||||
ISymbol symbol = null;
|
||||
if( duple != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
lookupQualifiedName( scopeSymbol, duple, references, true );
|
||||
symbol = lookupQualifiedName( scopeSymbol, duple, references, true );
|
||||
} catch( ASTSemanticException ase )
|
||||
{
|
||||
requireReferenceResolution = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( symbol != null ){
|
||||
createConstructorReference( symbol, (ASTExpression) expressionList, duple, references );
|
||||
}
|
||||
|
||||
getExpressionReferences( expressionList, references );
|
||||
return new ASTConstructorMemberInitializer(
|
||||
expressionList,
|
||||
|
|
Loading…
Add table
Reference in a new issue