From b4c738d66af21a4850d8b6f478fa7484ba260ace Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Wed, 2 Aug 2006 14:36:41 +0000 Subject: [PATCH] Added support for nested classes. Changed the way member owners are done. --- .../cdt/internal/pdom/tests/ClassTests.java | 28 ++- .../resources/pdomtests/classTests/nested.cpp | 12 ++ .../eclipse/cdt/internal/core/pdom/PDOM.java | 5 +- .../cdt/internal/core/pdom/db/ListItem.java | 82 +++++++++ .../internal/core/pdom/dom/PDOMMember.java | 70 -------- .../core/pdom/dom/PDOMMemberOwner.java | 102 +++++------ .../cdt/internal/core/pdom/dom/PDOMNode.java | 4 +- .../internal/core/pdom/dom/c/PDOMCField.java | 4 +- .../core/pdom/dom/c/PDOMCLinkage.java | 54 +++++- .../core/pdom/dom/c/PDOMCStructure.java | 62 +++++-- .../core/pdom/dom/cpp/PDOMCPPClassType.java | 161 +++++++++++------- .../core/pdom/dom/cpp/PDOMCPPField.java | 6 +- .../core/pdom/dom/cpp/PDOMCPPLinkage.java | 61 +++++-- .../core/pdom/dom/cpp/PDOMCPPMethod.java | 14 +- 14 files changed, 423 insertions(+), 242 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/resources/pdomtests/classTests/nested.cpp create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ListItem.java delete mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMember.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/ClassTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/ClassTests.java index 7d1074d383b..4c039933fa1 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/ClassTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/ClassTests.java @@ -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.IASTName; 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.ICPPMethod; import org.eclipse.cdt.core.model.ICProject; @@ -48,4 +49,29 @@ public class ClassTests extends PDOMTestBase { IASTFileLocation loc = Bf_refs[0].getFileLocation(); 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()); + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/resources/pdomtests/classTests/nested.cpp b/core/org.eclipse.cdt.core.tests/resources/pdomtests/classTests/nested.cpp new file mode 100644 index 00000000000..456d2f10c7a --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/pdomtests/classTests/nested.cpp @@ -0,0 +1,12 @@ +class NestedA { +public: + class NestedB { + public: + int x; + }; +}; + +int f() { + NestedA::NestedB x; + return x.x; +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 6c86221360c..a1fb370a444 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -54,7 +54,7 @@ public class PDOM extends PlatformObject private Database db; - public static final int VERSION = 10; + public static final int VERSION = 11; // 0 - the beginning of it all // 1 - first change to kick off upgrades // 2 - added file inclusions @@ -66,6 +66,7 @@ public class PDOM extends PlatformObject // 8 - enumerators // 9 - base classes // 10 - typedefs, types on C++ variables + // 11 - changed how members work public static final int LINKAGES = Database.DATA_AREA; public static final int FILE_INDEX = Database.DATA_AREA + 4; @@ -361,4 +362,4 @@ public class PDOM extends PlatformObject fireChange(); } -} +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ListItem.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ListItem.java new file mode 100644 index 00000000000..c79242c2c3a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ListItem.java @@ -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; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMember.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMember.java deleted file mode 100644 index 0ab0e65a58a..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMember.java +++ /dev/null @@ -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); - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMemberOwner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMemberOwner.java index d6196e4f59e..480d02e36ba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMemberOwner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMemberOwner.java @@ -11,11 +11,11 @@ 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.ast.IASTName; 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; /** @@ -25,9 +25,8 @@ import org.eclipse.core.runtime.CoreException; public abstract class PDOMMemberOwner extends PDOMBinding { 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 { super(pdom, parent, name); @@ -43,69 +42,44 @@ public abstract class PDOMMemberOwner extends PDOMBinding { public void accept(IPDOMVisitor visitor) throws CoreException { super.accept(visitor); - for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) - if (visitor.visit(member)) - member.accept(visitor); - - } - - 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; + ListItem firstItem = getFirstMemberItem(); + if (firstItem == null) + return; - for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) - ++n; - - return n; - } - - public PDOMMember getMember(int index) throws CoreException { - int n = 0; - for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) - if (n++ == index) - return member; - return null; + PDOMLinkage linkage = getLinkage(); + ListItem item = firstItem; + do { + PDOMNode node = linkage.getNode(item.getItem()); + if (visitor.visit(node)) + node.accept(visitor); + item = item.getNext(); + } while (!item.equals(firstItem)); } - public PDOMMember[] findMembers(char[] name) throws CoreException { - ArrayList members = new ArrayList(); - - for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) - if (member.hasName(name)) - members.add(member); - - return (PDOMMember[])members.toArray(new PDOMMember[members.size()]); + private ListItem getFirstMemberItem() throws CoreException { + Database db = pdom.getDB(); + int item = db.getInt(record + FIRST_MEMBER); + return item != 0 ? new ListItem(db, item) : null; + } + + public void addMember(PDOMNode member) throws CoreException { + 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); + } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java index 738b8cac031..fff9b3430a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNode.java @@ -50,6 +50,8 @@ public abstract class PDOMNode implements IPDOMNode{ // parent db.putInt(record + PARENT, parent != null ? parent.getRecord() : 0); + if (parent instanceof PDOMMemberOwner) + ((PDOMMemberOwner)parent).addMember(this); } protected abstract int getRecordSize(); @@ -107,4 +109,4 @@ public abstract class PDOMNode implements IPDOMNode{ // nothing here } -} +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCField.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCField.java index 35e5609679d..d63b2603286 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCField.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCField.java @@ -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.IType; 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.PDOMNotImplementedError; import org.eclipse.core.runtime.CoreException; @@ -25,7 +25,7 @@ import org.eclipse.core.runtime.CoreException; * @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 { super(pdom, parent, name); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java index c6b63d2fbe9..af165e65062 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java @@ -14,6 +14,8 @@ package org.eclipse.cdt.internal.core.pdom.dom.c; import java.util.List; 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.IASTFunctionCallExpression; 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.PDOMFile; 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.PDOMName; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Status; /** * @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) { - if (binding instanceof IVariable) + if (binding instanceof IField) + // This needs to be before variable + return CFIELD; + else if (binding instanceof IVariable) return CVARIABLE; else if (binding instanceof IFunction) return CFUNCTION; else if (binding instanceof ICompositeType) return CSTRUCTURE; - else if (binding instanceof IField) - return CFIELD; else if (binding instanceof IEnumeration) return CENUMERATION; else if (binding instanceof IEnumerator) @@ -203,10 +235,16 @@ public class PDOMCLinkage extends PDOMLinkage { getIndex().accept(visitor); return visitor.pdomBinding; } else if (parent instanceof PDOMMemberOwner) { + FindBinding2 visitor = new FindBinding2(binding.getNameCharArray(), getBindingType(binding)); PDOMMemberOwner owner = (PDOMMemberOwner)parent; - PDOMMember[] members = owner.findMembers(binding.getNameCharArray()); - if (members.length > 0) - return members[0]; + try { + owner.accept(visitor); + } catch (CoreException e) { + if (e.getStatus().equals(Status.OK_STATUS)) + return visitor.getBinding(); + else + throw e; + } } return null; } @@ -267,4 +305,4 @@ public class PDOMCLinkage extends PDOMLinkage { return null; } -} +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java index 7a129b6b2ee..0afff6c534b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java @@ -12,8 +12,11 @@ package org.eclipse.cdt.internal.core.pdom.dom.c; import java.util.ArrayList; +import java.util.List; 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.IASTName; 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.IType; 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.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Status; /** * @author Doug Schaefer @@ -53,29 +56,60 @@ public class PDOMCStructure extends PDOMMemberOwner implements ICompositeType { 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 { try { - ArrayList fields = new ArrayList(); - - for (PDOMMember member = getFirstMember(); member != null; member = member.getNextMember()) { - if (member instanceof IField) - fields.add(member); - } - - return (IField[])fields.toArray(new IField[fields.size()]); + GetFields fields = new GetFields(); + accept(fields); + return fields.getFields(); } catch (CoreException e) { CCorePlugin.log(e); 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 { + FindField field = new FindField(name); try { - PDOMMember[] members = findMembers(name.toCharArray()); - return members.length > 0 ? (PDOMCField)members[0] : null; - } catch (CoreException e) { - CCorePlugin.log(e); + accept(field); + // returned => not found 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; } -} +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index e4e58f5cfa5..a5174c9e3cc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -17,6 +17,8 @@ import java.util.List; import java.util.Set; 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.IASTName; 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.dom.PDOMBinding; 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.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError; @@ -107,37 +108,6 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType, 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 { try { List list = new ArrayList(); @@ -161,27 +131,56 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType, 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 { - 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 { - 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()) { - if (member instanceof ICPPMethod) - methods.add(member); - } - + // Get my members + GetMethods myMethods = new GetMethods(methods); + 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()]); } catch (CoreException 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(); } + 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 { return this; } @@ -248,14 +298,7 @@ public class PDOMCPPClassType extends PDOMMemberOwner implements ICPPClassType, } public IBinding getBinding(IASTName name, boolean resolve) throws DOMException { - try { - 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; - } + return null; } public IScope getParent() throws DOMException { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java index 1c754d1fc67..eac60654bb5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPField.java @@ -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.internal.core.dom.parser.cpp.CPPVisitor; 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.core.runtime.CoreException; @@ -27,7 +27,7 @@ import org.eclipse.core.runtime.CoreException; * @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) throws CoreException { @@ -48,7 +48,7 @@ public class PDOMCPPField extends PDOMMember implements ICPPField { public ICPPClassType getClassOwner() throws DOMException { try { - return (ICPPClassType)getMemberOwner(); + return (ICPPClassType)getParentNode(); } catch (CoreException e) { CCorePlugin.log(e); return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 11527a77267..f6e8fab5d83 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -14,6 +14,8 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp; import java.util.List; 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.IASTIdExpression; 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.PDOMFile; 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.PDOMName; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Status; /** * @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) { - if (binding instanceof ICPPVariable) - return CPPVARIABLE; - else if (binding instanceof ICPPTemplateDefinition) + if (binding instanceof ICPPTemplateDefinition) // this must be before class type 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) return CPPFUNCTION; else if (binding instanceof ICPPClassType) return CPPCLASSTYPE; - else if (binding instanceof ICPPField) - return CPPFIELD; - else if (binding instanceof ICPPMethod) - return CPPMETHOD; else if (binding instanceof ICPPNamespaceAlias) return CPPNAMESPACEALIAS; else if (binding instanceof ICPPNamespace) @@ -260,10 +293,16 @@ public class PDOMCPPLinkage extends PDOMLinkage { getIndex().accept(visitor); return visitor.pdomBinding; } else if (parent instanceof PDOMMemberOwner) { + FindBinding2 visitor = new FindBinding2(binding.getNameCharArray(), getBindingType(binding)); PDOMMemberOwner owner = (PDOMMemberOwner)parent; - PDOMMember[] members = owner.findMembers(binding.getNameCharArray()); - if (members.length > 0) - return members[0]; + try { + owner.accept(visitor); + } catch (CoreException e) { + if (e.getStatus().equals(Status.OK_STATUS)) + return visitor.getBinding(); + else + throw e; + } } else if (parent instanceof PDOMCPPNamespace) { FindBinding visitor = new FindBinding(pdom, binding.getNameCharArray(), getBindingType(binding)); ((PDOMCPPNamespace)parent).getIndex().accept(visitor); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java index 9cf48c44724..8da95d4c6c4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethod.java @@ -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.ICPPParameter; 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.PDOMNotImplementedError; import org.eclipse.core.runtime.CoreException; @@ -37,12 +37,12 @@ import org.eclipse.core.runtime.CoreException; * @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 FIRST_PARAM = PDOMMember.RECORD_SIZE + 4; + public static final int NUM_PARAMS = PDOMBinding.RECORD_SIZE + 0; + 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 { super(pdom, parent, name); @@ -165,7 +165,7 @@ public class PDOMCPPMethod extends PDOMMember implements ICPPMethod, ICPPFunctio public ICPPClassType getClassOwner() throws DOMException { try { - return (ICPPClassType)getMemberOwner(); + return (ICPPClassType)getParentNode(); } catch (CoreException e) { CCorePlugin.log(e); return null; @@ -205,4 +205,4 @@ public class PDOMCPPMethod extends PDOMMember implements ICPPMethod, ICPPFunctio return false; } -} +} \ No newline at end of file