1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

fix bug 98818: distributed namespaces

This commit is contained in:
Andrew Niefer 2005-06-09 19:18:53 +00:00
parent be3075f51c
commit 46d3f69877
3 changed files with 71 additions and 42 deletions

View file

@ -4682,4 +4682,40 @@ public class AST2CPPTests extends AST2BaseTest {
assertSame( col.getName(2).resolveBinding(), col.getName(5).resolveBinding() );
}
public void testBug98818() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("namespace n { \n");
buffer.append(" namespace m { \n");
buffer.append(" class A; \n");
buffer.append(" } \n");
buffer.append("} \n");
buffer.append("namespace n { \n");
buffer.append(" namespace m { \n");
buffer.append(" class A { void f(); }; \n");
buffer.append(" } \n");
buffer.append("} \n");
buffer.append("namespace n { \n");
buffer.append(" namespace m { \n");
buffer.append(" void A::f(){} \n");
buffer.append(" } \n");
buffer.append("} \n");
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
tu.accept(col);
ICPPNamespace n = (ICPPNamespace) col.getName(0).resolveBinding();
ICPPNamespace m = (ICPPNamespace) col.getName(1).resolveBinding();
assertSame( n, col.getName(3).resolveBinding() );
assertSame( n, col.getName(7).resolveBinding() );
assertSame( m, col.getName(4).resolveBinding() );
assertSame( m, col.getName(8).resolveBinding() );
ICPPClassType A = (ICPPClassType) col.getName(2).resolveBinding();
assertSame( A, col.getName(5).resolveBinding() );
ICPPMethod f = (ICPPMethod) col.getName(9).resolveBinding();
assertSame( f, col.getName(11).resolveBinding() );
}
}

View file

@ -13,11 +13,6 @@
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
@ -65,7 +60,7 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
ICPPNamespaceScope scope = null;
ICPPASTTranslationUnit tu = null;
public CPPNamespace( IASTName nsDef ){
public CPPNamespace( ICPPASTNamespaceDefinition nsDef ){
findAllDefinitions( nsDef );
}
@ -84,28 +79,34 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
}
static private class NamespaceCollector extends CPPASTVisitor {
private char [] name;
public List namespaces = Collections.EMPTY_LIST;
public int processResult = PROCESS_SKIP;
private ICPPASTNamespaceDefinition namespaceDef = null;
private IASTName [] namespaces = null;
public NamespaceCollector( IASTName name ){
public NamespaceCollector( ICPPASTNamespaceDefinition ns ){
shouldVisitNamespaces = true;
shouldVisitDeclarations = true;
this.name = name.toCharArray();
this.namespaceDef = ns;
}
public int visit( ICPPASTNamespaceDefinition namespace) {
if( CharArrayUtils.equals( namespace.getName().toCharArray(), name ) ){
if( namespaces == Collections.EMPTY_LIST )
namespaces = new ArrayList();
namespaces.add( namespace.getName() );
}
if( processResult == PROCESS_CONTINUE ){
processResult = PROCESS_SKIP;
return PROCESS_CONTINUE;
}
return processResult;
ICPPASTNamespaceDefinition orig = namespaceDef, candidate = namespace;
while( candidate != null ){
if( !CharArrayUtils.equals( orig.getName().toCharArray(), candidate.getName().toCharArray() ) )
return PROCESS_CONTINUE;
if( orig.getParent() instanceof ICPPASTNamespaceDefinition ){
if( !(candidate.getParent() instanceof ICPPASTNamespaceDefinition ) )
return PROCESS_CONTINUE;
orig = (ICPPASTNamespaceDefinition) orig.getParent();
candidate = (ICPPASTNamespaceDefinition) candidate.getParent();
} else if( candidate.getParent() instanceof ICPPASTNamespaceDefinition ){
return PROCESS_CONTINUE;
} else {
break;
}
}
namespaces = (IASTName[]) ArrayUtil.append( IASTName.class, namespaces, namespace.getName() );
return PROCESS_SKIP;
}
public int visit( IASTDeclaration declaration ){
@ -113,6 +114,10 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
return PROCESS_CONTINUE;
return PROCESS_SKIP;
}
public IASTName [] getNamespaces() {
return (IASTName[]) ArrayUtil.trim( IASTName.class, namespaces );
}
}
static private class NamespaceMemberCollector extends CPPASTVisitor {
@ -172,24 +177,12 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
return PROCESS_CONTINUE;
}
}
private void findAllDefinitions( IASTName namespaceName ){
NamespaceCollector collector = new NamespaceCollector( namespaceName );
ICPPASTNamespaceDefinition nsDef = (ICPPASTNamespaceDefinition) namespaceName.getParent();
IASTNode node = nsDef.getParent();
while( node instanceof ICPPASTLinkageSpecification )
node = node.getParent();
if( node instanceof ICPPASTNamespaceDefinition ){
collector.processResult = ASTVisitor.PROCESS_CONTINUE;
}
node.accept( collector );
int size = collector.namespaces.size();
namespaceDefinitions = new IASTName [ size ];
for( int i = 0; i < size; i++ ){
namespaceDefinitions[i] = (IASTName) collector.namespaces.get(i);
private void findAllDefinitions( ICPPASTNamespaceDefinition namespaceDef ){
NamespaceCollector collector = new NamespaceCollector( namespaceDef );
namespaceDef.getTranslationUnit().accept( collector );
namespaceDefinitions = collector.getNamespaces();
for( int i = 0; i < namespaceDefinitions.length; i++ ){
namespaceDefinitions[i].setBinding( this );
}
}

View file

@ -409,8 +409,8 @@ public class CPPVisitor {
IBinding binding;
try {
binding = scope.getBinding( namespaceDef.getName(), false );
if( binding == null ){
binding = new CPPNamespace( namespaceDef.getName() );
if( binding == null || binding instanceof IProblemBinding ){
binding = new CPPNamespace( namespaceDef );
scope.addName( namespaceDef.getName() );
}
} catch ( DOMException e ) {