4c10a87c14c569dd5e79440a552c7bc04c87739f
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / util / ASTNodeFinder.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core.util;
12
13 import java.util.ArrayList;
14
15 import net.sourceforge.phpdt.core.IField;
16 import net.sourceforge.phpdt.core.IJavaElement;
17 import net.sourceforge.phpdt.core.IMethod;
18 import net.sourceforge.phpdt.core.IType;
19 import net.sourceforge.phpdt.core.compiler.CharOperation;
20 import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
21 import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
22 import net.sourceforge.phpdt.internal.compiler.ast.Argument;
23 import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration;
24 import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration;
25 import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration;
26 import net.sourceforge.phpdt.internal.compiler.ast.TypeReference;
27 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
28 import net.sourceforge.phpdt.internal.compiler.lookup.ClassScope;
29
30 /**
31  * Finds an ASTNode given an IJavaElement in a CompilationUnitDeclaration
32  */
33 public class ASTNodeFinder {
34         private CompilationUnitDeclaration unit;
35
36         public ASTNodeFinder(CompilationUnitDeclaration unit) {
37                 this.unit = unit;
38         }
39
40         /*
41          * Finds the FieldDeclaration in the given ast corresponding to the given
42          * field handle. Returns null if not found.
43          */
44         public FieldDeclaration findField(IField fieldHandle) {
45                 TypeDeclaration typeDecl = findType((IType) fieldHandle.getParent());
46                 if (typeDecl == null)
47                         return null;
48                 FieldDeclaration[] fields = typeDecl.fields;
49                 if (fields != null) {
50                         char[] fieldName = fieldHandle.getElementName().toCharArray();
51                         for (int i = 0, length = fields.length; i < length; i++) {
52                                 FieldDeclaration field = fields[i];
53                                 if (CharOperation.equals(fieldName, field.name)) {
54                                         return field;
55                                 }
56                         }
57                 }
58                 return null;
59         }
60
61         /*
62          * Finds the Initializer in the given ast corresponding to the given
63          * initializer handle. Returns null if not found.
64          */
65         // public Initializer findInitializer(IInitializer initializerHandle) {
66         // TypeDeclaration typeDecl =
67         // findType((IType)initializerHandle.getParent());
68         // if (typeDecl == null) return null;
69         // FieldDeclaration[] fields = typeDecl.fields;
70         // if (fields != null) {
71         // int occurenceCount = ((JavaElement)initializerHandle).occurrenceCount;
72         // for (int i = 0, length = fields.length; i < length; i++) {
73         // FieldDeclaration field = fields[i];
74         // if (field instanceof Initializer && --occurenceCount == 0) {
75         // return (Initializer)field;
76         // }
77         // }
78         // }
79         // return null;
80         // }
81         /*
82          * Finds the AbstractMethodDeclaration in the given ast corresponding to the
83          * given method handle. Returns null if not found.
84          */
85         public AbstractMethodDeclaration findMethod(IMethod methodHandle) {
86                 TypeDeclaration typeDecl = findType((IType) methodHandle.getParent());
87                 if (typeDecl == null)
88                         return null;
89                 AbstractMethodDeclaration[] methods = typeDecl.methods;
90                 if (methods != null) {
91                         char[] selector = methodHandle.getElementName().toCharArray();
92                         String[] parameterTypeSignatures = methodHandle.getParameterTypes();
93                         int parameterCount = parameterTypeSignatures.length;
94                         nextMethod: for (int i = 0, length = methods.length; i < length; i++) {
95                                 AbstractMethodDeclaration method = methods[i];
96                                 if (CharOperation.equals(selector, method.selector)) {
97                                         Argument[] args = method.arguments;
98                                         int argsLength = args == null ? 0 : args.length;
99                                         if (argsLength == parameterCount) {
100                                                 for (int j = 0; j < parameterCount; j++) {
101                                                         TypeReference type = args[j].type;
102                                                         String signature = Util.typeSignature(type);
103                                                         if (!signature.equals(parameterTypeSignatures[j])) {
104                                                                 continue nextMethod;
105                                                         }
106                                                 }
107                                                 return method;
108                                         }
109                                 }
110                         }
111                 }
112                 return null;
113         }
114
115         /*
116          * Finds the TypeDeclaration in the given ast corresponding to the given
117          * type handle. Returns null if not found.
118          */
119         public TypeDeclaration findType(IType typeHandle) {
120                 IJavaElement parent = typeHandle.getParent();
121                 final char[] typeName = typeHandle.getElementName().toCharArray();
122                 // final int occurenceCount = ((SourceType)typeHandle).occurrenceCount;
123                 final boolean findAnonymous = typeName.length == 0;
124                 class Visitor extends ASTVisitor {
125                         TypeDeclaration result;
126
127                         int count = 0;
128
129                         public boolean visit(TypeDeclaration typeDeclaration,
130                                         BlockScope scope) {
131                                 if (result != null)
132                                         return false;
133                                 // if ((typeDeclaration.bits & ASTNode.IsAnonymousTypeMASK) !=
134                                 // 0) {
135                                 // if (findAnonymous && ++count == occurenceCount) {
136                                 // result = typeDeclaration;
137                                 // }
138                                 // } else {
139                                 if (!findAnonymous
140                                                 && CharOperation.equals(typeName, typeDeclaration.name)) {
141                                         result = typeDeclaration;
142                                 }
143                                 // }
144                                 return false; // visit only one level
145                         }
146                 }
147                 switch (parent.getElementType()) {
148                 case IJavaElement.COMPILATION_UNIT:
149                         ArrayList types = this.unit.types;
150                         if (types != null) {
151                                 for (int i = 0, length = types.size(); i < length; i++) {
152                                         TypeDeclaration type = (TypeDeclaration) types.get(i);// [i];
153                                         if (CharOperation.equals(typeName, type.name)) {
154                                                 return type;
155                                         }
156                                 }
157                         }
158                         break;
159                 case IJavaElement.TYPE:
160                         TypeDeclaration parentDecl = findType((IType) parent);
161                         if (parentDecl == null)
162                                 return null;
163                         // types = parentDecl.memberTypes;
164                         // if (types != null) {
165                         // for (int i = 0, length = types.length; i < length; i++) {
166                         // TypeDeclaration type = types[i];
167                         // if (CharOperation.equals(typeName, type.name)) {
168                         // return type;
169                         // }
170                         // }
171                         // }
172                         break;
173                 case IJavaElement.FIELD:
174                         FieldDeclaration fieldDecl = findField((IField) parent);
175                         if (fieldDecl == null)
176                                 return null;
177                         Visitor visitor = new Visitor();
178                         fieldDecl.traverse(visitor, null);
179                         return visitor.result;
180                         // case IJavaElement.INITIALIZER:
181                         // Initializer initializer = findInitializer((IInitializer)parent);
182                         // if (initializer == null) return null;
183                         // visitor = new Visitor();
184                         // initializer.traverse(visitor, null);
185                         // return visitor.result;
186                 case IJavaElement.METHOD:
187                         AbstractMethodDeclaration methodDecl = findMethod((IMethod) parent);
188                         if (methodDecl == null)
189                                 return null;
190                         visitor = new Visitor();
191                         methodDecl.traverse(visitor, (ClassScope) null);
192                         return visitor.result;
193                 }
194                 return null;
195         }
196 }