--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core.util;
+
+import java.util.ArrayList;
+
+import net.sourceforge.phpdt.core.IField;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMethod;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.compiler.CharOperation;
+import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
+import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
+import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope;
+import net.sourceforge.phpdt.internal.core.SourceType;
+import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode;
+import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.Argument;
+import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration;
+import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference;
+
+/**
+ * Finds an ASTNode given an IJavaElement in a CompilationUnitDeclaration
+ */
+public class ASTNodeFinder {
+ private CompilationUnitDeclaration unit;
+
+ public ASTNodeFinder(CompilationUnitDeclaration unit) {
+ this.unit = unit;
+ }
+
+ /*
+ * Finds the FieldDeclaration in the given ast corresponding to the given field handle.
+ * Returns null if not found.
+ */
+ public FieldDeclaration findField(IField fieldHandle) {
+ TypeDeclaration typeDecl = findType((IType)fieldHandle.getParent());
+ if (typeDecl == null) return null;
+ FieldDeclaration[] fields = typeDecl.fields;
+ if (fields != null) {
+ char[] fieldName = fieldHandle.getElementName().toCharArray();
+ for (int i = 0, length = fields.length; i < length; i++) {
+ FieldDeclaration field = fields[i];
+ if (CharOperation.equals(fieldName, field.name)) {
+ return field;
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ * Finds the Initializer in the given ast corresponding to the given initializer handle.
+ * Returns null if not found.
+ */
+// public Initializer findInitializer(IInitializer initializerHandle) {
+// TypeDeclaration typeDecl = findType((IType)initializerHandle.getParent());
+// if (typeDecl == null) return null;
+// FieldDeclaration[] fields = typeDecl.fields;
+// if (fields != null) {
+// int occurenceCount = ((JavaElement)initializerHandle).occurrenceCount;
+// for (int i = 0, length = fields.length; i < length; i++) {
+// FieldDeclaration field = fields[i];
+// if (field instanceof Initializer && --occurenceCount == 0) {
+// return (Initializer)field;
+// }
+// }
+// }
+// return null;
+// }
+
+ /*
+ * Finds the AbstractMethodDeclaration in the given ast corresponding to the given method handle.
+ * Returns null if not found.
+ */
+ public AbstractMethodDeclaration findMethod(IMethod methodHandle) {
+ TypeDeclaration typeDecl = findType((IType)methodHandle.getParent());
+ if (typeDecl == null) return null;
+ AbstractMethodDeclaration[] methods = typeDecl.methods;
+ if (methods != null) {
+ char[] selector = methodHandle.getElementName().toCharArray();
+ String[] parameterTypeSignatures = methodHandle.getParameterTypes();
+ int parameterCount = parameterTypeSignatures.length;
+ nextMethod: for (int i = 0, length = methods.length; i < length; i++) {
+ AbstractMethodDeclaration method = methods[i];
+ if (CharOperation.equals(selector, method.selector)) {
+ Argument[] args = method.arguments;
+ int argsLength = args == null ? 0 : args.length;
+ if (argsLength == parameterCount) {
+ for (int j = 0; j < parameterCount; j++) {
+ TypeReference type = args[j].type;
+ String signature = Util.typeSignature(type);
+ if (!signature.equals(parameterTypeSignatures[j])) {
+ continue nextMethod;
+ }
+ }
+ return method;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /*
+ * Finds the TypeDeclaration in the given ast corresponding to the given type handle.
+ * Returns null if not found.
+ */
+ public TypeDeclaration findType(IType typeHandle) {
+ IJavaElement parent = typeHandle.getParent();
+ final char[] typeName = typeHandle.getElementName().toCharArray();
+// final int occurenceCount = ((SourceType)typeHandle).occurrenceCount;
+ final boolean findAnonymous = typeName.length == 0;
+ class Visitor extends ASTVisitor {
+ TypeDeclaration result;
+ int count = 0;
+ public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
+ if (result != null) return false;
+// if ((typeDeclaration.bits & ASTNode.IsAnonymousTypeMASK) != 0) {
+// if (findAnonymous && ++count == occurenceCount) {
+// result = typeDeclaration;
+// }
+// } else {
+ if (!findAnonymous && CharOperation.equals(typeName, typeDeclaration.name)) {
+ result = typeDeclaration;
+ }
+// }
+ return false; // visit only one level
+ }
+ }
+ switch (parent.getElementType()) {
+ case IJavaElement.COMPILATION_UNIT:
+ ArrayList types = this.unit.types;
+ if (types != null) {
+ for (int i = 0, length = types.size(); i < length; i++) {
+ TypeDeclaration type = (TypeDeclaration)types.get(i);//[i];
+ if (CharOperation.equals(typeName, type.name)) {
+ return type;
+ }
+ }
+ }
+ break;
+ case IJavaElement.TYPE:
+ TypeDeclaration parentDecl = findType((IType)parent);
+ if (parentDecl == null) return null;
+// types = parentDecl.memberTypes;
+// if (types != null) {
+// for (int i = 0, length = types.length; i < length; i++) {
+// TypeDeclaration type = types[i];
+// if (CharOperation.equals(typeName, type.name)) {
+// return type;
+// }
+// }
+// }
+ break;
+ case IJavaElement.FIELD:
+ FieldDeclaration fieldDecl = findField((IField)parent);
+ if (fieldDecl == null) return null;
+ Visitor visitor = new Visitor();
+ fieldDecl.traverse(visitor, null);
+ return visitor.result;
+// case IJavaElement.INITIALIZER:
+// Initializer initializer = findInitializer((IInitializer)parent);
+// if (initializer == null) return null;
+// visitor = new Visitor();
+// initializer.traverse(visitor, null);
+// return visitor.result;
+ case IJavaElement.METHOD:
+ AbstractMethodDeclaration methodDecl = findMethod((IMethod)parent);
+ if (methodDecl == null) return null;
+ visitor = new Visitor();
+ methodDecl.traverse(visitor, (ClassScope)null);
+ return visitor.result;
+ }
+ return null;
+ }
+}