improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / Member.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 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;
12
13 import java.util.ArrayList;
14
15 import net.sourceforge.phpdt.internal.core.SourceType;
16
17 import net.sourceforge.phpdt.core.Flags;
18 import net.sourceforge.phpdt.core.IJavaElement;
19 import net.sourceforge.phpdt.core.IMember;
20 import net.sourceforge.phpdt.core.IMethod;
21 import net.sourceforge.phpdt.core.ISourceRange;
22 import net.sourceforge.phpdt.core.IType;
23 import net.sourceforge.phpdt.core.JavaModelException;
24 import net.sourceforge.phpdt.core.Signature;
25 import net.sourceforge.phpdt.core.jdom.IDOMNode;
26
27
28 /**
29  * @see IMember
30  */
31
32 public abstract class Member extends SourceRefElement implements IMember {
33         protected Member(JavaElement parent, String name) {
34                 super(parent, name);
35         }
36 protected boolean areSimilarMethods(
37         String name1, String[] params1, 
38         String name2, String[] params2,
39         String[] simpleNames1) {
40                 
41         if (name1.equals(name2)) {
42                 int params1Length = params1.length;
43                 if (params1Length == params2.length) {
44                         for (int i = 0; i < params1Length; i++) {
45                                 String simpleName1 = 
46                                         simpleNames1 == null ? 
47                                                 Signature.getSimpleName(Signature.toString(params1[i])) :
48                                                 simpleNames1[i];
49                                 String simpleName2 = Signature.getSimpleName(Signature.toString(params2[i]));
50                                 if (!simpleName1.equals(simpleName2)) {
51                                         return false;
52                                 }
53                         }
54                         return true;
55                 }
56         }
57         return false;
58 }
59 /**
60  * Converts a field constant from the compiler's representation
61  * to the Java Model constant representation (Number or String).
62  */
63 //protected static Object convertConstant(Constant constant) {
64 //      if (constant == null)
65 //              return null;
66 //      if (constant == Constant.NotAConstant) {
67 //              return null;
68 //      }
69 //      switch (constant.typeID()) {
70 //              case TypeIds.T_boolean :
71 //                      return constant.booleanValue() ? Boolean.TRUE : Boolean.FALSE;
72 //              case TypeIds.T_byte :
73 //                      return new Byte(constant.byteValue());
74 //              case TypeIds.T_char :
75 //                      return new Character(constant.charValue());
76 //              case TypeIds.T_double :
77 //                      return new Double(constant.doubleValue());
78 //              case TypeIds.T_float :
79 //                      return new Float(constant.floatValue());
80 //              case TypeIds.T_int :
81 //                      return new Integer(constant.intValue());
82 //              case TypeIds.T_long :
83 //                      return new Long(constant.longValue());
84 //              case TypeIds.T_short :
85 //                      return new Short(constant.shortValue());
86 //              case TypeIds.T_String :
87 //                      return constant.stringValue();
88 //              default :
89 //                      return null;
90 //      }
91 //}
92 /**
93  * @see JavaElement#equalsDOMNode
94  */
95 protected boolean equalsDOMNode(IDOMNode node) throws JavaModelException {
96         return getElementName().equals(node.getName());
97 }
98 /*
99  * Helper method for SourceType.findMethods and BinaryType.findMethods
100  */
101 protected IMethod[] findMethods(IMethod method, IMethod[] methods) {
102         String elementName = method.getElementName();
103         String[] parameters = method.getParameterTypes();
104         int paramLength = parameters.length;
105         String[] simpleNames = new String[paramLength];
106         for (int i = 0; i < paramLength; i++) {
107                 simpleNames[i] = Signature.getSimpleName(Signature.toString(parameters[i]));
108         }
109         ArrayList list = new ArrayList();
110         next: for (int i = 0, length = methods.length; i < length; i++) {
111                 IMethod existingMethod = methods[i];
112                 if (this.areSimilarMethods(
113                                 elementName,
114                                 parameters,
115                                 existingMethod.getElementName(),
116                                 existingMethod.getParameterTypes(),
117                                 simpleNames)) {
118                         list.add(existingMethod);
119                 }
120         }
121         int size = list.size();
122         if (size == 0) {
123                 return null;
124         } else {
125                 IMethod[] result = new IMethod[size];
126                 list.toArray(result);
127                 return result;
128         }
129 }
130 /**
131  * @see IMember
132  */
133 //public IClassFile getClassFile() {
134 //      return ((JavaElement)getParent()).getClassFile();
135 //}
136 /**
137  * @see IMember
138  */
139 public IType getDeclaringType() {
140         JavaElement parentElement = (JavaElement)getParent();
141         if (parentElement.getElementType() == TYPE) {
142                 return (IType) parentElement;
143         }
144         return null;
145 }
146 /**
147  * @see IMember
148  */
149 public int getFlags() throws JavaModelException {
150         MemberElementInfo info = (MemberElementInfo) getElementInfo();
151         return info.getModifiers();
152 }
153 /**
154  * @see JavaElement#getHandleMemento()
155  */
156 protected char getHandleMementoDelimiter() {
157         return JavaElement.JEM_TYPE;
158 }
159 /*
160  * Returns the outermost context defining a local element. Per construction, it can only be a
161  * method/field/initializarer member; thus, returns null if this member is already a top-level type or member type.
162  * e.g for X.java/X/Y/foo()/Z/bar()/T, it will return X.java/X/Y/foo()
163  */
164 public Member getOuterMostLocalContext() {
165         IJavaElement current = this;
166         Member lastLocalContext = null;
167         parentLoop: while (true) {
168                 switch (current.getElementType()) {
169                         case CLASS_FILE:
170                         case COMPILATION_UNIT:
171                                 break parentLoop; // done recursing
172                         case TYPE:
173                                 // cannot be a local context
174                                 break;
175                         case INITIALIZER:
176                         case FIELD:
177                         case METHOD:
178                                  // these elements can define local members
179                                 lastLocalContext = (Member) current;
180                                 break;
181                 }               
182                 current = current.getParent();
183         } 
184         return lastLocalContext;
185 }
186 /**
187  * @see IMember
188  */
189 public ISourceRange getNameRange() throws JavaModelException {
190         MemberElementInfo info= (MemberElementInfo)getElementInfo();
191         return new SourceRange(info.getNameSourceStart(), info.getNameSourceEnd() - info.getNameSourceStart() + 1);
192 }
193 /**
194  * @see IMember
195  */
196 public IType getType(String typeName, int count) {
197         if (isBinary()) {
198                 throw new IllegalArgumentException("Not a source member " + toStringWithAncestors()); //$NON-NLS-1$
199         } else {
200                 SourceType type = new SourceType(this, typeName);
201                 type.occurrenceCount = count;
202                 return type;
203         }
204 }
205 /**
206  * @see IMember
207  */
208 public boolean isBinary() {
209         return false;
210 }
211 protected boolean isMainMethod(IMethod method) throws JavaModelException {
212         if ("main".equals(method.getElementName()) && Signature.SIG_VOID.equals(method.getReturnType())) { //$NON-NLS-1$
213                 int flags= method.getFlags();
214                 if (Flags.isStatic(flags) && Flags.isPublic(flags)) {
215                         String[] paramTypes= method.getParameterTypes();
216                         if (paramTypes.length == 1) {
217                                 String name=  Signature.toString(paramTypes[0]);
218                                 return "String[]".equals(Signature.getSimpleName(name)); //$NON-NLS-1$
219                         }
220                 }
221         }
222         return false;
223 }
224 /**
225  * @see IJavaElement
226  */
227 public boolean isReadOnly() {
228         return false; //getClassFile() != null;
229 }
230 /**
231  */
232 public String readableName() {
233
234         IJavaElement declaringType = getDeclaringType();
235         if (declaringType != null) {
236                 String declaringName = ((JavaElement) getDeclaringType()).readableName();
237                 StringBuffer buffer = new StringBuffer(declaringName);
238                 buffer.append('.');
239                 buffer.append(this.getElementName());
240                 return buffer.toString();
241         } else {
242                 return super.readableName();
243         }
244 }
245 /**
246  * Updates the name range for this element.
247  */
248 protected void updateNameRange(int nameStart, int nameEnd) {
249         try {
250                 MemberElementInfo info = (MemberElementInfo) getElementInfo();
251                 info.setNameSourceStart(nameStart);
252                 info.setNameSourceEnd(nameEnd);
253         } catch (JavaModelException npe) {
254                 return;
255         }
256 }
257 }