1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Added support for nested classes. Changed the way member owners are done.

This commit is contained in:
Doug Schaefer 2006-08-02 14:36:41 +00:00
parent 7dc248df17
commit b4c738d66a
14 changed files with 423 additions and 242 deletions

View file

@ -16,6 +16,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
@ -48,4 +49,29 @@ public class ClassTests extends PDOMTestBase {
IASTFileLocation loc = Bf_refs[0].getFileLocation(); IASTFileLocation loc = Bf_refs[0].getFileLocation();
assertEquals(offset(95, 84), loc.getNodeOffset()); assertEquals(offset(95, 84), loc.getNodeOffset());
} }
}
public void testNested() throws Exception {
PDOM pdom = (PDOM)CCorePlugin.getPDOMManager().getPDOM(project);
IBinding[] bindings = pdom.findBindings(Pattern.compile("NestedA"));
assertEquals(1, bindings.length);
ICPPClassType NestedA = (ICPPClassType)bindings[0];
ICPPClassType[] nested = NestedA.getNestedClasses();
assertEquals(1, nested.length);
ICPPClassType NestedB = nested[0];
assertEquals("NestedB", NestedB.getName());
IField[] fields = NestedB.getFields();
assertEquals(1, fields.length);
IField NestedB_x = fields[0];
IASTName[] refs = pdom.getReferences(NestedB);
assertEquals(1, refs.length);
IASTFileLocation loc = refs[0].getFileLocation();
assertEquals(offset(96, 87), loc.getNodeOffset());
refs = pdom.getReferences(NestedB_x);
assertEquals(1, refs.length);
loc = refs[0].getFileLocation();
assertEquals(offset(118, 108), loc.getNodeOffset());
}
}

View file

@ -0,0 +1,12 @@
class NestedA {
public:
class NestedB {
public:
int x;
};
};
int f() {
NestedA::NestedB x;
return x.x;
}

View file

@ -54,7 +54,7 @@ public class PDOM extends PlatformObject
private Database db; private Database db;
public static final int VERSION = 10; public static final int VERSION = 11;
// 0 - the beginning of it all // 0 - the beginning of it all
// 1 - first change to kick off upgrades // 1 - first change to kick off upgrades
// 2 - added file inclusions // 2 - added file inclusions
@ -66,6 +66,7 @@ public class PDOM extends PlatformObject
// 8 - enumerators // 8 - enumerators
// 9 - base classes // 9 - base classes
// 10 - typedefs, types on C++ variables // 10 - typedefs, types on C++ variables
// 11 - changed how members work
public static final int LINKAGES = Database.DATA_AREA; public static final int LINKAGES = Database.DATA_AREA;
public static final int FILE_INDEX = Database.DATA_AREA + 4; public static final int FILE_INDEX = Database.DATA_AREA + 4;
@ -361,4 +362,4 @@ public class PDOM extends PlatformObject
fireChange(); fireChange();
} }
} }

View file

@ -0,0 +1,82 @@
/*******************************************************************************
* Copyright (c) 2006 QNX Software Systems 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:
* QNX - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db;
import org.eclipse.core.runtime.CoreException;
/**
* This is a list item. It contains a next and prev pointer
* as well as a pointer to the item.
* block.
*
* @author Doug Schaefer
*/
public class ListItem {
protected final Database db;
protected final int record;
protected static final int NEXT = 0;
protected static final int PREV = 4;
protected static final int ITEM = 8;
protected static final int RECORD_SIZE = 12;
public ListItem(Database db, int record) {
this.db = db;
this.record = record;
}
public ListItem(Database db) throws CoreException {
this.db = db;
this.record = db.malloc(RECORD_SIZE);
}
public int getRecord() {
return record;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
else if (obj instanceof ListItem)
return record == ((ListItem)obj).record;
else
return false;
}
public void setItem(int item) throws CoreException {
db.putInt(record + ITEM, item);
}
public int getItem() throws CoreException {
return db.getInt(record + ITEM);
}
public void setNext(ListItem next) throws CoreException {
db.putInt(record + NEXT, next.getRecord());
}
public ListItem getNext() throws CoreException {
int next = db.getInt(record + NEXT);
return next != 0 ? new ListItem(db, next) : null;
}
public void setPrev(ListItem prev) throws CoreException {
db.putInt(record + PREV, prev.getRecord());
}
public ListItem getPrev() throws CoreException {
int prev = db.getInt(record + PREV);
return prev != 0 ? new ListItem(db, prev) : null;
}
}

View file

@ -1,70 +0,0 @@
/*******************************************************************************
* Copyright (c) 2005, 2006 QNX Software Systems 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:
* QNX - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPClassType;
import org.eclipse.core.runtime.CoreException;
/**
* @author Doug Schaefer
*
*/
public abstract class PDOMMember extends PDOMBinding {
private static final int OWNER = PDOMBinding.RECORD_SIZE + 0;
private static final int NEXT_MEMBER = PDOMBinding.RECORD_SIZE + 4;
private static final int PREV_MEMBER = PDOMBinding.RECORD_SIZE + 8;
protected static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 12;
public PDOMMember(PDOM pdom, PDOMMemberOwner parent, IASTName name) throws CoreException {
super(pdom, parent, name);
parent.addMember(this);
}
public PDOMMember(PDOM pdom, int record) {
super(pdom, record);
}
public PDOMMember getNextMember() throws CoreException {
return (PDOMMember)getLinkage().getNode(
pdom.getDB().getInt(record + NEXT_MEMBER));
}
public void setNextMember(PDOMMember member) throws CoreException {
pdom.getDB().putInt(record + NEXT_MEMBER,
member != null ? member.getRecord() : 0);
}
public PDOMMember getPrevMember() throws CoreException {
return (PDOMMember)getLinkage().getNode(
pdom.getDB().getInt(record + PREV_MEMBER));
}
public void setPrevMember(PDOMMember member) throws CoreException {
pdom.getDB().putInt(record + PREV_MEMBER,
member != null ? member.getRecord() : 0);
}
public PDOMMemberOwner getMemberOwner() throws CoreException {
return (PDOMCPPClassType)getLinkage().getNode(
pdom.getDB().getInt(record + OWNER));
}
public void setMemberOwner(PDOMMemberOwner owner) throws CoreException {
pdom.getDB().putInt(record + OWNER,
owner != null ? owner.getRecord() : 0);
}
}

View file

