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

Type Hierarchy: support for typedefs

This commit is contained in:
Markus Schorn 2007-01-23 15:14:35 +00:00
parent 57102e1bd4
commit 98261e8d92
8 changed files with 160 additions and 80 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -15,10 +15,12 @@ import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.c.ICCompositeTypeScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
@ -61,6 +63,9 @@ public class CElementHandleFactory {
else if (binding instanceof IVariable) {
element= new VariableHandle(parentElement, (IVariable) binding);
}
else if (binding instanceof IEnumeration) {
element= new EnumerationHandle(parentElement, (IEnumeration) binding);
}
else if (binding instanceof IEnumerator) {
element= new EnumeratorHandle(parentElement, (IEnumerator) binding);
}
@ -69,7 +74,10 @@ public class CElementHandleFactory {
}
else if (binding instanceof ICPPNamespace) {
element= new NamespaceHandle(parentElement, (ICPPNamespace) binding);
}
}
else if (binding instanceof ITypedef) {
element= new TypedefHandle(parentElement, (ITypedef) binding);
}
if (element != null && region != null) {
element.setRangeOfID(region, timestamp);
}

View file

@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.model.ext;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.model.ICElement;
public class TypedefHandle extends CElementHandle implements org.eclipse.cdt.core.model.ITypeDef {
public TypedefHandle(ICElement parent, ITypedef typedef) {
super(parent, ICElement.C_TYPEDEF, typedef.getName());
}
}

View file

@ -166,7 +166,7 @@ ICPPClassScope, IPDOMMemberOwner, IIndexType {
public ICPPMethod[] getMethods() throws DOMException {
try {
MethodCollector methods = new MethodCollector(true);
accept(methods);
acceptInHierarchy(new HashSet(), methods);
return methods.getMethods();
} catch (CoreException e) {
return new ICPPMethod[0];

View file

@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
@ -365,6 +366,12 @@ class PDOMCPPLinkage extends PDOMLinkage {
pdomName.setIsBaseSpecifier(true);
}
}
else if (parentNode instanceof IASTDeclSpecifier) {
IASTDeclSpecifier ds= (IASTDeclSpecifier) parentNode;
if (ds.getStorageClass() == IASTDeclSpecifier.sc_typedef) {
pdomName.setIsBaseSpecifier(true);
}
}
}
}

View file

