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

handle namespace that are split into pieces

This commit is contained in:
Andrew Niefer 2005-01-18 22:00:09 +00:00
parent d0606bd516
commit 9e5cafe0d9
8 changed files with 245 additions and 86 deletions

View file

@ -241,9 +241,9 @@ public class AST2BaseTest extends TestCase {
processNames = true;
}
public List nameList = new ArrayList();
public boolean processName( IASTName name ){
public int processName( IASTName name ){
nameList.add( name );
return true;
return PROCESS_CONTINUE;
}
public IASTName getName( int idx ){
if( idx < 0 || idx >= nameList.size() )

View file

@ -873,5 +873,31 @@ public class AST2CPPTests extends AST2BaseTest {
assertInstances( collector, A, 3 );
assertInstances( collector, x1, 1 );
}
public void testExtendedNamespaces() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append( "namespace A { \n" ); //$NON-NLS-1$
buffer.append( " int x; \n" ); //$NON-NLS-1$
buffer.append( "} \n" ); //$NON-NLS-1$
buffer.append( "int x; \n" ); //$NON-NLS-1$
buffer.append( "namespace A { \n" ); //$NON-NLS-1$
buffer.append( " void f() { x; } \n" ); //$NON-NLS-1$
buffer.append( "} \n" ); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector collector = new CPPNameCollector();
CPPVisitor.visitTranslationUnit( tu, collector );
assertEquals( collector.size(), 6 );
ICPPNamespace A = (ICPPNamespace) collector.getName(0).resolveBinding();
IVariable x1 = (IVariable) collector.getName( 1 ).resolveBinding();
IVariable x2 = (IVariable) collector.getName( 2 ).resolveBinding();
assertInstances( collector, A, 2 );
assertInstances( collector, x1, 2 );
assertInstances( collector, x2, 1 );
}
}

View file

@ -88,9 +88,9 @@ public class CompleteParser2Tests extends TestCase {
processNames = true;
}
public List nameList = new ArrayList();
public boolean processName( IASTName name ){
public int processName( IASTName name ){
nameList.add( name );
return true;
return PROCESS_CONTINUE;
}
public IASTName getName( int idx ){
if( idx < 0 || idx >= nameList.size() )

View file

@ -18,5 +18,4 @@ package org.eclipse.cdt.core.dom.ast.cpp;
* @author aniefer
*/
public interface ICPPNamespaceScope extends ICPPScope {
public ICPPASTUsingDirective [] getUsingDirectives();
}

View file

@ -14,7 +14,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
/**
* @author jcamelon
@ -83,16 +83,12 @@ public class CPPASTNamespaceDefinition extends CPPASTNode implements
private int currentIndex = 0;
private IASTDeclaration [] declarations = null;
private static final int DEFAULT_DECLARATIONS_LIST_SIZE = 4;
private ICPPNamespaceScope scope = null;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition#getScope()
*/
public IScope getScope() {
if(scope == null )
scope = new CPPNamespaceScope( this );
return scope;
return ((ICPPNamespace) name.resolveBinding()).getNamespaceScope();
}
}

View file

@ -13,12 +13,20 @@
*/
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.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
/**
* @author aniefer
@ -26,10 +34,66 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
public class CPPNamespace implements ICPPNamespace {
private static final char[] EMPTY_CHAR_ARRAY = { };
ICPPASTNamespaceDefinition [] namespaceDefinitions = null;
IASTName [] namespaceDefinitions = null;
ICPPNamespaceScope scope = null;
ICPPASTTranslationUnit tu = null;
public CPPNamespace( ICPPASTNamespaceDefinition nsDef ){
namespaceDefinitions = new ICPPASTNamespaceDefinition[] { nsDef };
public CPPNamespace( IASTName nsDef ){
findAllDefinitions( nsDef );
}
static private class NamespaceCollector extends CPPVisitor.CPPBaseVisitorAction {
private char [] name;
public List namespaces = Collections.EMPTY_LIST;
public int processResult = PROCESS_SKIP;
public NamespaceCollector( IASTName name ){
processNamespaces = true;
processDeclarations = true;
this.name = name.toCharArray();
}
public int processNamespace( 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;
}
public int processDeclaration( IASTDeclaration declaration ){
return PROCESS_SKIP;
}
}
private void findAllDefinitions( IASTName namespaceName ){
NamespaceCollector collector = new NamespaceCollector( namespaceName );
ICPPASTNamespaceDefinition nsDef = (ICPPASTNamespaceDefinition) namespaceName.getParent();
IASTNode node = nsDef.getParent();
if( node instanceof IASTTranslationUnit )
CPPVisitor.visitTranslationUnit( (IASTTranslationUnit) node, collector );
else if( node instanceof ICPPASTNamespaceDefinition ){
collector.processResult = CPPVisitor.CPPBaseVisitorAction.PROCESS_CONTINUE;
CPPVisitor.visitNamespaceDefinition( (ICPPASTNamespaceDefinition) node, collector );
}
int size = collector.namespaces.size();
namespaceDefinitions = new IASTName [ size ];
for( int i = 0; i < size; i++ ){
namespaceDefinitions[i] = (IASTName) collector.namespaces.get(i);
((CPPASTName)namespaceDefinitions[i]).setBinding( this );
}
}
public IASTName [] getNamespaceDefinitions() {
return namespaceDefinitions;
}
/**
@ -39,40 +103,31 @@ public class CPPNamespace implements ICPPNamespace {
tu = unit;
}
public void addDefinition( ICPPASTNamespaceDefinition nsDef ){
if( namespaceDefinitions == null )
return;
for( int i = 0; i < namespaceDefinitions.length; i++ ){
if( namespaceDefinitions[i] == null ){
namespaceDefinitions[i] = nsDef;
return;
}
}
ICPPASTNamespaceDefinition [] temp = new ICPPASTNamespaceDefinition[ namespaceDefinitions.length * 2 ];
System.arraycopy( namespaceDefinitions, 0, temp, 0, namespaceDefinitions.length );
temp[ namespaceDefinitions.length ] = nsDef;
namespaceDefinitions = temp;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace#getNamespaceScope()
*/
public ICPPNamespaceScope getNamespaceScope() {
return (ICPPNamespaceScope) ( tu != null ? tu.getScope() : namespaceDefinitions[0].getScope() );
if( scope == null ){
if( tu != null )
scope = (ICPPNamespaceScope) tu.getScope();
else
scope = new CPPNamespaceScope( namespaceDefinitions[0].getParent() );
}
return scope;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
public String getName() {
return tu != null ? null : namespaceDefinitions[0].getName().toString(); //$NON-NLS-1$
return tu != null ? null : namespaceDefinitions[0].toString(); //$NON-NLS-1$
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
public char[] getNameCharArray() {
return tu != null ? EMPTY_CHAR_ARRAY : namespaceDefinitions[0].getName().toCharArray();
return tu != null ? EMPTY_CHAR_ARRAY : namespaceDefinitions[0].toCharArray();
}
/* (non-Javadoc)

View file

@ -550,7 +550,10 @@ public class CPPSemantics {
IASTName possible = null;
IASTNode [] nodes = null;
IASTNode parent = scope.getPhysicalNode();
IASTName [] namespaceDefs = null;
int namespaceIdx = -1;
List found = null;
if( parent instanceof IASTCompoundStatement ){
@ -563,7 +566,12 @@ public class CPPSemantics {
ICPPASTCompositeTypeSpecifier comp = (ICPPASTCompositeTypeSpecifier) parent;
nodes = comp.getMembers();
} else if ( parent instanceof ICPPASTNamespaceDefinition ){
nodes = ((ICPPASTNamespaceDefinition)parent).getDeclarations();
//need binding because namespaces can be split
CPPNamespace namespace = (CPPNamespace) ((ICPPASTNamespaceDefinition)parent).getName().resolveBinding();
namespaceDefs = namespace.getNamespaceDefinitions();
nodes = ((ICPPASTNamespaceDefinition)namespaceDefs[0].getParent()).getDeclarations();
namespaceIdx = -1;
}
int idx = -1;
@ -595,7 +603,16 @@ public class CPPSemantics {
if( idx > -1 && ++idx < nodes.length ){
item = nodes[idx];
} else {
item = null;
item = null;
while( namespaceIdx > -1 && namespaceDefs.length > ++namespaceIdx ){
nodes = ((ICPPASTNamespaceDefinition)namespaceDefs[0].getParent()).getDeclarations();
if( nodes.length > 0 ){
idx = 0;
item = nodes[0];
break;
}
}
}
}
return found;

View file

@ -249,10 +249,9 @@ public class CPPVisitor {
ICPPScope scope = (ICPPScope) getContainingScope( namespaceDef );
CPPNamespace binding = (CPPNamespace) scope.getBinding( namespaceDef.getName() );
if( binding == null ){
binding = new CPPNamespace( namespaceDef );
binding = new CPPNamespace( namespaceDef.getName() );
scope.addBinding( binding );
} else
binding.addDefinition( namespaceDef );
}
return binding;
} else if( declaration instanceof ICPPASTUsingDirective ){
return CPPSemantics.resolveBinding( ((ICPPASTUsingDirective) declaration).getQualifiedName() );
@ -519,22 +518,28 @@ public class CPPVisitor {
public boolean processStatements = false;
public boolean processTypeIds = false;
public boolean processEnumerators = false;
public boolean processBaseSpecifiers;
public boolean processBaseSpecifiers = false;
public boolean processNamespaces = false;
/**
* @return true to continue visiting, return false to stop
*/
public boolean processName( IASTName name ) { return true; }
public boolean processDeclaration( IASTDeclaration declaration ){ return true; }
public boolean processInitializer( IASTInitializer initializer ){ return true; }
public boolean processParameterDeclaration( IASTParameterDeclaration parameterDeclaration ) { return true; }
public boolean processDeclarator( IASTDeclarator declarator ) { return true; }
public boolean processDeclSpecifier( IASTDeclSpecifier declSpec ){return true; }
public boolean processExpression( IASTExpression expression ) { return true; }
public boolean processStatement( IASTStatement statement ) { return true; }
public boolean processTypeId( IASTTypeId typeId ) { return true; }
public boolean processEnumerator( IASTEnumerator enumerator ) { return true; }
public boolean processBaseSpecifier(ICPPASTBaseSpecifier specifier) { return true; }
public final static int PROCESS_SKIP = 1;
public final static int PROCESS_ABORT = 2;
public final static int PROCESS_CONTINUE = 3;
public int processName( IASTName name ) { return PROCESS_CONTINUE; }
public int processDeclaration( IASTDeclaration declaration ){ return PROCESS_CONTINUE; }
public int processInitializer( IASTInitializer initializer ){ return PROCESS_CONTINUE; }
public int processParameterDeclaration( IASTParameterDeclaration parameterDeclaration ) { return PROCESS_CONTINUE; }
public int processDeclarator( IASTDeclarator declarator ) { return PROCESS_CONTINUE; }
public int processDeclSpecifier( IASTDeclSpecifier declSpec ){return PROCESS_CONTINUE; }
public int processExpression( IASTExpression expression ) { return PROCESS_CONTINUE; }
public int processStatement( IASTStatement statement ) { return PROCESS_CONTINUE; }
public int processTypeId( IASTTypeId typeId ) { return PROCESS_CONTINUE; }
public int processEnumerator( IASTEnumerator enumerator ) { return PROCESS_CONTINUE; }
public int processBaseSpecifier(ICPPASTBaseSpecifier specifier) { return PROCESS_CONTINUE; }
public int processNamespace( ICPPASTNamespaceDefinition namespace) { return PROCESS_CONTINUE; }
}
public static class CollectProblemsAction extends CPPBaseVisitorAction {
@ -585,41 +590,40 @@ public class CPPVisitor {
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processDeclaration(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
*/
public boolean processDeclaration(IASTDeclaration declaration) {
public int processDeclaration(IASTDeclaration declaration) {
if ( declaration instanceof IASTProblemHolder )
addProblem(((IASTProblemHolder)declaration).getProblem());
return true;
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processExpression(org.eclipse.cdt.core.dom.ast.IASTExpression)
*/
public boolean processExpression(IASTExpression expression) {
public int processExpression(IASTExpression expression) {
if ( expression instanceof IASTProblemHolder )
addProblem(((IASTProblemHolder)expression).getProblem());
return true;
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processStatement(org.eclipse.cdt.core.dom.ast.IASTStatement)
*/
public boolean processStatement(IASTStatement statement) {
public int processStatement(IASTStatement statement) {
if ( statement instanceof IASTProblemHolder )
addProblem(((IASTProblemHolder)statement).getProblem());
return true;
return PROCESS_CONTINUE;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction#processTypeId(org.eclipse.cdt.core.dom.ast.IASTTypeId)
*/
public boolean processTypeId(IASTTypeId typeId) {
public int processTypeId(IASTTypeId typeId) {
if ( typeId instanceof IASTProblemHolder )
addProblem(((IASTProblemHolder)typeId).getProblem());
return true;
return PROCESS_CONTINUE;
}
}
@ -630,14 +634,38 @@ public class CPPVisitor {
}
}
public static boolean visitNamespaceDefinition( ICPPASTNamespaceDefinition namespace, CPPBaseVisitorAction action ){
if( action.processNamespaces ){
switch( action.processNamespace( namespace ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( !visitName( namespace.getName(), action ) ) return false;
IASTDeclaration [] decls = namespace.getDeclarations();
for( int i = 0; i < decls.length; i++ ){
if( !visitDeclaration( decls[i], action ) ) return false;
}
return true;
}
/**
* @param declaration
* @param action
* @return
*/
public static boolean visitDeclaration(IASTDeclaration declaration, CPPBaseVisitorAction action) {
if( action.processDeclarations )
if( !action.processDeclaration( declaration ) ) return false;
if( declaration instanceof ICPPASTNamespaceDefinition )
return visitNamespaceDefinition( (ICPPASTNamespaceDefinition) declaration, action );
if( action.processDeclarations ) {
switch( action.processDeclaration( declaration ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( declaration instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simple = (IASTSimpleDeclaration) declaration;
@ -655,13 +683,6 @@ public class CPPVisitor {
if( !visitName( ((ICPPASTUsingDeclaration)declaration).getName(), action ) ) return false;
} else if( declaration instanceof ICPPASTUsingDirective ){
if( !visitName( ((ICPPASTUsingDirective)declaration).getQualifiedName(), action ) ) return false;
} else if( declaration instanceof ICPPASTNamespaceDefinition ){
ICPPASTNamespaceDefinition namespace = (ICPPASTNamespaceDefinition) declaration;
if( !visitName( namespace.getName(), action ) ) return false;
IASTDeclaration [] decls = namespace.getDeclarations();
for( int i = 0; i < decls.length; i++ ){
if( !visitDeclaration( decls[i], action ) ) return false;
}
} else if( declaration instanceof ICPPASTNamespaceAlias ){
ICPPASTNamespaceAlias alias = (ICPPASTNamespaceAlias) declaration;
if( !visitName( alias.getQualifiedName(), action ) ) return false;
@ -690,8 +711,13 @@ public class CPPVisitor {
* @return
*/
public static boolean visitName(IASTName name, CPPBaseVisitorAction action) {
if( action.processNames )
if( !action.processName( name ) ) return false;
if( action.processNames ){
switch( action.processName( name ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( name instanceof ICPPASTQualifiedName ){
IASTName [] names = ((ICPPASTQualifiedName)name).getNames();
@ -708,8 +734,13 @@ public class CPPVisitor {
* @return
*/
public static boolean visitDeclSpecifier(IASTDeclSpecifier declSpecifier, CPPBaseVisitorAction action) {
if( action.processDeclSpecifiers )
if( !action.processDeclSpecifier( declSpecifier ) ) return false;
if( action.processDeclSpecifiers ){
switch( action.processDeclSpecifier( declSpecifier ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( declSpecifier instanceof ICPPASTCompositeTypeSpecifier ){
ICPPASTCompositeTypeSpecifier composite = (ICPPASTCompositeTypeSpecifier) declSpecifier;
@ -747,8 +778,13 @@ public class CPPVisitor {
* @return
*/
public static boolean visitDeclarator(IASTDeclarator declarator, CPPBaseVisitorAction action) {
if( action.processDeclarators )
if( !action.processDeclarator( declarator ) ) return false;
if( action.processDeclarators ){
switch( action.processDeclarator( declarator ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( declarator.getPropertyInParent() != IASTTypeId.ABSTRACT_DECLARATOR ){
if( !visitName( declarator.getName(), action ) ) return false;
@ -802,8 +838,13 @@ public class CPPVisitor {
* @return
*/
public static boolean visitStatement(IASTStatement statement, CPPBaseVisitorAction action) {
if( action.processStatements )
if( !action.processStatement( statement ) ) return false;
if( action.processStatements ){
switch( action.processStatement( statement ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( statement instanceof IASTCompoundStatement ){
IASTStatement [] list = ((IASTCompoundStatement) statement).getStatements();
@ -865,8 +906,13 @@ public class CPPVisitor {
* @return
*/
public static boolean visitExpression(IASTExpression expression, CPPBaseVisitorAction action) {
if( action.processExpressions )
if( !action.processExpression( expression ) ) return false;
if( action.processExpressions ){
switch( action.processExpression( expression ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( expression instanceof IASTArraySubscriptExpression ){
if( !visitExpression( ((IASTArraySubscriptExpression)expression).getArrayExpression(), action ) ) return false;
@ -930,8 +976,13 @@ public class CPPVisitor {
* @return
*/
public static boolean visitTypeId(IASTTypeId typeId, CPPBaseVisitorAction action) {
if( action.processTypeIds )
if( !action.processTypeId( typeId ) ) return false;
if( action.processTypeIds ){
switch( action.processTypeId( typeId ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( !visitDeclSpecifier( typeId.getDeclSpecifier(), action ) ) return false;
if( !visitDeclarator( typeId.getAbstractDeclarator(), action ) ) return false;
return true;
@ -943,8 +994,13 @@ public class CPPVisitor {
* @return
*/
public static boolean visitInitializer(IASTInitializer initializer, CPPBaseVisitorAction action) {
if( action.processInitializers )
if( !action.processInitializer( initializer ) ) return false;
if( action.processInitializers ){
switch( action.processInitializer( initializer ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( initializer instanceof IASTInitializerExpression ){
if( !visitExpression( ((IASTInitializerExpression) initializer).getExpression(), action ) ) return false;
@ -965,8 +1021,13 @@ public class CPPVisitor {
* @return
*/
public static boolean visitEnumerator(IASTEnumerator enumerator, CPPBaseVisitorAction action) {
if( action.processEnumerators )
if( !action.processEnumerator( enumerator ) ) return false;
if( action.processEnumerators ){
switch( action.processEnumerator( enumerator ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( !visitName( enumerator.getName(), action ) ) return false;
if( enumerator.getValue() != null )
@ -980,8 +1041,13 @@ public class CPPVisitor {
* @return
*/
public static boolean visitBaseSpecifier(ICPPASTBaseSpecifier specifier, CPPBaseVisitorAction action) {
if( action.processBaseSpecifiers )
if( !action.processBaseSpecifier( specifier ) ) return false;
if( action.processBaseSpecifiers ){
switch( action.processBaseSpecifier( specifier ) ){
case CPPBaseVisitorAction.PROCESS_ABORT : return false;
case CPPBaseVisitorAction.PROCESS_SKIP : return true;
default : break;
}
}
if( !visitName( specifier.getName(), action ) ) return false;
return true;