@ -11,11 +11,11 @@
package org.eclipse.cdt.internal.core.pdom.dom; package org.eclipse.cdt.internal.core.pdom.dom;
import java.util.ArrayList;
import org.eclipse.cdt.core.dom.IPDOMVisitor; import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.ListItem;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
@ -25,9 +25,8 @@ import org.eclipse.core.runtime.CoreException;
public abstract class PDOMMemberOwner extends PDOMBinding { public abstract class PDOMMemberOwner extends PDOMBinding {
private static final int FIRST_MEMBER = PDOMBinding.RECORD_SIZE + 0; private static final int FIRST_MEMBER = PDOMBinding.RECORD_SIZE + 0;
private static final int LAST_MEMBER = PDOMBinding.RECORD_SIZE + 4;
protected static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 8; protected static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 4;
public PDOMMemberOwner(PDOM pdom, PDOMNode parent, IASTName name) throws CoreException { public PDOMMemberOwner(PDOM pdom, PDOMNode parent, IASTName name) throws CoreException {
super(pdom, parent, name); super(pdom, parent, name);
@ -43,69 +42,44 @@ public abstract class PDOMMemberOwner extends PDOMBinding {
public void accept(IPDOMVisitor visitor) throws CoreException { public void accept(IPDOMVisitor visitor) throws CoreException {
super.accept(visitor); super.accept(visitor);
for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) ListItem firstItem = getFirstMemberItem();
if (visitor.visit(member)) if (firstItem == null)
member.accept(visitor); return;
}
public void addMember(PDOMMember member) throws CoreException {
PDOMMember last = getLastMember();
if (last != null) {
last.setNextMember(member);
member.setPrevMember(last);
} else // first add
setFirstMember(member);
setLastMember(member);
member.setMemberOwner(this);
}
public PDOMMember getFirstMember() throws CoreException {
return (PDOMMember)getLinkage().getNode(
pdom.getDB().getInt(record + FIRST_MEMBER));
}
public PDOMMember getLastMember() throws CoreException {
return (PDOMMember)getLinkage().getNode(
pdom.getDB().getInt(record + LAST_MEMBER));
}
public void setFirstMember(PDOMMember member) throws CoreException {
int memberrec = member != null ? member.getRecord() : 0;
pdom.getDB().putInt(record + FIRST_MEMBER, memberrec);
}
public void setLastMember(PDOMMember member) throws CoreException {
int memberrec = member != null ? member.getRecord() : 0;
pdom.getDB().putInt(record + LAST_MEMBER, memberrec);
}
public int getNumMembers() throws CoreException {
int n = 0;
for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) PDOMLinkage linkage = getLinkage();
++n; ListItem item = firstItem;
do {
return n; PDOMNode node = linkage.getNode(item.getItem());
} if (visitor.visit(node))
node.accept(visitor);
public PDOMMember getMember(int index) throws CoreException { item = item.getNext();
int n = 0; } while (!item.equals(firstItem));
for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember())
if (n++ == index)
return member;
return null;
} }
public PDOMMember[] findMembers(char[] name) throws CoreException { private ListItem getFirstMemberItem() throws CoreException {
ArrayList members = new ArrayList(); Database db = pdom.getDB();
int item = db.getInt(record + FIRST_MEMBER);
for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) return item != 0 ? new ListItem(db, item) : null;
if (member.hasName(name)) }
members.add(member);
public void addMember(PDOMNode member) throws CoreException {
return (PDOMMember[])members.toArray(new PDOMMember[members.size()]); Database db = pdom.getDB();
ListItem firstMember = getFirstMemberItem();
if (firstMember == null) {
firstMember = new ListItem(db);
firstMember.setItem(member.getRecord());
firstMember.setNext(firstMember);
firstMember.setPrev(firstMember);
db.putInt(record + FIRST_MEMBER, firstMember.getRecord());
} else {
ListItem newMember = new ListItem(db);
newMember.setItem(member.getRecord());
ListItem prevMember = firstMember.getPrev();
prevMember.setNext(newMember);
firstMember.setPrev(newMember);
newMember.setPrev(prevMember);
newMember.setNext(firstMember);
}
} }
} }

View file

@ -50,6 +50,8 @@ public abstract class PDOMNode implements IPDOMNode{
// parent // parent
db.putInt(record + PARENT, parent != null ? parent.getRecord() : 0); db.putInt(record + PARENT, parent != null ? parent.getRecord() : 0);
if (parent instanceof PDOMMemberOwner)
((PDOMMemberOwner)parent).addMember(this);
} }
protected abstract int getRecordSize(); protected abstract int getRecordSize();
@ -107,4 +109,4 @@ public abstract class PDOMNode implements IPDOMNode{
// nothing here // nothing here
} }
} }

View file

@ -16,7 +16,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMember; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -25,7 +25,7 @@ import org.eclipse.core.runtime.CoreException;
* @author Doug Schaefer * @author Doug Schaefer
* *
*/ */
public class PDOMCField extends PDOMMember implements IField { public class PDOMCField extends PDOMBinding implements IField {
public PDOMCField(PDOM pdom, PDOMMemberOwner parent, IASTName name) throws CoreException { public PDOMCField(PDOM pdom, PDOMMemberOwner parent, IASTName name) throws CoreException {
super(pdom, parent, name); super(pdom, parent, name);

View file

@ -14,6 +14,8 @@ package org.eclipse.cdt.internal.core.pdom.dom.c;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
@ -39,12 +41,12 @@ import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile; import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMember;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Status;
/** /**
* @author Doug Schaefer * @author Doug Schaefer
@ -174,15 +176,45 @@ public class PDOMCLinkage extends PDOMLinkage {
} }
} }
private static class FindBinding2 implements IPDOMVisitor {
private PDOMBinding binding;
private final char[] name;
private final int[] desiredType;
public FindBinding2(char[] name, int desiredType) {
this(name, new int[] { desiredType });
}
public FindBinding2(char[] name, int[] desiredType) {
this.name = name;
this.desiredType = desiredType;
}
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof PDOMBinding) {
PDOMBinding tBinding = (PDOMBinding)node;
if (tBinding.hasName(name)) {
int nodeType = tBinding.getNodeType();
for (int i = 0; i < desiredType.length; ++i)
if (nodeType == desiredType[i]) {
// got it
binding = tBinding;
throw new CoreException(Status.OK_STATUS);
}
}
}
return false;
}
public PDOMBinding getBinding() { return binding; }
}
protected int getBindingType(IBinding binding) { protected int getBindingType(IBinding binding) {
if (binding instanceof IVariable) if (binding instanceof IField)
// This needs to be before variable
return CFIELD;
else if (binding instanceof IVariable)
return CVARIABLE; return CVARIABLE;
else if (binding instanceof IFunction) else if (binding instanceof IFunction)
return CFUNCTION; return CFUNCTION;
else if (binding instanceof ICompositeType) else if (binding instanceof ICompositeType)
return CSTRUCTURE; return CSTRUCTURE;
else if (binding instanceof IField)
return CFIELD;
else if (binding instanceof IEnumeration) else if (binding instanceof IEnumeration)
return CENUMERATION; return CENUMERATION;
else if (binding instanceof IEnumerator) else if (binding instanceof IEnumerator)
@ -203,10 +235,16 @@ public class PDOMCLinkage extends PDOMLinkage {
getIndex().accept(visitor); getIndex().accept(visitor);
return visitor.pdomBinding; return visitor.pdomBinding;
} else if (parent instanceof PDOMMemberOwner) { } else if (parent instanceof PDOMMemberOwner) {
FindBinding2 visitor = new FindBinding2(binding.getNameCharArray(), getBindingType(binding));
PDOMMemberOwner owner = (PDOMMemberOwner)parent; PDOMMemberOwner owner = (PDOMMemberOwner)parent;
PDOMMember[] members = owner.findMembers(binding.getNameCharArray()); try {
if (members.length > 0) owner.accept(visitor);
return members[0]; } catch (CoreException e) {
if (e.getStatus().equals(Status.OK_STATUS))
return visitor.getBinding();
else
throw e;
}
} }
return null; return null;
} }
@ -267,4 +305,4 @@ public class PDOMCLinkage extends PDOMLinkage {
return null; return null;
} }
} }

View file

@ -12,8 +12,11 @@
package org.eclipse.cdt.internal.core.pdom.dom.c; package org.eclipse.cdt.internal.core.pdom.dom.c;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
@ -21,11 +24,11 @@ import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMember;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Status;
/** /**
* @author Doug Schaefer * @author Doug Schaefer
@ -53,29 +56,60 @@ public class PDOMCStructure extends PDOMMemberOwner implements ICompositeType {
throw new PDOMNotImplementedError(); throw new PDOMNotImplementedError();
} }
private static class GetFields implements IPDOMVisitor {
private List fields = new ArrayList();
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof IField)
fields.add(node);
return false;
}
public IField[] getFields() {
return (IField[])fields.toArray(new IField[fields.size()]);
}
}
public IField[] getFields() throws DOMException { public IField[] getFields() throws DOMException {
try { try {
ArrayList fields = new ArrayList(); GetFields fields = new GetFields();
accept(fields);
for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) { return fields.getFields();
if (member instanceof IField)
fields.add(member);
}
return (IField[])fields.toArray(new IField[fields.size()]);
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
return new IField[0]; return new IField[0];
} }
} }
public static class FindField implements IPDOMVisitor {
private IField field;
private final String name;
public FindField(String name) {
this.name = name;
}
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof IField) {
IField tField = (IField)node;
if (name.equals(tField.getName())) {
field = tField;
throw new CoreException(Status.OK_STATUS);
}
}
return false;
}
public IField getField() { return field; }
}
public IField findField(String name) throws DOMException { public IField findField(String name) throws DOMException {
FindField field = new FindField(name);
try { try {
PDOMMember[] members = findMembers(name.toCharArray()); accept(field);
return members.length > 0 ? (PDOMCField)members[0] : null; // returned => not found
} catch (CoreException e) {
CCorePlugin.log(e);
return null; return null;
} catch (CoreException e) {
if (e.getStatus().equals(Status.OK_STATUS))
return field.getField();
else {
CCorePlugin.log(e);
return null;
}
} }
} }
@ -91,4 +125,4 @@ public class PDOMCStructure extends PDOMMemberOwner implements ICompositeType {
return false; return false;
} }
} }

View file

@ -17,6 +17,8 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -34,7 +36,6 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMember;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
@ -107,37 +108,6 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
throw new PDOMNotImplementedError(); throw new PDOMNotImplementedError();
} }
private void visitAllDeclaredMethods(Set visited, List methods) throws CoreException {
if (visited.contains(this))
return;
visited.add(this);
// Get my members
for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) {
if (member instanceof ICPPMethod)
methods.add(member);
}
// Visit my base classes
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase()) {
IBinding baseClass = base.getBaseClass();
if (baseClass != null && baseClass instanceof PDOMCPPClassType)
((PDOMCPPClassType)baseClass).visitAllDeclaredMethods(visited, methods);
}
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
List methods = new ArrayList();
Set visited = new HashSet();
try {
visitAllDeclaredMethods(visited, methods);
return (ICPPMethod[])methods.toArray(new ICPPMethod[methods.size()]);
} catch (CoreException e) {
CCorePlugin.log(e);
return new ICPPMethod[0];
}
}
public ICPPBase[] getBases() throws DOMException { public ICPPBase[] getBases() throws DOMException {
try { try {
List list = new ArrayList(); List list = new ArrayList();
@ -161,27 +131,56 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
throw new PDOMNotImplementedError(); throw new PDOMNotImplementedError();
} }
private static class GetMethods implements IPDOMVisitor {
private final List methods;
public GetMethods(List methods) {
this.methods = methods;
}
public GetMethods() {
this.methods = new ArrayList();
}
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof ICPPMethod)
methods.add(node);
return false; // don't visit the method
}
public ICPPMethod[] getMethods() {
return (ICPPMethod[])methods.toArray(new ICPPMethod[methods.size()]);
}
}
public ICPPMethod[] getDeclaredMethods() throws DOMException { public ICPPMethod[] getDeclaredMethods() throws DOMException {
throw new PDOMNotImplementedError();
}
public IField[] getFields() throws DOMException {
throw new PDOMNotImplementedError();
}
public IBinding[] getFriends() throws DOMException {
throw new PDOMNotImplementedError();
}
public ICPPMethod[] getMethods() throws DOMException {
try { try {
ArrayList methods = new ArrayList(); GetMethods methods = new GetMethods();
accept(methods);
return methods.getMethods();
} catch (CoreException e) {
return new ICPPMethod[0];
}
}
private void visitAllDeclaredMethods(Set visited, List methods) throws CoreException {
if (visited.contains(this))
return;
visited.add(this);
for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) { // Get my members
if (member instanceof ICPPMethod) GetMethods myMethods = new GetMethods(methods);
methods.add(member); accept(myMethods);
}
// Visit my base classes
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase()) {
IBinding baseClass = base.getBaseClass();
if (baseClass != null && baseClass instanceof PDOMCPPClassType)
((PDOMCPPClassType)baseClass).visitAllDeclaredMethods(visited, methods);
}
}
public ICPPMethod[] getAllDeclaredMethods() throws DOMException {
List methods = new ArrayList();
Set visited = new HashSet();
try {
visitAllDeclaredMethods(visited, methods);
return (ICPPMethod[])methods.toArray(new ICPPMethod[methods.size()]); return (ICPPMethod[])methods.toArray(new ICPPMethod[methods.size()]);
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
@ -189,10 +188,61 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
} }
} }
public ICPPClassType[] getNestedClasses() throws DOMException { public ICPPMethod[] getMethods() throws DOMException {
// TODO Should really include implicit methods too
return getDeclaredMethods();
}
private static class GetFields implements IPDOMVisitor {
private List fields = new ArrayList();
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof IField)
fields.add(node);
return false;
}
public IField[] getFields() {
return (IField[])fields.toArray(new IField[fields.size()]);
}
}
public IField[] getFields() throws DOMException {
try {
GetFields visitor = new GetFields();
accept(visitor);
return visitor.getFields();
} catch (CoreException e) {
CCorePlugin.log(e);
return new IField[0];
}
}
public IBinding[] getFriends() throws DOMException {
throw new PDOMNotImplementedError(); throw new PDOMNotImplementedError();
} }
private static class GetNestedClasses implements IPDOMVisitor {
private List nestedClasses = new ArrayList();
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof ICPPClassType)
nestedClasses.add(node);
return false;
}
public ICPPClassType[] getNestedClasses() {
return (ICPPClassType[])nestedClasses.toArray(new ICPPClassType[nestedClasses.size()]);
}
}
public ICPPClassType[] getNestedClasses() throws DOMException {
try {
GetNestedClasses visitor = new GetNestedClasses();
accept(visitor);
return visitor.getNestedClasses();
} catch (CoreException e) {
CCorePlugin.log(e);
return new ICPPClassType[0];
}
}
public IScope getCompositeScope() throws DOMException { public IScope getCompositeScope() throws DOMException {
return this; return this;
} }
@ -248,14 +298,7 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType,
} }
public IBinding getBinding(IASTName name, boolean resolve) throws DOMException { public IBinding getBinding(IASTName name, boolean resolve) throws DOMException {
try { return null;
PDOMMember[] matches = findMembers(name.toCharArray());
// TODO - need to check for overloads
return matches.length > 0 ? matches[0] : null;
} catch (CoreException e) {
CCorePlugin.log(e);
return null;
}
} }
public IScope getParent() throws DOMException { public IScope getParent() throws DOMException {

View file

@ -19,7 +19,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMember; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -27,7 +27,7 @@ import org.eclipse.core.runtime.CoreException;
* @author Doug Schaefer * @author Doug Schaefer
* *
*/ */
public class PDOMCPPField extends PDOMMember implements ICPPField { public class PDOMCPPField extends PDOMBinding implements ICPPField {
public PDOMCPPField(PDOM pdom, PDOMCPPClassType parent, IASTName name) public PDOMCPPField(PDOM pdom, PDOMCPPClassType parent, IASTName name)
throws CoreException { throws CoreException {
@ -48,7 +48,7 @@ public class PDOMCPPField extends PDOMMember implements ICPPField {
public ICPPClassType getClassOwner() throws DOMException { public ICPPClassType getClassOwner() throws DOMException {
try { try {
return (ICPPClassType)getMemberOwner(); return (ICPPClassType)getParentNode();
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
return null; return null;

View file

@ -14,6 +14,8 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
@ -48,12 +50,12 @@ import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile; import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMember;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Status;
/** /**
* @author Doug Schaefer * @author Doug Schaefer
@ -219,20 +221,51 @@ public class PDOMCPPLinkage extends PDOMLinkage {
} }
} }
private static class FindBinding2 implements IPDOMVisitor {
private PDOMBinding binding;
private final char[] name;
private final int[] desiredType;
public FindBinding2(char[] name, int desiredType) {
this(name, new int[] { desiredType });
}
public FindBinding2(char[] name, int[] desiredType) {
this.name = name;
this.desiredType = desiredType;
}
public boolean visit(IPDOMNode node) throws CoreException {
if (node instanceof PDOMBinding) {
PDOMBinding tBinding = (PDOMBinding)node;
if (tBinding.hasName(name)) {
int nodeType = tBinding.getNodeType();
for (int i = 0; i < desiredType.length; ++i)
if (nodeType == desiredType[i]) {
// got it
binding = tBinding;
throw new CoreException(Status.OK_STATUS);
}
}
}
return false;
}
public PDOMBinding getBinding() { return binding; }
}
protected int getBindingType(IBinding binding) { protected int getBindingType(IBinding binding) {
if (binding instanceof ICPPVariable) if (binding instanceof ICPPTemplateDefinition)
return CPPVARIABLE;
else if (binding instanceof ICPPTemplateDefinition)
// this must be before class type // this must be before class type
return 0; return 0;
else if (binding instanceof ICPPField)
// this must be before variables
return CPPFIELD;
else if (binding instanceof ICPPVariable)
return CPPVARIABLE;
else if (binding instanceof ICPPMethod)
// this must be before functions
return CPPMETHOD;
else if (binding instanceof ICPPFunction) else if (binding instanceof ICPPFunction)
return CPPFUNCTION; return CPPFUNCTION;
else if (binding instanceof ICPPClassType) else if (binding instanceof ICPPClassType)
return CPPCLASSTYPE; return CPPCLASSTYPE;
else if (binding instanceof ICPPField)
return CPPFIELD;
else if (binding instanceof ICPPMethod)
return CPPMETHOD;
else if (binding instanceof ICPPNamespaceAlias) else if (binding instanceof ICPPNamespaceAlias)
return CPPNAMESPACEALIAS; return CPPNAMESPACEALIAS;
else if (binding instanceof ICPPNamespace) else if (binding instanceof ICPPNamespace)
@ -260,10 +293,16 @@ public class PDOMCPPLinkage extends PDOMLinkage {
getIndex().accept(visitor); getIndex().accept(visitor);
return visitor.pdomBinding; return visitor.pdomBinding;
} else if (parent instanceof PDOMMemberOwner) { } else if (parent instanceof PDOMMemberOwner) {
FindBinding2 visitor = new FindBinding2(binding.getNameCharArray(), getBindingType(binding));
PDOMMemberOwner owner = (PDOMMemberOwner)parent; PDOMMemberOwner owner = (PDOMMemberOwner)parent;
PDOMMember[] members = owner.findMembers(binding.getNameCharArray()); try {
if (members.length > 0) owner.accept(visitor);
return members[0]; } catch (CoreException e) {
if (e.getStatus().equals(Status.OK_STATUS))
return visitor.getBinding();
else
throw e;
}
} else if (parent instanceof PDOMCPPNamespace) { } else if (parent instanceof PDOMCPPNamespace) {
FindBinding visitor = new FindBinding(pdom, binding.getNameCharArray(), getBindingType(binding)); FindBinding visitor = new FindBinding(pdom, binding.getNameCharArray(), getBindingType(binding));
((PDOMCPPNamespace)parent).getIndex().accept(visitor); ((PDOMCPPNamespace)parent).getIndex().accept(visitor);

View file

@ -28,7 +28,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMember; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -37,12 +37,12 @@ import org.eclipse.core.runtime.CoreException;
* @author Doug Schaefer * @author Doug Schaefer
* *
*/ */
public class PDOMCPPMethod extends PDOMMember implements ICPPMethod, ICPPFunctionType { public class PDOMCPPMethod extends PDOMBinding implements ICPPMethod, ICPPFunctionType {
public static final int NUM_PARAMS = PDOMMember.RECORD_SIZE + 0; public static final int NUM_PARAMS = PDOMBinding.RECORD_SIZE + 0;
public static final int FIRST_PARAM = PDOMMember.RECORD_SIZE + 4; public static final int FIRST_PARAM = PDOMBinding.RECORD_SIZE + 4;
public static final int RECORD_SIZE = PDOMMember.RECORD_SIZE + 8; public static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 8;
public PDOMCPPMethod(PDOM pdom, PDOMMemberOwner parent, IASTName name) throws CoreException { public PDOMCPPMethod(PDOM pdom, PDOMMemberOwner parent, IASTName name) throws CoreException {
super(pdom, parent, name); super(pdom, parent, name);
@ -165,7 +165,7 @@ public class PDOMCPPMethod extends PDOMMember implements ICPPMethod, ICPPFunctio
public ICPPClassType getClassOwner() throws DOMException { public ICPPClassType getClassOwner() throws DOMException {
try { try {
return (ICPPClassType)getMemberOwner(); return (ICPPClassType)getParentNode();
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
return null; return null;
@ -205,4 +205,4 @@ public class PDOMCPPMethod extends PDOMMember implements ICPPMethod, ICPPFunctio
return false; return false;
} }
} }