1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-30 21:55:31 +02:00

Patch for Andrew Niefer

Core:
        Added IDerivableContainerSymbol.lookupFunctionForFriendship.
        Modified IASTFactory.createMethod to take an ITokenDuple for the 
method name.
        Added LookupType.FORFRIENDSHIP and use it in LookupElement.
        Modified CompleteParseASTFactory.createMethod to handle friend 
functions.

Tests:
        Added CompleteParseASTTest::testBug48307_FriendFunction_1
        Added CompleteParseASTTest::testBug48307_FriendFunction_2
This commit is contained in:
John Camelon 2004-01-08 16:57:54 +00:00
parent ed90c66221
commit 15e4fa6b79
9 changed files with 129 additions and 21 deletions

View file

@ -1,3 +1,7 @@
2004-01-08 Andrew Niefer
Added CompleteParseASTTest::testBug48307_FriendFunction_1
Added CompleteParseASTTest::testBug48307_FriendFunction_2
2004-01-06 Andrew Niefer
Added ContextualParseTest::testCompletionLookup_LookupKindTHIS

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.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTReference;
import org.eclipse.cdt.core.parser.ast.IASTScope;
@ -41,6 +42,7 @@ import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
import org.eclipse.cdt.core.parser.ast.IASTNode.LookupResult;
import org.eclipse.cdt.internal.core.parser.ParserException;
@ -1113,4 +1115,48 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
while( i.hasNext() )
assertTrue( ((IASTFunction)i.next()).takesVarArgs() );
}
public void testBug48307_FriendFunction_1() throws Exception {
StringWriter writer = new StringWriter();
writer.write( "class A{ public : void foo(); }; " );
writer.write( "class B{ ");
writer.write( " private : int aPrivate;" );
writer.write( " friend void A::foo(); ");
writer.write( "};" );
writer.write( "void A::foo(){}" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTClassSpecifier classB = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTMethod method = (IASTMethod) i.next();
LookupResult result = method.lookup( "a", new IASTNode.LookupKind[] { IASTNode.LookupKind.ALL }, classB );
assertEquals( result.getResultsSize(), 1 );
IASTField field = (IASTField) result.getNodes().next();
assertEquals( field.getName(), "aPrivate" );
}
public void testBug48307_FriendFunction_2() throws Exception {
StringWriter writer = new StringWriter();
writer.write( "void global();" );
writer.write( "class B{ ");
writer.write( " private : int aPrivate;" );
writer.write( " friend void global(); ");
writer.write( "};" );
writer.write( "void global(){}" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTFunction functionDecl = (IASTFunction) i.next();
IASTClassSpecifier classB = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTFunction functionDef = (IASTFunction) i.next();
LookupResult result = functionDef.lookup( "a", new IASTNode.LookupKind[] { IASTNode.LookupKind.ALL }, classB );
assertEquals( result.getResultsSize(), 1 );
IASTField field = (IASTField) result.getNodes().next();
assertEquals( field.getName(), "aPrivate" );
}
}

View file

@ -1,3 +1,10 @@
2004-01-08 Andrew Niefer
Fixing 48307 - PST: Friendship needs to be handled better
Added IDerivableContainerSymbol.lookupFunctionForFriendship.
Modified IASTFactory.createMethod to take an ITokenDuple for the method name.
Added LookupType.FORFRIENDSHIP and use it in LookupElement.
Modified CompleteParseASTFactory.createMethod to handle friend functions.
2004-01-06 Andrew Niefer
For Content Assist, support lookup using LookupKind.THIS (lookup in the class of the this pointer )
Fix bug where forward declared method/functions appeared twice in the content assist lookup results.

View file

@ -180,7 +180,7 @@ public interface IASTFactory
public IASTMethod createMethod(
IASTScope scope,
String name,
ITokenDuple name,
List parameters,
IASTAbstractDeclaration returnType,
IASTExceptionSpecification exception,

View file

@ -463,7 +463,7 @@ public class DeclarationWrapper implements IDeclaratorOwner
return astFactory
.createMethod(
scope,
nested ? declarator.getOwnedDeclarator().getName() : declarator.getName(),
nested ? declarator.getOwnedDeclarator().getNameDuple() : declarator.getNameDuple(),
createParameterList(declarator.getParameters()),
astFactory.createAbstractDeclaration(
constt,

View file

@ -107,6 +107,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
public static final LookupType QUALIFIED = new LookupType( 1 );
public static final LookupType UNQUALIFIED = new LookupType( 2 );
public static final LookupType FORDEFINITION = new LookupType( 3 );
public static final LookupType FORFRIENDSHIP = new LookupType( 4 );
private LookupType( int constant)
{
@ -174,8 +175,11 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
result = startingScope.qualifiedFunctionLookup(name, new LinkedList(parameters));
else if( lookupType == LookupType.UNQUALIFIED )
result = startingScope.unqualifiedFunctionLookup( name, new LinkedList( parameters ) );
else
else if( lookupType == LookupType.FORDEFINITION )
result = startingScope.lookupMethodForDefinition( name, new LinkedList( parameters ) );
else if( lookupType == LookupType.FORFRIENDSHIP ){
result = ((IDerivableContainerSymbol)startingScope).lookupFunctionForFriendship( name, new LinkedList( parameters) );
}
}
else
result = null;
@ -185,8 +189,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
result = startingScope.qualifiedLookup(name, type);
else if( lookupType == LookupType.UNQUALIFIED )
result = startingScope.elaboratedLookup( type, name );
else
else if( lookupType == LookupType.FORDEFINITION )
result = startingScope.lookupMemberForDefinition( name );
else if( lookupType == LookupType.FORFRIENDSHIP )
result = ((IDerivableContainerSymbol)startingScope).lookupForFriendship( name );
}
} catch (ParserSymbolTableException e) {
if( e.reason != ParserSymbolTableException.r_UnableToResolveFunction )
@ -1622,7 +1628,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
name.length() - 1 );
return createMethod(
methodParentScope,
newName.toString(),
newName,
parameters,
returnType,
exception,
@ -1876,7 +1882,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
public IASTMethod createMethod(
IASTScope scope,
String name,
ITokenDuple name,
List parameters,
IASTAbstractDeclaration returnType,
IASTExceptionSpecification exception,
@ -1902,7 +1908,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
public IASTMethod createMethod(
IASTScope scope,
String name,
ITokenDuple nameDuple,
List parameters,
IASTAbstractDeclaration returnType,
IASTExceptionSpecification exception,
@ -1926,7 +1932,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
boolean isDestructor = false;
IContainerSymbol ownerScope = scopeToSymbol( scope );
IParameterizedSymbol symbol = pst.newParameterizedSymbol( name, TypeInfo.t_function );
IParameterizedSymbol symbol = pst.newParameterizedSymbol( nameDuple.toString(), TypeInfo.t_function );
setFunctionTypeInfoBits(isInline, isFriend, isStatic, symbol);
setMethodTypeInfoBits( symbol, isConst, isVolatile, isVirtual, isExplicit );
if(references == null)
@ -1943,9 +1949,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
if(parentName.indexOf(DOUBLE_COLON) != -1){
parentName = parentName.substring(parentName.lastIndexOf(DOUBLE_COLON) + DOUBLE_COLON.length());
}
if( parentName.equals(name) ){
if( parentName.equals(nameDuple.toString()) ){
isConstructor = true;
} else if(name.startsWith(TELTA) && parentName.equals(name.substring(1))){
} else if(nameDuple.getFirstToken().getType() == IToken.tCOMPL && parentName.equals(nameDuple.getLastToken().getImage())){
isDestructor = true;
}
}
@ -1953,7 +1959,9 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
symbol.setIsForwardDeclaration(!isFunctionDefinition);
boolean previouslyDeclared = false;
if( isFunctionDefinition )
IParameterizedSymbol functionDeclaration = null;
if( isFunctionDefinition || isFriend )
{
List functionParameters = new LinkedList();
// the lookup requires a list of type infos
@ -1964,15 +1972,34 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
functionParameters.add(param.getSymbol().getTypeInfo());
}
IParameterizedSymbol functionDeclaration = null;
List functionReferences = new ArrayList();
functionDeclaration =
(IParameterizedSymbol) lookupQualifiedName(ownerScope, name, isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, 0, functionReferences, false, LookupType.FORDEFINITION );
if( functionDeclaration != null )
if( isFriend )
{
functionDeclaration =
(IParameterizedSymbol) lookupQualifiedName(ownerScope, nameDuple, isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, functionReferences, false, LookupType.FORFRIENDSHIP );
} else {
functionDeclaration =
(IParameterizedSymbol) lookupQualifiedName(ownerScope, nameDuple.toString(), isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, 0, functionReferences, false, LookupType.FORDEFINITION );
}
previouslyDeclared = ( functionDeclaration != null );
if( isFriend )
{
if( functionDeclaration != null )
{
symbol.setTypeSymbol( functionDeclaration );
// friend declaration, has no real visibility, set private
visibility = ASTAccessVisibility.PRIVATE;
} else
{
//for a friend function declaration, if there is no prior declaration, the program is illformed
throw new ASTSemanticException();
}
} else if( functionDeclaration != null )
{
previouslyDeclared = true;
functionDeclaration.setTypeSymbol( symbol );
// set the definition visibility = declaration visibility
ASTMethodReference reference = (ASTMethodReference) functionReferences.iterator().next();
@ -1982,7 +2009,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
try
{
if( !isConstructor )
if( isFriend )
{
((IDerivableContainerSymbol)ownerScope).addFriend( functionDeclaration );
} else if( !isConstructor )
ownerScope.addSymbol( symbol );
else
{

View file

@ -193,9 +193,9 @@ public class QuickParseASTFactory extends BaseASTFactory implements IASTFactory
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createMethod(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, java.util.List, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, org.eclipse.cdt.core.parser.ast.IASTExceptionSpecification, boolean, boolean, boolean, int, int, org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration, boolean, boolean, boolean, boolean, boolean, boolean, boolean, org.eclipse.cdt.core.parser.ast.ASTAccessVisibility)
*/
public IASTMethod createMethod(IASTScope scope, String name, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, int nameEndOffset, IASTTemplate ownerTemplate, boolean isConst, boolean isVolatile, boolean isVirtual, boolean isExplicit, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean isFunctionDefinition, boolean hasFunctionTryBlock, boolean hasVariableArguments )
public IASTMethod createMethod(IASTScope scope, ITokenDuple name, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, int nameEndOffset, IASTTemplate ownerTemplate, boolean isConst, boolean isVolatile, boolean isVirtual, boolean isExplicit, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean isFunctionDefinition, boolean hasFunctionTryBlock, boolean hasVariableArguments )
{
return new ASTMethod(scope, name, nameEndOffset, parameters, returnType, exception, isInline, isFriend, isStatic, startOffset, nameOffset, ownerTemplate, isConst, isVolatile, false, false, isVirtual, isExplicit, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock, hasVariableArguments);
return new ASTMethod(scope, name.toString(), nameEndOffset, parameters, returnType, exception, isInline, isFriend, isStatic, startOffset, nameOffset, ownerTemplate, isConst, isVolatile, false, false, isVirtual, isExplicit, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock, hasVariableArguments);
}
/* (non-Javadoc)

View file

@ -287,6 +287,25 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
return ParserSymbolTable.resolveAmbiguities( data );
}
public IParameterizedSymbol lookupFunctionForFriendship( String name, List parameters ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
data.parameters = parameters;
IContainerSymbol enclosing = getContainingSymbol();
if( enclosing != null && enclosing.isType( TypeInfo.t_namespace, TypeInfo.t_union ) ){
while( enclosing != null && ( enclosing.getType() != TypeInfo.t_namespace) )
{
enclosing = enclosing.getContainingSymbol();
}
}
data.stopAt = enclosing;
ParserSymbolTable.lookup( data, this );
return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data );
}
public List getFriends(){
if( _friends == null ){
_friends = new LinkedList();

View file

@ -40,6 +40,8 @@ public interface IDerivableContainerSymbol extends IContainerSymbol {
public void addFriend( ISymbol friend ) throws ParserSymbolTableException;
public ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException;
public IParameterizedSymbol lookupFunctionForFriendship( String name, List parameters ) throws ParserSymbolTableException;
public List getFriends();
public interface IParentSymbol{