@ -11,6 +11,8 @@
package org.eclipse.cdt.internal.core.pdom.indexer;
import java.util.ArrayList;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
@ -19,12 +21,14 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
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.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
abstract public class IndexerASTVisitor extends ASTVisitor {
private IASTName fDefinitionName;
private IASTNode fDefinitionNode;
private ArrayList fStack= new ArrayList();
public IndexerASTVisitor() {
shouldVisitNames= true;
@ -37,12 +41,6 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
final public int visit(IASTName name) {
if (!(name instanceof ICPPASTQualifiedName)) {
if (fDefinitionNode != null) {
if (!fDefinitionNode.contains(name)) {
fDefinitionNode= null;
fDefinitionName= null;
}
}
if (name != fDefinitionName) {
visit(name, fDefinitionName);
}
@ -50,69 +48,91 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
return PROCESS_CONTINUE;
}
private void push(IASTName name, IASTNode node) {
if (fDefinitionName != null) {
fStack.add(new Object[] {fDefinitionName, fDefinitionNode});
}
if (name instanceof ICPPASTQualifiedName) {
name= ((ICPPASTQualifiedName) name).getLastName();
}
fDefinitionName= name;
fDefinitionNode= node;
}
private void pop(IASTNode node) {
if (node == fDefinitionNode) {
if (fStack.isEmpty()) {
fDefinitionName= null;
fDefinitionNode= null;
}
else {
Object[] old= (Object[]) fStack.remove(fStack.size()-1);
fDefinitionName= (IASTName) old[0];
fDefinitionNode= (IASTNode) old[1];
}
}
}
// functions and methods
public int visit(IASTDeclaration decl) {
if (decl instanceof IASTFunctionDefinition) {
IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
fDefinitionNode= decl;
fDefinitionName= fdef.getDeclarator().getName();
if (fDefinitionName instanceof ICPPASTQualifiedName) {
fDefinitionName= ((ICPPASTQualifiedName) fDefinitionName).getLastName();
IASTName name = fdef.getDeclarator().getName();
visit(name, fDefinitionName);
push(name, decl);
}
else if (decl instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) decl;
if (sdecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
IASTDeclarator[] declarators= sdecl.getDeclarators();
for (int i = 0; i < declarators.length; i++) {
IASTDeclarator declarator = declarators[i];
if (declarator.getPointerOperators().length == 0 &&
declarator.getNestedDeclarator() == null) {
IASTName name= declarator.getName();
visit(name, fDefinitionName);
push(name, decl);
}
}
}
visit(fDefinitionName, null);
}
return PROCESS_CONTINUE;
}
// leave methods don't get called correctly: bug 152846
// public int leave(IASTDeclaration decl) {
// if (decl == fDefinitionNode) {
// fDefinitionNode= null;
// fDefinitionName= null;
// }
// return PROCESS_CONTINUE;
// }
public int leave(IASTDeclaration decl) {
pop(decl);
return PROCESS_CONTINUE;
}
// class definitions, typedefs
public int visit(IASTDeclSpecifier declspec) {
if (declspec instanceof ICPPASTCompositeTypeSpecifier) {
if (fDefinitionNode == null || !fDefinitionNode.contains(declspec)) {
ICPPASTCompositeTypeSpecifier cts= (ICPPASTCompositeTypeSpecifier) declspec;
fDefinitionNode= declspec;
fDefinitionName= cts.getName();
if (fDefinitionName instanceof ICPPASTQualifiedName) {
fDefinitionName= ((ICPPASTQualifiedName) fDefinitionName).getLastName();
}
visit(fDefinitionName, null);
}
ICPPASTCompositeTypeSpecifier cts= (ICPPASTCompositeTypeSpecifier) declspec;
IASTName name = cts.getName();
visit(name, fDefinitionName);
push(name, declspec);
}
return PROCESS_CONTINUE;
}
// leave methods don't get called correctly: bug 152846
// public int leave(IASTDeclSpecifier declspec) {
// if (declspec == fDefinitionNode) {
// fDefinitionNode= null;
// fDefinitionName= null;
// }
// return PROCESS_CONTINUE;
// }
public int leave(IASTDeclSpecifier declspec) {
pop(declspec);
return PROCESS_CONTINUE;
}
// variable and field initializers
public int visit(IASTInitializer initializer) {
if (fDefinitionNode == null) {
if (!(fDefinitionNode instanceof IASTFunctionDefinition)) {
IASTNode cand= initializer.getParent();
if (cand instanceof IASTDeclarator) {
fDefinitionNode= cand;
fDefinitionName= ((IASTDeclarator) cand).getName();
push(((IASTDeclarator) cand).getName(), initializer);
}
}
return PROCESS_CONTINUE;
}
// leave methods don't get called correctly: bug 152846
// public int leave(IASTInitializer initializer) {
// if (fDefinitionNode == initializer) {
// fDefinitionNode= null;
// fDefinitionName= null;
// }
// return PROCESS_CONTINUE;
// }
public int leave(IASTInitializer initializer) {
pop(initializer);
return PROCESS_CONTINUE;
}
}

View file

@ -25,6 +25,8 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.index.IIndex;
@ -117,14 +119,12 @@ class THGraph {
}
else if (input != null) {
try {
ICElement inputHandle= null;
IIndexName name= IndexUI.elementToName(index, input);
if (name != null) {
ICElementHandle inputHandle= IndexUI.getCElementForName(input.getCProject(), index, name);
fInputNode= addNode(inputHandle);
inputHandle= IndexUI.getCElementForName(input.getCProject(), index, name);
}
else {
fInputNode= addNode(input);
}
fInputNode= addNode(inputHandle == null ? input : inputHandle);
} catch (CoreException e) {
CUIPlugin.getDefault().log(e);
} catch (DOMException e) {
@ -149,9 +149,11 @@ class THGraph {
THGraphNode graphNode= addNode(elem);
try {
IBinding binding = IndexUI.elementToBinding(index, elem);
if (binding != null) {
addMembers(index, graphNode, binding);
}
if (binding instanceof ICPPClassType) {
ICPPClassType ct= (ICPPClassType) binding;
addMembers(index, graphNode, ct);
ICPPBase[] bases= ct.getBases();
for (int i = 0; i < bases.length; i++) {
if (monitor.isCanceled()) {
@ -171,6 +173,23 @@ class THGraph {
}
}
}
else if (binding instanceof ITypedef) {
ITypedef ct= (ITypedef) binding;
IType type= ct.getType();
if (type instanceof IBinding) {
IBinding basecl= (IBinding) type;
ICElementHandle[] baseElems= IndexUI.findRepresentative(index, basecl);
if (baseElems.length > 0) {
ICElementHandle baseElem= baseElems[0];
THGraphNode baseGraphNode= addNode(baseElem);
addMembers(index, baseGraphNode, basecl);
addEdge(graphNode, baseGraphNode);
if (handled.add(baseElem)) {
stack.add(baseElem);
}
}
}
}
} catch (DOMException e) {
CUIPlugin.getDefault().log(e);
} catch (CoreException e) {
@ -196,26 +215,24 @@ class THGraph {
THGraphNode graphNode= addNode(elem);
try {
IBinding binding = IndexUI.elementToBinding(index, elem);
if (binding instanceof ICPPClassType) {
IIndexName[] names= index.findNames(binding, IIndex.FIND_REFERENCES);
for (int i = 0; i < names.length; i++) {
if (monitor.isCanceled()) {
return;
}
IIndexName indexName = names[i];
if (indexName.isBaseSpecifier()) {
IIndexName subClassDef= indexName.getEnclosingDefinition();
if (subClassDef != null) {
IBinding subClass= index.findBinding(subClassDef);
ICElementHandle[] subClassElems= IndexUI.findRepresentative(index, subClass);
if (subClassElems.length > 0) {
ICElementHandle subClassElem= subClassElems[0];
THGraphNode subGraphNode= addNode(subClassElem);
addMembers(index, subGraphNode, subClass);
addEdge(subGraphNode, graphNode);
if (handled.add(subClassElem)) {
stack.add(subClassElem);
}
IIndexName[] names= index.findNames(binding, IIndex.FIND_REFERENCES | IIndex.FIND_DEFINITIONS);
for (int i = 0; i < names.length; i++) {
if (monitor.isCanceled()) {
return;
}
IIndexName indexName = names[i];
if (indexName.isBaseSpecifier()) {
IIndexName subClassDef= indexName.getEnclosingDefinition();
if (subClassDef != null) {
IBinding subClass= index.findBinding(subClassDef);
ICElementHandle[] subClassElems= IndexUI.findRepresentative(index, subClass);
if (subClassElems.length > 0) {
ICElementHandle subClassElem= subClassElems[0];
THGraphNode subGraphNode= addNode(subClassElem);
addMembers(index, subGraphNode, subClass);
addEdge(subGraphNode, graphNode);
if (handled.add(subClassElem)) {
stack.add(subClassElem);
}
}
}

View file

@ -78,7 +78,9 @@ class THGraphNode {
private void collectMembers(HashSet visited, List list) {
if (visited.add(this)) {
list.addAll(Arrays.asList(fMembers));
if (fMembers != null) {
list.addAll(Arrays.asList(fMembers));
}
List bases= getOutgoing();
for (Iterator iterator = bases.iterator(); iterator.hasNext();) {
THGraphEdge edge = (THGraphEdge) iterator.next();

View file

@ -28,6 +28,8 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.ICElement;
@ -185,8 +187,9 @@ public class TypeHierarchyUI {
}
public static boolean isValidInput(IBinding binding) {
if (binding instanceof ICompositeType) {
// || binding instanceof ITypedef ||
if (binding instanceof ICompositeType
|| binding instanceof IEnumeration
|| binding instanceof ITypedef) {
// binding instanceof IField || binding instanceof ICPPMethod) {
return true;
}
@ -204,7 +207,8 @@ public class TypeHierarchyUI {
case ICElement.C_CLASS_DECLARATION:
case ICElement.C_STRUCT_DECLARATION:
case ICElement.C_UNION_DECLARATION:
// case ICElement.C_TYPEDEF:
case ICElement.C_ENUMERATION:
case ICElement.C_TYPEDEF:
// case ICElement.C_FIELD:
// case ICElement.C_METHOD:
// case ICElement.C_METHOD_DECLARATION: