From 46d3f69877089f1b8517f50d4c878c4923f40861 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Thu, 9 Jun 2005 19:18:53 +0000 Subject: [PATCH] fix bug 98818: distributed namespaces --- .../core/parser/tests/ast2/AST2CPPTests.java | 36 +++++++++ .../core/dom/parser/cpp/CPPNamespace.java | 73 +++++++++---------- .../core/dom/parser/cpp/CPPVisitor.java | 4 +- 3 files changed, 71 insertions(+), 42 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index d20a3de41e5..7e7e8759e37 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -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() ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java index f6151d7adc0..ca2f2ae0b16 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java @@ -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 ); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 085c8f5a575..611dd709994 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -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 ) {