1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

ICPPClassType.getNestedClasses()

ICPPNamespace.getMemberBindings()

for bug 92425
This commit is contained in:
Andrew Niefer 2005-06-03 20:03:36 +00:00
parent a31d84767b
commit 072e9d936e
13 changed files with 258 additions and 8 deletions

View file

@ -4595,4 +4595,45 @@ public class AST2CPPTests extends AST2BaseTest {
assertSame( foo, col.getName(14).resolveBinding() );
}
public void testBug92425() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("class A; \n");
buffer.append("class A { \n");
buffer.append(" class B; \n");
buffer.append(" class C {}; \n");
buffer.append("}; \n");
buffer.append("class A::B{}; \n");
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
tu.accept(col);
ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding();
ICPPClassType B = (ICPPClassType) col.getName(2).resolveBinding();
ICPPClassType C = (ICPPClassType) col.getName(3).resolveBinding();
ICPPClassType [] classes = A.getNestedClasses();
assertEquals( classes.length, 2 );
assertSame( classes[0], B );
assertSame( classes[1], C );
}
public void testBug92425_2() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("namespace A { \n"); //$NON-NLS-1$
buffer.append(" struct F {} f; \n"); //$NON-NLS-1$
buffer.append(" void f( int a) {} \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
tu.accept(col);
ICPPNamespace A = (ICPPNamespace) col.getName(0).resolveBinding();
IBinding [] bindings = A.getMemberBindings();
assertEquals( bindings.length, 3 );
assertSame( bindings[0], col.getName(1).resolveBinding() );
assertSame( bindings[1], col.getName(2).resolveBinding() );
assertSame( bindings[2], col.getName(3).resolveBinding() );
}
}

View file

@ -21,7 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IField;
* @author Doug Schaefer
*/
public interface ICPPClassType extends ICompositeType, ICPPBinding {
public static final ICPPClassType [] EMPTY_CLASS_ARRAY = new ICPPClassType[0];
public static final int k_class = ICPPASTCompositeTypeSpecifier.k_class;
/**
@ -101,4 +101,11 @@ public interface ICPPClassType extends ICompositeType, ICPPBinding {
* @throws DOMException
*/
public IBinding[] getFriends() throws DOMException;
/**
* return an array of nested classes/structures
* @return
* @throws DOMException
*/
public ICPPClassType [] getNestedClasses() throws DOMException;
}

View file

@ -14,6 +14,7 @@
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
/**
* This interface represents a C++ namespace
@ -28,4 +29,11 @@ public interface ICPPNamespace extends ICPPBinding {
* @throws DOMException
*/
public ICPPNamespaceScope getNamespaceScope() throws DOMException;
/**
* get an array of the all the bindings declared in this namespace.
* @return
* @throws DOMException
*/
public IBinding [] getMemberBindings() throws DOMException;
}

View file

@ -175,4 +175,8 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP
return false;
}
public ICPPClassType[] getNestedClasses() throws DOMException {
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
}

View file

@ -234,6 +234,8 @@ public class CPPClassInstanceScope implements ICPPClassScope {
bindings.remove( name, 0, name.length );
}
if( instanceMap != null && instanceMap.containsKey( binding ) )
instanceMap.remove( binding );
isFullyCached = false;
}
@ -261,4 +263,10 @@ public class CPPClassInstanceScope implements ICPPClassScope {
bindings.put( c, binding );
}
}
public IBinding getInstance( IBinding binding ){
if( instanceMap != null && instanceMap.containsKey( binding ) )
return (IBinding) instanceMap.get( binding );
return null;
}
}

View file

@ -178,4 +178,8 @@ public class CPPClassSpecialization extends CPPSpecialization implements
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
public ICPPClassType[] getNestedClasses() throws DOMException {
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
}

View file

