mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Symbol Table work for Content Assist By Andrew
This commit is contained in:
parent
33f033599d
commit
67ad10a37b
14 changed files with 275 additions and 43 deletions
|
@ -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
|
2003-12-17 Hoda Amer
|
||||||
Small modifications to cope with the new interfaces
|
Small modifications to cope with the new interfaces
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,13 @@ import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||||
import org.eclipse.cdt.core.parser.ParserMode;
|
import org.eclipse.cdt.core.parser.ParserMode;
|
||||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
|
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.IASTCompletionNode;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTField;
|
import org.eclipse.cdt.core.parser.ast.IASTField;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTFunction;
|
import org.eclipse.cdt.core.parser.ast.IASTFunction;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTMethod;
|
import org.eclipse.cdt.core.parser.ast.IASTMethod;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTNode;
|
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.IASTVariable;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTNode.LookupResult;
|
import org.eclipse.cdt.core.parser.ast.IASTNode.LookupResult;
|
||||||
import org.eclipse.cdt.internal.core.parser.ParserLogService;
|
import org.eclipse.cdt.internal.core.parser.ParserLogService;
|
||||||
|
@ -246,4 +248,127 @@ public class ContextualParseTest extends CompleteParseBaseTest {
|
||||||
assertEquals( method.getName(), "aMethod" );
|
assertEquals( method.getName(), "aMethod" );
|
||||||
assertEquals( baseMethod.getName(), "aPublicBaseMethod" );
|
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" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 B : private A {};
|
||||||
* class C : public B, public A {};
|
* class C : public B, public A {};
|
||||||
*
|
*
|
||||||
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void testVisibilityDetermination() throws Exception{
|
public void testVisibilityDetermination() throws Exception{
|
||||||
newTable();
|
newTable();
|
||||||
|
|
||||||
|
IDerivableContainerSymbol D = table.newDerivableContainerSymbol( "D", TypeInfo.t_class );
|
||||||
|
table.getCompilationUnit().addSymbol( D );
|
||||||
|
|
||||||
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
|
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class );
|
||||||
ISymbol i = table.newSymbol( "i", TypeInfo.t_int );
|
ISymbol i = table.newSymbol( "i", TypeInfo.t_int );
|
||||||
|
ISymbol j = table.newSymbol( "j", TypeInfo.t_int );
|
||||||
|
|
||||||
table.getCompilationUnit().addSymbol( A );
|
table.getCompilationUnit().addSymbol( A );
|
||||||
|
|
||||||
|
ISymbol friend = A.lookupForFriendship( "D" );
|
||||||
|
assertEquals( friend, D );
|
||||||
|
A.addFriend( friend );
|
||||||
|
|
||||||
A.addSymbol( i );
|
A.addSymbol( i );
|
||||||
|
A.addSymbol( j );
|
||||||
|
|
||||||
IASTCompilationUnit compUnit = new ASTCompilationUnit(table.getCompilationUnit() );
|
IASTCompilationUnit compUnit = new ASTCompilationUnit(table.getCompilationUnit() );
|
||||||
ISymbolASTExtension cuExtension = new StandardSymbolExtension( table.getCompilationUnit(), (ASTSymbol) compUnit );
|
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 );
|
IASTField field = new ASTField(i, null, null, null, 0, 0, 0, new ArrayList(), false, null, ASTAccessVisibility.PUBLIC );
|
||||||
ISymbolASTExtension extension = new StandardSymbolExtension( i, (ASTSymbol) field );
|
ISymbolASTExtension extension = new StandardSymbolExtension( i, (ASTSymbol) field );
|
||||||
i.setASTExtension( extension );
|
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 );
|
IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class );
|
||||||
B.addParent( A, false, ASTAccessVisibility.PRIVATE, 0, null );
|
B.addParent( A, false, ASTAccessVisibility.PRIVATE, 0, null );
|
||||||
|
@ -3248,6 +3268,8 @@ public class ParserSymbolTableTest extends TestCase {
|
||||||
assertTrue( table.getCompilationUnit().isVisible( i, A ) );
|
assertTrue( table.getCompilationUnit().isVisible( i, A ) );
|
||||||
assertFalse( table.getCompilationUnit().isVisible( i, B ) );
|
assertFalse( table.getCompilationUnit().isVisible( i, B ) );
|
||||||
assertTrue( table.getCompilationUnit().isVisible(i, C ) );
|
assertTrue( table.getCompilationUnit().isVisible(i, C ) );
|
||||||
|
assertTrue( D.isVisible( j, A ) );
|
||||||
|
assertFalse( D.isVisible( j, B ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
2003-12-17 Hoda Amer
|
||||||
Content Assist work : Integrated with Parser and Symbol table modifications
|
Content Assist work : Integrated with Parser and Symbol table modifications
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ public interface IASTFactory
|
||||||
IASTScope scope,
|
IASTScope scope,
|
||||||
ASTClassKind elaboratedClassKind,
|
ASTClassKind elaboratedClassKind,
|
||||||
ITokenDuple typeName,
|
ITokenDuple typeName,
|
||||||
int startingOffset, int endOffset, boolean isForewardDecl) throws ASTSemanticException;
|
int startingOffset, int endOffset, boolean isForewardDecl, boolean isFriend) throws ASTSemanticException;
|
||||||
|
|
||||||
public IASTEnumerationSpecifier createEnumerationSpecifier(
|
public IASTEnumerationSpecifier createEnumerationSpecifier(
|
||||||
IASTScope scope,
|
IASTScope scope,
|
||||||
|
|
|
@ -1654,7 +1654,7 @@ public abstract class Parser implements IParser
|
||||||
d,
|
d,
|
||||||
t.getOffset(),
|
t.getOffset(),
|
||||||
d.getLastToken().getEndOffset(),
|
d.getLastToken().getEndOffset(),
|
||||||
isForewardDecl );
|
isForewardDecl, sdw.isFriend() );
|
||||||
}
|
}
|
||||||
catch (ASTSemanticException e)
|
catch (ASTSemanticException e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
IContainerSymbol currentScopeSymbol = scopeToSymbol(scope);
|
||||||
TypeInfo.eType pstType = classKindToTypeInfo(kind);
|
TypeInfo.eType pstType = classKindToTypeInfo(kind);
|
||||||
|
@ -2504,7 +2504,14 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
ISymbol checkSymbol = null;
|
ISymbol checkSymbol = null;
|
||||||
try
|
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)
|
catch (ParserSymbolTableException e)
|
||||||
{
|
{
|
||||||
|
@ -2520,7 +2527,11 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
checkSymbol.setIsForwardDeclaration( true );
|
checkSymbol.setIsForwardDeclaration( true );
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
currentScopeSymbol.addSymbol( checkSymbol );
|
if( isFriend ){
|
||||||
|
((IDerivableContainerSymbol)currentScopeSymbol).addFriend( checkSymbol );
|
||||||
|
} else {
|
||||||
|
currentScopeSymbol.addSymbol( checkSymbol );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (ParserSymbolTableException e1)
|
catch (ParserSymbolTableException e1)
|
||||||
{
|
{
|
||||||
|
@ -2538,6 +2549,13 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
{
|
{
|
||||||
throw new ASTSemanticException();
|
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) {
|
public IASTCodeScope createNewCodeBlock(IASTScope scope) {
|
||||||
IContainerSymbol symbol = scopeToSymbol( scope );
|
IContainerSymbol symbol = scopeToSymbol( scope );
|
||||||
|
|
||||||
IContainerSymbol newScope = pst.newContainerSymbol("");
|
IContainerSymbol newScope = pst.newContainerSymbol("", TypeInfo.t_block);
|
||||||
newScope.setContainingSymbol(symbol);
|
newScope.setContainingSymbol(symbol);
|
||||||
|
|
||||||
ASTCodeScope codeScope = new ASTCodeScope( newScope );
|
ASTCodeScope codeScope = new ASTCodeScope( newScope );
|
||||||
|
|
|
@ -263,7 +263,7 @@ public class QuickParseASTFactory extends BaseASTFactory implements IASTFactory
|
||||||
return new ASTAbstractTypeSpecifierDeclaration( scope, typeSpecifier, template, startingOffset, endingOffset );
|
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 );
|
return new ASTElaboratedTypeSpecifier( scope, elaboratedClassKind, typeName.toString(), startingOffset, typeName.getFirstToken().getOffset(), typeName.getLastToken().getEndOffset(), endOffset );
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,12 +169,21 @@ public class BasicSymbol implements Cloneable, ISymbol
|
||||||
public Map getArgumentMap(){
|
public Map getArgumentMap(){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getIsInvisible(){
|
||||||
|
return _isInvisible;
|
||||||
|
}
|
||||||
|
public void setIsInvisible( boolean invisible ){
|
||||||
|
_isInvisible = invisible ;
|
||||||
|
}
|
||||||
|
|
||||||
private String _name; //our name
|
private String _name; //our name
|
||||||
private ISymbolASTExtension _object; //the object associated with us
|
private ISymbolASTExtension _object; //the object associated with us
|
||||||
private TypeInfo _typeInfo; //our type info
|
private TypeInfo _typeInfo; //our type info
|
||||||
private IContainerSymbol _containingScope; //the scope that contains us
|
private IContainerSymbol _containingScope; //the scope that contains us
|
||||||
private int _depth; //how far down the scope stack we are
|
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 boolean _isTemplateMember = false;
|
||||||
private TemplateInstance _templateInstance;
|
private TemplateInstance _templateInstance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -635,8 +635,12 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
|
||||||
{
|
{
|
||||||
return true;
|
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 )
|
if( visibility == ASTAccessVisibility.PROTECTED )
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
@ -651,6 +655,33 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
|
||||||
return true;
|
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)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#instantiate(java.util.List)
|
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#instantiate(java.util.List)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -241,24 +241,22 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
|
||||||
* TODO: if/when the parser symbol table starts caring about visibility
|
* TODO: if/when the parser symbol table starts caring about visibility
|
||||||
* (public/protected/private) we will need to do more to record friendship.
|
* (public/protected/private) we will need to do more to record friendship.
|
||||||
*/
|
*/
|
||||||
private ISymbol addFriend( String name ) throws ParserSymbolTableException{
|
public void addFriend( ISymbol friend ) throws ParserSymbolTableException{
|
||||||
ISymbol friend = lookupForFriendship( name );
|
//is this symbol already in the table?
|
||||||
|
IContainerSymbol containing = friend.getContainingSymbol();
|
||||||
if( friend == null ){
|
if( containing == null ){
|
||||||
friend = getSymbolTable().newSymbol( name );
|
//its not, it goes in the innermost enclosing namespace
|
||||||
friend.getTypeInfo().setIsForwardDeclaration( true );
|
IContainerSymbol enclosing = getContainingSymbol();
|
||||||
|
while( enclosing != null && !enclosing.isType( TypeInfo.t_namespace ) ){
|
||||||
IContainerSymbol containing = getContainingSymbol();
|
enclosing = enclosing.getContainingSymbol();
|
||||||
//find innermost enclosing namespace
|
|
||||||
while( containing != null && containing.getType() != TypeInfo.t_namespace ){
|
|
||||||
containing = containing.getContainingSymbol();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IContainerSymbol namespace = ( containing == null ) ? getSymbolTable().getCompilationUnit() : containing;
|
friend.setIsInvisible( true );
|
||||||
namespace.addSymbol( friend );
|
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-
|
* without considering scopes that are outside the innermost enclosing non-
|
||||||
* class scope.
|
* 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() );
|
LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
|
||||||
|
|
||||||
boolean inClass = ( getType() == TypeInfo.t_class);
|
|
||||||
|
|
||||||
IContainerSymbol enclosing = getContainingSymbol();
|
IContainerSymbol enclosing = getContainingSymbol();
|
||||||
while( enclosing != null && (inClass ? enclosing.getType() != TypeInfo.t_class
|
if( enclosing != null && enclosing.isType( TypeInfo.t_namespace, TypeInfo.t_union ) ){
|
||||||
: enclosing.getType() == TypeInfo.t_namespace) )
|
while( enclosing != null && ( enclosing.getType() != TypeInfo.t_namespace) )
|
||||||
{
|
{
|
||||||
enclosing = enclosing.getContainingSymbol();
|
enclosing = enclosing.getContainingSymbol();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.stopAt = enclosing;
|
data.stopAt = enclosing;
|
||||||
|
|
||||||
ParserSymbolTable.lookup( data, this );
|
ParserSymbolTable.lookup( data, this );
|
||||||
return ParserSymbolTable.resolveAmbiguities( data );
|
return ParserSymbolTable.resolveAmbiguities( data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List getFriends(){
|
||||||
|
if( _friends == null ){
|
||||||
|
_friends = new LinkedList();
|
||||||
|
}
|
||||||
|
return _friends;
|
||||||
|
}
|
||||||
|
|
||||||
static private class AddParentCommand extends Command{
|
static private class AddParentCommand extends Command{
|
||||||
public AddParentCommand( IDerivableContainerSymbol container, ParentWrapper wrapper ){
|
public AddParentCommand( IDerivableContainerSymbol container, ParentWrapper wrapper ){
|
||||||
|
@ -363,4 +365,5 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
|
||||||
|
|
||||||
private LinkedList _constructors; //constructor list
|
private LinkedList _constructors; //constructor list
|
||||||
private LinkedList _parentScopes; //inherited scopes (is base classes)
|
private LinkedList _parentScopes; //inherited scopes (is base classes)
|
||||||
|
private LinkedList _friends;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,10 @@ public interface IDerivableContainerSymbol extends IContainerSymbol {
|
||||||
public IParameterizedSymbol lookupConstructor( List parameters ) throws ParserSymbolTableException;
|
public IParameterizedSymbol lookupConstructor( List parameters ) throws ParserSymbolTableException;
|
||||||
public List getConstructors();
|
public List getConstructors();
|
||||||
|
|
||||||
|
public void addFriend( ISymbol friend ) throws ParserSymbolTableException;
|
||||||
|
public ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException;
|
||||||
|
public List getFriends();
|
||||||
|
|
||||||
public interface IParentSymbol{
|
public interface IParentSymbol{
|
||||||
public void setParent( ISymbol parent );
|
public void setParent( ISymbol parent );
|
||||||
public ISymbol getParent();
|
public ISymbol getParent();
|
||||||
|
|
|
@ -54,6 +54,8 @@ public interface ISymbol extends Cloneable {
|
||||||
public void setTemplateInstance( TemplateInstance instance );
|
public void setTemplateInstance( TemplateInstance instance );
|
||||||
|
|
||||||
public int getDepth();
|
public int getDepth();
|
||||||
|
public boolean getIsInvisible();
|
||||||
|
public void setIsInvisible( boolean invisible );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param name
|
* @param name
|
||||||
|
|
|
@ -335,7 +335,7 @@ public class ParserSymbolTable {
|
||||||
name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name;
|
name = ( iterator != null && iterator.hasNext() ) ? (String) iterator.next() : data.name;
|
||||||
while( name != null ){
|
while( name != null ){
|
||||||
if( nameMatches( data, name ) ){
|
if( nameMatches( data, name ) ){
|
||||||
obj = parameters.get( data.name );
|
obj = parameters.get( name );
|
||||||
obj = collectSymbol( data, obj );
|
obj = collectSymbol( data, obj );
|
||||||
if( obj != null ){
|
if( obj != null ){
|
||||||
found.put( name, obj );
|
found.put( name, obj );
|
||||||
|
@ -393,7 +393,7 @@ public class ParserSymbolTable {
|
||||||
IContainerSymbol cls = null;
|
IContainerSymbol cls = null;
|
||||||
|
|
||||||
while( symbol != 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 )
|
if( symbol.isTemplateMember() && data.templateInstance != null )
|
||||||
foundSymbol = new TemplateInstance( symbol.getSymbolTable(), symbol, data.templateInstance.getArgumentMap() );
|
foundSymbol = new TemplateInstance( symbol.getSymbolTable(), symbol, data.templateInstance.getArgumentMap() );
|
||||||
else
|
else
|
||||||
|
@ -674,12 +674,17 @@ public class ParserSymbolTable {
|
||||||
TypeInfo.eType newType = newSymbol.getType();
|
TypeInfo.eType newType = newSymbol.getType();
|
||||||
|
|
||||||
//handle forward decls
|
//handle forward decls
|
||||||
if( origSymbol.getTypeInfo().isForwardDeclaration() &&
|
if( origSymbol.getTypeInfo().isForwardDeclaration() ){
|
||||||
origSymbol.getTypeSymbol() == newSymbol )
|
if( origSymbol.getTypeSymbol() == newSymbol )
|
||||||
{
|
return true;
|
||||||
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 ...
|
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*/) ) ){
|
( newType == TypeInfo.t_type || (newType.compareTo( TypeInfo.t_function ) >= 0 /*&& newType <= TypeInfo.typeMask*/) ) ){
|
||||||
|
|
||||||
|
@ -707,7 +712,8 @@ public class ParserSymbolTable {
|
||||||
|
|
||||||
Iterator iter = origList.iterator();
|
Iterator iter = origList.iterator();
|
||||||
ISymbol symbol = (ISymbol) iter.next();
|
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) )
|
if( !valid && (symbol instanceof IParameterizedSymbol) )
|
||||||
valid = isValidFunctionOverload( (IParameterizedSymbol)symbol, (IParameterizedSymbol)newSymbol );
|
valid = isValidFunctionOverload( (IParameterizedSymbol)symbol, (IParameterizedSymbol)newSymbol );
|
||||||
|
|
||||||
|
@ -2239,7 +2245,6 @@ public class ParserSymbolTable {
|
||||||
|
|
||||||
static protected class LookupData
|
static protected class LookupData
|
||||||
{
|
{
|
||||||
|
|
||||||
public Set ambiguities;
|
public Set ambiguities;
|
||||||
public String name;
|
public String name;
|
||||||
public Map usingDirectives;
|
public Map usingDirectives;
|
||||||
|
@ -2256,7 +2261,7 @@ public class ParserSymbolTable {
|
||||||
public boolean ignoreUsingDirectives = false;
|
public boolean ignoreUsingDirectives = false;
|
||||||
public boolean usingDirectivesOnly = false;
|
public boolean usingDirectivesOnly = false;
|
||||||
public boolean forUserDefinedConversion = false;
|
public boolean forUserDefinedConversion = false;
|
||||||
|
|
||||||
public Map foundItems = null;
|
public Map foundItems = null;
|
||||||
|
|
||||||
public ISymbol templateInstance = null;
|
public ISymbol templateInstance = null;
|
||||||
|
|
Loading…
Add table
Reference in a new issue