From 67ad10a37b9e9bcba5e44cca4c44ea7e9b93e900 Mon Sep 17 00:00:00 2001 From: Hoda Amer Date: Wed, 17 Dec 2003 20:51:39 +0000 Subject: [PATCH] Symbol Table work for Content Assist By Andrew --- core/org.eclipse.cdt.core.tests/ChangeLog | 7 + .../parser/tests/ContextualParseTest.java | 125 ++++++++++++++++++ .../parser/tests/ParserSymbolTableTest.java | 24 +++- .../parser/ChangeLog-parser | 6 + .../cdt/core/parser/ast/IASTFactory.java | 2 +- .../cdt/internal/core/parser/Parser.java | 2 +- .../ast/complete/CompleteParseASTFactory.java | 26 +++- .../ast/quick/QuickParseASTFactory.java | 2 +- .../internal/core/parser/pst/BasicSymbol.java | 9 ++ .../core/parser/pst/ContainerSymbol.java | 33 ++++- .../parser/pst/DerivableContainerSymbol.java | 51 +++---- .../parser/pst/IDerivableContainerSymbol.java | 4 + .../cdt/internal/core/parser/pst/ISymbol.java | 2 + .../core/parser/pst/ParserSymbolTable.java | 25 ++-- 14 files changed, 275 insertions(+), 43 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog index 96d3deb91d1..98e2b1420db 100644 --- a/core/org.eclipse.cdt.core.tests/ChangeLog +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -1,3 +1,10 @@ +2003-12-17 Andrew Niefer + test changes for content assist + added ContextualParseTest.testCompletionLookup_FriendClass_1() + added ContextualParseTest.testCompletionLookup_FriendClass_2() + added ContextualParseTest.testCompletionLookup_ParametersAsLocalVariables() + modified ParserSymbolTableTest.testVisibilityDetermination() + 2003-12-17 Hoda Amer Small modifications to cope with the new interfaces diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ContextualParseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ContextualParseTest.java index 1f1274d0829..d67ed59ae0f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ContextualParseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ContextualParseTest.java @@ -17,11 +17,13 @@ import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier; +import org.eclipse.cdt.core.parser.ast.IASTCodeScope; import org.eclipse.cdt.core.parser.ast.IASTCompletionNode; import org.eclipse.cdt.core.parser.ast.IASTField; import org.eclipse.cdt.core.parser.ast.IASTFunction; import org.eclipse.cdt.core.parser.ast.IASTMethod; import org.eclipse.cdt.core.parser.ast.IASTNode; +import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.parser.ast.IASTVariable; import org.eclipse.cdt.core.parser.ast.IASTNode.LookupResult; import org.eclipse.cdt.internal.core.parser.ParserLogService; @@ -246,4 +248,127 @@ public class ContextualParseTest extends CompleteParseBaseTest { assertEquals( method.getName(), "aMethod" ); assertEquals( baseMethod.getName(), "aPublicBaseMethod" ); } + + public void testCompletionLookup_FriendClass_1() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write( "class A {" ); + writer.write( " private: void aPrivateMethod();" ); + writer.write( " friend class C;" ); + writer.write( "};" ); + + writer.write( "class C {" ); + writer.write( " void foo();" ); + writer.write( "};" ); + + writer.write( "void C::foo(){" ); + writer.write( " A a;" ); + writer.write( " a.a \n" ); + + String code = writer.toString(); + int index = code.indexOf( "a.a" ); + + IASTCompletionNode node = parse( code, index + 3 ); + + assertNotNull( node ); + + String prefix = node.getCompletionPrefix(); + assertEquals( prefix, "a" ); + + assertTrue( node.getCompletionScope() instanceof IASTFunction ); + assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.MEMBER_REFERENCE ); + assertNotNull( node.getCompletionContext() ); + assertTrue( node.getCompletionContext() instanceof IASTClassSpecifier ); + + LookupResult result = node.getCompletionScope().lookup( prefix, new IASTNode.LookupKind [] { IASTNode.LookupKind.METHODS }, node.getCompletionContext() ); + assertEquals( result.getPrefix(), prefix ); + + Iterator iter = result.getNodes(); + assertTrue( iter.hasNext() ); + + IASTMethod method = (IASTMethod) iter.next(); + + assertFalse( iter.hasNext() ); + + assertEquals( method.getName(), "aPrivateMethod" ); + } + + public void testCompletionLookup_FriendClass_2() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write( "class C {" ); + writer.write( " void foo();" ); + writer.write( "};" ); + writer.write( "class A {" ); + writer.write( " private: void aPrivateMethod();" ); + writer.write( " friend class C;" ); + writer.write( "};" ); + + writer.write( "void C::foo(){" ); + writer.write( " A a;" ); + writer.write( " a.a \n" ); + + String code = writer.toString(); + int index = code.indexOf( "a.a" ); + + IASTCompletionNode node = parse( code, index + 3 ); + + assertNotNull( node ); + + String prefix = node.getCompletionPrefix(); + assertEquals( prefix, "a" ); + + assertTrue( node.getCompletionScope() instanceof IASTFunction ); + assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.MEMBER_REFERENCE ); + assertNotNull( node.getCompletionContext() ); + assertTrue( node.getCompletionContext() instanceof IASTClassSpecifier ); + + LookupResult result = node.getCompletionScope().lookup( prefix, new IASTNode.LookupKind [] { IASTNode.LookupKind.METHODS }, node.getCompletionContext() ); + assertEquals( result.getPrefix(), prefix ); + + Iterator iter = result.getNodes(); + assertTrue( iter.hasNext() ); + + IASTMethod method = (IASTMethod) iter.next(); + + assertFalse( iter.hasNext() ); + + assertEquals( method.getName(), "aPrivateMethod" ); + } + + public void testCompletionLookup_ParametersAsLocalVariables() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write( "int foo( int aParameter ){" ); + writer.write( " int aLocal;" ); + writer.write( " if( aLocal != 0 ){" ); + writer.write( " int aBlockLocal;" ); + writer.write( " a \n" ); + + String code = writer.toString(); + int index = code.indexOf( " a " ); + + IASTCompletionNode node = parse( code, index + 2 ); + + assertNotNull( node ); + + String prefix = node.getCompletionPrefix(); + assertEquals( prefix, "a" ); + + assertTrue( node.getCompletionScope() instanceof IASTCodeScope ); + assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.SINGLE_NAME_REFERENCE ); + assertNull( node.getCompletionContext() ); + + LookupResult result = node.getCompletionScope().lookup( prefix, new IASTNode.LookupKind [] { IASTNode.LookupKind.LOCAL_VARIABLES }, node.getCompletionContext() ); + assertEquals( result.getPrefix(), prefix ); + + Iterator iter = result.getNodes(); + + IASTVariable aBlockLocal = (IASTVariable) iter.next(); + IASTVariable aLocal = (IASTVariable) iter.next(); + IASTParameterDeclaration aParameter = (IASTParameterDeclaration) iter.next(); + + assertFalse( iter.hasNext() ); + + assertEquals( aBlockLocal.getName(), "aBlockLocal" ); + assertEquals( aLocal.getName(), "aLocal" ); + assertEquals( aParameter.getName(), "aParameter" ); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java index f870fe91da0..9f47748c7bc 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java @@ -3209,20 +3209,36 @@ public class ParserSymbolTableTest extends TestCase { } /** - * class A { public: static int i; }; + * class D { }; + * class A { + * public: static int i; + * private: static int j; + * friend class D; + * }; * class B : private A {}; * class C : public B, public A {}; * + * * @throws Exception */ public void testVisibilityDetermination() throws Exception{ newTable(); + IDerivableContainerSymbol D = table.newDerivableContainerSymbol( "D", TypeInfo.t_class ); + table.getCompilationUnit().addSymbol( D ); + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); ISymbol i = table.newSymbol( "i", TypeInfo.t_int ); + ISymbol j = table.newSymbol( "j", TypeInfo.t_int ); table.getCompilationUnit().addSymbol( A ); + + ISymbol friend = A.lookupForFriendship( "D" ); + assertEquals( friend, D ); + A.addFriend( friend ); + A.addSymbol( i ); + A.addSymbol( j ); IASTCompilationUnit compUnit = new ASTCompilationUnit(table.getCompilationUnit() ); ISymbolASTExtension cuExtension = new StandardSymbolExtension( table.getCompilationUnit(), (ASTSymbol) compUnit ); @@ -3235,6 +3251,10 @@ public class ParserSymbolTableTest extends TestCase { IASTField field = new ASTField(i, null, null, null, 0, 0, 0, new ArrayList(), false, null, ASTAccessVisibility.PUBLIC ); ISymbolASTExtension extension = new StandardSymbolExtension( i, (ASTSymbol) field ); i.setASTExtension( extension ); + + field = new ASTField(i, null, null, null, 0, 0, 0, new ArrayList(), false, null, ASTAccessVisibility.PRIVATE ); + extension = new StandardSymbolExtension( j, (ASTSymbol) field ); + j.setASTExtension( extension ); IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class ); B.addParent( A, false, ASTAccessVisibility.PRIVATE, 0, null ); @@ -3248,6 +3268,8 @@ public class ParserSymbolTableTest extends TestCase { assertTrue( table.getCompilationUnit().isVisible( i, A ) ); assertFalse( table.getCompilationUnit().isVisible( i, B ) ); assertTrue( table.getCompilationUnit().isVisible(i, C ) ); + assertTrue( D.isVisible( j, A ) ); + assertFalse( D.isVisible( j, B ) ); } /** diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog-parser b/core/org.eclipse.cdt.core/parser/ChangeLog-parser index 0ba46abaee7..d4f6f601205 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog-parser +++ b/core/org.eclipse.cdt.core/parser/ChangeLog-parser @@ -1,3 +1,9 @@ +2003-12-17 Andrew Niefer + Content Assist work: + - change parser & symbol table to handle handle friend classes + - change visibility filtering to check for friendship + - fix finding function parameters in prefix lookup + 2003-12-17 Hoda Amer Content Assist work : Integrated with Parser and Symbol table modifications diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java index 4c3f4322833..3adcc607080 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java @@ -97,7 +97,7 @@ public interface IASTFactory IASTScope scope, ASTClassKind elaboratedClassKind, ITokenDuple typeName, - int startingOffset, int endOffset, boolean isForewardDecl) throws ASTSemanticException; + int startingOffset, int endOffset, boolean isForewardDecl, boolean isFriend) throws ASTSemanticException; public IASTEnumerationSpecifier createEnumerationSpecifier( IASTScope scope, diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index d54136c4b62..21b4ca75204 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -1654,7 +1654,7 @@ public abstract class Parser implements IParser d, t.getOffset(), d.getLastToken().getEndOffset(), - isForewardDecl ); + isForewardDecl, sdw.isFriend() ); } catch (ASTSemanticException e) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index 1f55f16a164..579cedb3704 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -2485,7 +2485,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } - public IASTElaboratedTypeSpecifier createElaboratedTypeSpecifier(IASTScope scope, ASTClassKind kind, ITokenDuple name, int startingOffset, int endOffset, boolean isForewardDecl) throws ASTSemanticException + public IASTElaboratedTypeSpecifier createElaboratedTypeSpecifier(IASTScope scope, ASTClassKind kind, ITokenDuple name, int startingOffset, int endOffset, boolean isForewardDecl, boolean isFriend) throws ASTSemanticException { IContainerSymbol currentScopeSymbol = scopeToSymbol(scope); TypeInfo.eType pstType = classKindToTypeInfo(kind); @@ -2504,7 +2504,14 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto ISymbol checkSymbol = null; try { - checkSymbol = currentScopeSymbol.elaboratedLookup( pstType, lastToken.getImage()); + if( isFriend ){ + if( !(currentScopeSymbol instanceof IDerivableContainerSymbol) ){ + throw new ASTSemanticException(); + } + checkSymbol = ((IDerivableContainerSymbol)currentScopeSymbol).lookupForFriendship( lastToken.getImage() ); + } else { + checkSymbol = currentScopeSymbol.elaboratedLookup( pstType, lastToken.getImage()); + } } catch (ParserSymbolTableException e) { @@ -2520,7 +2527,11 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto checkSymbol.setIsForwardDeclaration( true ); try { - currentScopeSymbol.addSymbol( checkSymbol ); + if( isFriend ){ + ((IDerivableContainerSymbol)currentScopeSymbol).addFriend( checkSymbol ); + } else { + currentScopeSymbol.addSymbol( checkSymbol ); + } } catch (ParserSymbolTableException e1) { @@ -2538,6 +2549,13 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto { throw new ASTSemanticException(); } + } else if( isFriend ){ + try { + ((IDerivableContainerSymbol)currentScopeSymbol).addFriend( checkSymbol ); + } catch (ParserSymbolTableException e1) { + throw new ASTSemanticException(); + } + } } @@ -2612,7 +2630,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto public IASTCodeScope createNewCodeBlock(IASTScope scope) { IContainerSymbol symbol = scopeToSymbol( scope ); - IContainerSymbol newScope = pst.newContainerSymbol(""); + IContainerSymbol newScope = pst.newContainerSymbol("", TypeInfo.t_block); newScope.setContainingSymbol(symbol); ASTCodeScope codeScope = new ASTCodeScope( newScope ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java index afd5434dba3..4cf9c136f57 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java @@ -263,7 +263,7 @@ public class QuickParseASTFactory extends BaseASTFactory implements IASTFactory return new ASTAbstractTypeSpecifierDeclaration( scope, typeSpecifier, template, startingOffset, endingOffset ); } - public IASTElaboratedTypeSpecifier createElaboratedTypeSpecifier(IASTScope scope, ASTClassKind elaboratedClassKind, ITokenDuple typeName, int startingOffset, int endOffset, boolean isForewardDecl) + public IASTElaboratedTypeSpecifier createElaboratedTypeSpecifier(IASTScope scope, ASTClassKind elaboratedClassKind, ITokenDuple typeName, int startingOffset, int endOffset, boolean isForewardDecl, boolean isFriend) { return new ASTElaboratedTypeSpecifier( scope, elaboratedClassKind, typeName.toString(), startingOffset, typeName.getFirstToken().getOffset(), typeName.getLastToken().getEndOffset(), endOffset ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java index bee66f4f8af..00521aecc7e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/BasicSymbol.java @@ -169,12 +169,21 @@ public class BasicSymbol implements Cloneable, ISymbol public Map getArgumentMap(){ return null; } + + public boolean getIsInvisible(){ + return _isInvisible; + } + public void setIsInvisible( boolean invisible ){ + _isInvisible = invisible ; + } + private String _name; //our name private ISymbolASTExtension _object; //the object associated with us private TypeInfo _typeInfo; //our type info private IContainerSymbol _containingScope; //the scope that contains us private int _depth; //how far down the scope stack we are + private boolean _isInvisible = false; //used by friend declarations (11.4-9) private boolean _isTemplateMember = false; private TemplateInstance _templateInstance; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java index a0745d7168b..0b5791f264d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java @@ -635,8 +635,12 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { { return true; } + + //if this is a friend of the symbolContainer, then we are good + if( isFriendOf( symbolContainer ) ){ + return true; + } - //TODO: friendship if( visibility == ASTAccessVisibility.PROTECTED ) { try { @@ -651,6 +655,33 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { return true; } + protected boolean isFriendOf( IContainerSymbol symbol ){ + if( symbol instanceof IDerivableContainerSymbol ){ + IContainerSymbol container = this.getContainingSymbol(); + + while( container != null && container.isType( TypeInfo.t_block ) ){ + container = container.getContainingSymbol(); + } + if( container != null && !container.isType( TypeInfo.t_class, TypeInfo.t_union ) ){ + container = null; + } + + IDerivableContainerSymbol derivable = (IDerivableContainerSymbol) symbol; + + Iterator iter = derivable.getFriends().iterator(); + while( iter.hasNext() ){ + ISymbol friend = (ISymbol) iter.next(); + ISymbol typeSymbol = friend.getTypeSymbol(); + if( friend == this || typeSymbol == this || + friend == container || ( container != null && typeSymbol == container ) ) + { + return true; + } + } + } + return false; + } + /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#instantiate(java.util.List) */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java index 797f7ef67b2..ddd29ad293e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java @@ -241,24 +241,22 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva * TODO: if/when the parser symbol table starts caring about visibility * (public/protected/private) we will need to do more to record friendship. */ - private ISymbol addFriend( String name ) throws ParserSymbolTableException{ - ISymbol friend = lookupForFriendship( name ); - - if( friend == null ){ - friend = getSymbolTable().newSymbol( name ); - friend.getTypeInfo().setIsForwardDeclaration( true ); - - IContainerSymbol containing = getContainingSymbol(); - //find innermost enclosing namespace - while( containing != null && containing.getType() != TypeInfo.t_namespace ){ - containing = containing.getContainingSymbol(); + public void addFriend( ISymbol friend ) throws ParserSymbolTableException{ + //is this symbol already in the table? + IContainerSymbol containing = friend.getContainingSymbol(); + if( containing == null ){ + //its not, it goes in the innermost enclosing namespace + IContainerSymbol enclosing = getContainingSymbol(); + while( enclosing != null && !enclosing.isType( TypeInfo.t_namespace ) ){ + enclosing = enclosing.getContainingSymbol(); } - - IContainerSymbol namespace = ( containing == null ) ? getSymbolTable().getCompilationUnit() : containing; - namespace.addSymbol( friend ); + + friend.setIsInvisible( true ); + friend.setIsForwardDeclaration( true ); + enclosing.addSymbol( friend ); } - return friend; + getFriends().add( friend ); } /** @@ -273,24 +271,28 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva * without considering scopes that are outside the innermost enclosing non- * class scope. */ - private ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException{ + public ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException{ LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() ); - - boolean inClass = ( getType() == TypeInfo.t_class); - + IContainerSymbol enclosing = getContainingSymbol(); - while( enclosing != null && (inClass ? enclosing.getType() != TypeInfo.t_class - : enclosing.getType() == TypeInfo.t_namespace) ) - { - enclosing = 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 ParserSymbolTable.resolveAmbiguities( data ); } + public List getFriends(){ + if( _friends == null ){ + _friends = new LinkedList(); + } + return _friends; + } static private class AddParentCommand extends Command{ public AddParentCommand( IDerivableContainerSymbol container, ParentWrapper wrapper ){ @@ -363,4 +365,5 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva private LinkedList _constructors; //constructor list private LinkedList _parentScopes; //inherited scopes (is base classes) + private LinkedList _friends; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java index fab40fe569e..6eb6d9b1f26 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java @@ -38,6 +38,10 @@ public interface IDerivableContainerSymbol extends IContainerSymbol { public IParameterizedSymbol lookupConstructor( List parameters ) throws ParserSymbolTableException; public List getConstructors(); + public void addFriend( ISymbol friend ) throws ParserSymbolTableException; + public ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException; + public List getFriends(); + public interface IParentSymbol{ public void setParent( ISymbol parent ); public ISymbol getParent(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java index 7522c0decb9..d51184d6bca 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java @@ -54,6 +54,8 @@ public interface ISymbol extends Cloneable { public void setTemplateInstance( TemplateInstance instance ); public int getDepth(); + public boolean getIsInvisible(); + public void setIsInvisible( boolean invisible ); /** * @param name diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java index 4f38758679e..a221b21c8dc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java @@ -335,7 +335,7 @@ public class ParserSymbolTable { name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name; while( name != null ){ if( nameMatches( data, name ) ){ - obj = parameters.get( data.name ); + obj = parameters.get( name ); obj = collectSymbol( data, obj ); if( obj != null ){ found.put( name, obj ); @@ -393,7 +393,7 @@ public class ParserSymbolTable { IContainerSymbol cls = null; while( symbol != null ){ - if( checkType( data, symbol ) ){//, data.type, data.upperType ) ){ + if( !symbol.getIsInvisible() && checkType( data, symbol ) ){//, data.type, data.upperType ) ){ if( symbol.isTemplateMember() && data.templateInstance != null ) foundSymbol = new TemplateInstance( symbol.getSymbolTable(), symbol, data.templateInstance.getArgumentMap() ); else @@ -674,12 +674,17 @@ public class ParserSymbolTable { TypeInfo.eType newType = newSymbol.getType(); //handle forward decls - if( origSymbol.getTypeInfo().isForwardDeclaration() && - origSymbol.getTypeSymbol() == newSymbol ) - { - return true; + if( origSymbol.getTypeInfo().isForwardDeclaration() ){ + if( origSymbol.getTypeSymbol() == newSymbol ) + return true; + + //friend class declarations + if( origSymbol.getIsInvisible() && origSymbol.isType( newSymbol.getType() ) ){ + origSymbol.getTypeInfo().setTypeSymbol( newSymbol ); + return true; + } } - + if( (origType.compareTo(TypeInfo.t_class) >= 0 && origType.compareTo(TypeInfo.t_enumeration) <= 0) && //class name or enumeration ... ( newType == TypeInfo.t_type || (newType.compareTo( TypeInfo.t_function ) >= 0 /*&& newType <= TypeInfo.typeMask*/) ) ){ @@ -707,7 +712,8 @@ public class ParserSymbolTable { Iterator iter = origList.iterator(); ISymbol symbol = (ISymbol) iter.next(); - boolean valid = ( (symbol.getType().compareTo( TypeInfo.t_class ) >= 0 ) && (symbol.getType().compareTo( TypeInfo.t_enumeration ) <= 0 ) ); + boolean valid = isValidOverload( symbol, newSymbol );//( (symbol.getType().compareTo( TypeInfo.t_class ) >= 0 ) && (symbol.getType().compareTo( TypeInfo.t_enumeration ) <= 0 ) ); + if( !valid && (symbol instanceof IParameterizedSymbol) ) valid = isValidFunctionOverload( (IParameterizedSymbol)symbol, (IParameterizedSymbol)newSymbol ); @@ -2239,7 +2245,6 @@ public class ParserSymbolTable { static protected class LookupData { - public Set ambiguities; public String name; public Map usingDirectives; @@ -2256,7 +2261,7 @@ public class ParserSymbolTable { public boolean ignoreUsingDirectives = false; public boolean usingDirectivesOnly = false; public boolean forUserDefinedConversion = false; - + public Map foundItems = null; public ISymbol templateInstance = null;