@ -45,6 +45,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType.CPPClassTypeProblem;
/**
* @author aniefer
@ -348,4 +349,36 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
public ICPPDelegate createDelegate( IASTName name ) {
return new CPPClassTemplateDelegate( name, this );
}
public ICPPClassType[] getNestedClasses() {
if( definition == null ){
checkForDefinition();
if( definition == null ){
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null;
return new ICPPClassType[] { new CPPClassTypeProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) };
}
}
IBinding binding = null;
ICPPClassType [] result = null;
IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers();
for ( int i = 0; i < decls.length; i++ ) {
IASTDeclaration decl = decls[i];
while( decl instanceof ICPPASTTemplateDeclaration )
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
if( decl instanceof IASTSimpleDeclaration ){
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier();
if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){
binding = ((ICPPASTCompositeTypeSpecifier)declSpec).getName().resolveBinding();
} else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier &&
((IASTSimpleDeclaration)decl).getDeclarators().length == 0 )
{
binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding();
}
if( binding instanceof ICPPClassType )
result = (ICPPClassType[])ArrayUtil.append( ICPPClassType.class, result, binding );
}
}
return (ICPPClassType[]) ArrayUtil.trim( ICPPClassType.class, result );
}
}

View file

@ -114,6 +114,9 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
public boolean isSameType( IType type ) {
return ((ICPPClassType)getBinding()).isSameType( type );
}
public ICPPClassType[] getNestedClasses() throws DOMException {
return ((ICPPClassType)getBinding()).getNestedClasses();
}
}
public static class CPPClassTypeProblem extends ProblemBinding implements ICPPClassType{
public CPPClassTypeProblem( IASTNode node, int id, char[] arg ) {
@ -168,6 +171,9 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
public boolean isGloballyQualified() throws DOMException {
throw new DOMException( this );
}
public ICPPClassType[] getNestedClasses() throws DOMException {
throw new DOMException( this );
}
}
private IASTName definition;
@ -606,22 +612,25 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers();
for ( int i = 0; i < decls.length; i++ ) {
if( decls[i] instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decls[i]).getDeclarators();
IASTDeclaration decl = decls[i];
while( decl instanceof ICPPASTTemplateDeclaration )
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
if( decl instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators();
for ( int j = 0; j < dtors.length; j++ ) {
binding = dtors[j].getName().resolveBinding();
if( binding instanceof ICPPMethod)
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding );
}
} else if( decls[i] instanceof IASTFunctionDefinition ){
IASTDeclarator dtor = ((IASTFunctionDefinition)decls[i]).getDeclarator();
} else if( decl instanceof IASTFunctionDefinition ){
IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator();
dtor = CPPVisitor.getMostNestedDeclarator( dtor );
binding = dtor.getName().resolveBinding();
if( binding instanceof ICPPMethod ){
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding );
}
} else if( decls[i] instanceof ICPPASTUsingDeclaration ){
IASTName n = ((ICPPASTUsingDeclaration)decls[i]).getName();
} else if( decl instanceof ICPPASTUsingDeclaration ){
IASTName n = ((ICPPASTUsingDeclaration)decl).getName();
binding = n.resolveBinding();
if( binding instanceof ICPPUsingDeclaration ){
IBinding [] bs = ((ICPPUsingDeclaration)binding).getDelegates();
@ -768,4 +777,36 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
return ((ITypedef)type).isSameType( this );
return false;
}
public ICPPClassType[] getNestedClasses() {
if( definition == null ){
checkForDefinition();
if( definition == null ){
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null;
return new ICPPClassType[] { new CPPClassTypeProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) };
}
}
IBinding binding = null;
ICPPClassType [] result = null;
IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers();
for ( int i = 0; i < decls.length; i++ ) {
IASTDeclaration decl = decls[i];
while( decl instanceof ICPPASTTemplateDeclaration )
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
if( decls[i] instanceof IASTSimpleDeclaration ){
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decls[i]).getDeclSpecifier();
if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){
binding = ((ICPPASTCompositeTypeSpecifier)declSpec).getName().resolveBinding();
} else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier &&
((IASTSimpleDeclaration)decls[i]).getDeclarators().length == 0 )
{
binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding();
}
if( binding instanceof ICPPClassType )
result = (ICPPClassType[])ArrayUtil.append( ICPPClassType.class, result, binding );
}
}
return (ICPPClassType[]) ArrayUtil.trim( ICPPClassType.class, result );
}
}

View file

@ -176,4 +176,9 @@ public class CPPDeferredClassInstance extends CPPInstance implements ICPPClassTy
}
return false;
}
public ICPPClassType[] getNestedClasses() throws DOMException {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -19,19 +19,29 @@ 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;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
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.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
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.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
/**
@ -45,6 +55,9 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
public ICPPNamespaceScope getNamespaceScope() throws DOMException {
return ((ICPPNamespace)getBinding()).getNamespaceScope();
}
public IBinding[] getMemberBindings() throws DOMException {
return ((ICPPNamespace)getBinding()).getMemberBindings();
}
}
private static final char[] EMPTY_CHAR_ARRAY = { };
@ -102,6 +115,63 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
}
}
static private class NamespaceMemberCollector extends CPPASTVisitor {
public ObjectSet members = new ObjectSet(8);
public NamespaceMemberCollector(){
shouldVisitNamespaces = true;
shouldVisitDeclarators = true;
shouldVisitDeclSpecifiers = true;
shouldVisitDeclarations = true;
}
public int visit(IASTDeclarator declarator) {
while( declarator.getNestedDeclarator() != null )
declarator = declarator.getNestedDeclarator();
IBinding binding = declarator.getName().resolveBinding();
if( binding != null && !(binding instanceof IProblemBinding))
members.put( binding );
return PROCESS_SKIP;
}
public int visit(IASTDeclSpecifier declSpec) {
if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){
IBinding binding = ((ICPPASTCompositeTypeSpecifier)declSpec).getName().resolveBinding();
if( binding != null && !(binding instanceof IProblemBinding) )
members.put( binding );
return PROCESS_SKIP;
} else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier ) {
IASTNode parent = declSpec.getParent();
if( parent instanceof IASTSimpleDeclaration ){
if( ((IASTSimpleDeclaration)parent).getDeclarators().length > 0 )
return PROCESS_SKIP;
IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding();
if( binding != null && !(binding instanceof IProblemBinding) )
members.put( binding );
return PROCESS_SKIP;
}
}
return PROCESS_SKIP;
}
public int visit(ICPPASTNamespaceDefinition namespace) {
IBinding binding = namespace.getName().resolveBinding();
if( binding != null && !(binding instanceof IProblemBinding) )
members.put( binding );
return PROCESS_SKIP;
}
public int visit(IASTDeclaration declaration) {
if( declaration instanceof ICPPASTUsingDeclaration ){
IBinding binding =((ICPPASTUsingDeclaration)declaration).getName().resolveBinding();
if( binding != null && !(binding instanceof IProblemBinding) )
members.put( binding );
return PROCESS_SKIP;
} else if( declaration instanceof IASTFunctionDefinition ){
return visit( ((IASTFunctionDefinition)declaration).getDeclarator() );
}
return PROCESS_CONTINUE;
}
}
private void findAllDefinitions( IASTName namespaceName ){
NamespaceCollector collector = new NamespaceCollector( namespaceName );
ICPPASTNamespaceDefinition nsDef = (ICPPASTNamespaceDefinition) namespaceName.getParent();
@ -258,4 +328,21 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
}
}
public IBinding[] getMemberBindings() {
if( namespaceDefinitions != null ){
NamespaceMemberCollector collector = new NamespaceMemberCollector();
for (int i = 0; i < namespaceDefinitions.length; i++) {
IASTNode parent = namespaceDefinitions[i].getParent();
if( parent instanceof ICPPASTNamespaceDefinition ){
IASTDeclaration [] decls = ((ICPPASTNamespaceDefinition)parent).getDeclarations();
for (int j = 0; j < decls.length; j++) {
decls[j].accept( collector );
}
}
}
return (IBinding[]) ArrayUtil.trim( IBinding.class, collector.members.keyArray(), true );
}
return IBinding.EMPTY_BINDING_ARRAY;
}
}

View file

@ -146,4 +146,8 @@ public class CPPNamespaceAlias implements ICPPNamespaceAlias, ICPPInternalBindin
public void removeDeclaration(IASTNode node) {
}
public IBinding[] getMemberBindings() throws DOMException {
return namespace.getMemberBindings();
}
}

View file

@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
@ -34,7 +35,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.ObjectMap;
@ -308,4 +308,8 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
// TODO Auto-generated method stub
return null;
}
public ICPPClassType[] getNestedClasses() {
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
}

View file

@ -130,4 +130,8 @@ public class CPPUnknownClass extends CPPUnknownBinding implements ICPPClassType
return type == this;
}
public ICPPClassType[] getNestedClasses() {
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
}