mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-31 12:55:40 +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() );
|
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;
|
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.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
|
@ -65,7 +60,7 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
|
||||||
ICPPNamespaceScope scope = null;
|
ICPPNamespaceScope scope = null;
|
||||||
|
|
||||||
ICPPASTTranslationUnit tu = null;
|
ICPPASTTranslationUnit tu = null;
|
||||||
public CPPNamespace( IASTName nsDef ){
|
public CPPNamespace( ICPPASTNamespaceDefinition nsDef ){
|
||||||
findAllDefinitions( nsDef );
|
findAllDefinitions( nsDef );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,28 +79,34 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
|
||||||
}
|
}
|
||||||
|
|
||||||
static private class NamespaceCollector extends CPPASTVisitor {
|
static private class NamespaceCollector extends CPPASTVisitor {
|
||||||
private char [] name;
|
private ICPPASTNamespaceDefinition namespaceDef = null;
|
||||||
public List namespaces = Collections.EMPTY_LIST;
|
private IASTName [] namespaces = null;
|
||||||
public int processResult = PROCESS_SKIP;
|
|
||||||
|
|
||||||
public NamespaceCollector( IASTName name ){
|
public NamespaceCollector( ICPPASTNamespaceDefinition ns ){
|
||||||
shouldVisitNamespaces = true;
|
shouldVisitNamespaces = true;
|
||||||
shouldVisitDeclarations = true;
|
shouldVisitDeclarations = true;
|
||||||
this.name = name.toCharArray();
|
this.namespaceDef = ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int visit( ICPPASTNamespaceDefinition namespace) {
|
public int visit( ICPPASTNamespaceDefinition namespace) {
|
||||||
if( CharArrayUtils.equals( namespace.getName().toCharArray(), name ) ){
|
ICPPASTNamespaceDefinition orig = namespaceDef, candidate = namespace;
|
||||||
if( namespaces == Collections.EMPTY_LIST )
|
while( candidate != null ){
|
||||||
namespaces = new ArrayList();
|
if( !CharArrayUtils.equals( orig.getName().toCharArray(), candidate.getName().toCharArray() ) )
|
||||||
namespaces.add( namespace.getName() );
|
return PROCESS_CONTINUE;
|
||||||
}
|
if( orig.getParent() instanceof ICPPASTNamespaceDefinition ){
|
||||||
if( processResult == PROCESS_CONTINUE ){
|
if( !(candidate.getParent() instanceof ICPPASTNamespaceDefinition ) )
|
||||||
processResult = PROCESS_SKIP;
|
return PROCESS_CONTINUE;
|
||||||
return PROCESS_CONTINUE;
|
orig = (ICPPASTNamespaceDefinition) orig.getParent();
|
||||||
}
|
candidate = (ICPPASTNamespaceDefinition) candidate.getParent();
|
||||||
|
} else if( candidate.getParent() instanceof ICPPASTNamespaceDefinition ){
|
||||||
return processResult;
|
return PROCESS_CONTINUE;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespaces = (IASTName[]) ArrayUtil.append( IASTName.class, namespaces, namespace.getName() );
|
||||||
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int visit( IASTDeclaration declaration ){
|
public int visit( IASTDeclaration declaration ){
|
||||||
|
@ -113,6 +114,10 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
|
||||||
return PROCESS_CONTINUE;
|
return PROCESS_CONTINUE;
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IASTName [] getNamespaces() {
|
||||||
|
return (IASTName[]) ArrayUtil.trim( IASTName.class, namespaces );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static private class NamespaceMemberCollector extends CPPASTVisitor {
|
static private class NamespaceMemberCollector extends CPPASTVisitor {
|
||||||
|
@ -172,24 +177,12 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
|
||||||
return PROCESS_CONTINUE;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void findAllDefinitions( IASTName namespaceName ){
|
private void findAllDefinitions( ICPPASTNamespaceDefinition namespaceDef ){
|
||||||
NamespaceCollector collector = new NamespaceCollector( namespaceName );
|
NamespaceCollector collector = new NamespaceCollector( namespaceDef );
|
||||||
ICPPASTNamespaceDefinition nsDef = (ICPPASTNamespaceDefinition) namespaceName.getParent();
|
namespaceDef.getTranslationUnit().accept( collector );
|
||||||
IASTNode node = nsDef.getParent();
|
|
||||||
|
namespaceDefinitions = collector.getNamespaces();
|
||||||
while( node instanceof ICPPASTLinkageSpecification )
|
for( int i = 0; i < namespaceDefinitions.length; i++ ){
|
||||||
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);
|
|
||||||
namespaceDefinitions[i].setBinding( this );
|
namespaceDefinitions[i].setBinding( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,8 +409,8 @@ public class CPPVisitor {
|
||||||
IBinding binding;
|
IBinding binding;
|
||||||
try {
|
try {
|
||||||
binding = scope.getBinding( namespaceDef.getName(), false );
|
binding = scope.getBinding( namespaceDef.getName(), false );
|
||||||
if( binding == null ){
|
if( binding == null || binding instanceof IProblemBinding ){
|
||||||
binding = new CPPNamespace( namespaceDef.getName() );
|
binding = new CPPNamespace( namespaceDef );
|
||||||
scope.addName( namespaceDef.getName() );
|
scope.addName( namespaceDef.getName() );
|
||||||
}
|
}
|
||||||
} catch ( DOMException e ) {
|
} catch ( DOMException e ) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue