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:
parent
be3075f51c
commit
46d3f69877
3 changed files with 71 additions and 42 deletions
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
Loading…
Add table
Reference in a new issue