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:
parent
ed90c66221
commit
15e4fa6b79
9 changed files with 129 additions and 21 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -180,7 +180,7 @@ public interface IASTFactory
|
|||
|
||||
public IASTMethod createMethod(
|
||||
IASTScope scope,
|
||||
String name,
|
||||
ITokenDuple name,
|
||||
List parameters,
|
||||
IASTAbstractDeclaration returnType,
|
||||
IASTExceptionSpecification exception,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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{
|
||||
|
|
Loading…
Add table
Reference in a new issue