001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.core;
011:
012: import org.eclipse.jdt.core.*;
013: import org.eclipse.jdt.core.compiler.CharOperation;
014: import org.eclipse.jdt.internal.compiler.lookup.Binding;
015: import org.eclipse.jdt.internal.core.util.Util;
016:
017: /**
018: * @see IMethod
019: */
020:
021: public class SourceMethod extends NamedMember implements IMethod {
022:
023: /**
024: * The parameter type signatures of the method - stored locally
025: * to perform equality test. <code>null</code> indicates no
026: * parameters.
027: */
028: protected String[] parameterTypes;
029:
030: protected SourceMethod(JavaElement parent, String name,
031: String[] parameterTypes) {
032: super (parent, name);
033: // Assertion disabled since bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=179011
034: // Assert.isTrue(name.indexOf('.') == -1);
035: if (parameterTypes == null) {
036: this .parameterTypes = CharOperation.NO_STRINGS;
037: } else {
038: this .parameterTypes = parameterTypes;
039: }
040: }
041:
042: protected void closing(Object info) throws JavaModelException {
043: super .closing(info);
044: SourceMethodElementInfo elementInfo = (SourceMethodElementInfo) info;
045: ITypeParameter[] typeParameters = elementInfo.typeParameters;
046: for (int i = 0, length = typeParameters.length; i < length; i++) {
047: ((TypeParameter) typeParameters[i]).close();
048: }
049: }
050:
051: public boolean equals(Object o) {
052: if (!(o instanceof SourceMethod))
053: return false;
054: return super .equals(o)
055: && Util.equalArraysOrNull(this .parameterTypes,
056: ((SourceMethod) o).parameterTypes);
057: }
058:
059: /**
060: * @see IJavaElement
061: */
062: public int getElementType() {
063: return METHOD;
064: }
065:
066: /**
067: * @see IMethod
068: */
069: public String[] getExceptionTypes() throws JavaModelException {
070: SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
071: char[][] exs = info.getExceptionTypeNames();
072: return CompilationUnitStructureRequestor
073: .convertTypeNamesToSigs(exs);
074: }
075:
076: /**
077: * @see JavaElement#getHandleMemento(StringBuffer)
078: */
079: protected void getHandleMemento(StringBuffer buff) {
080: ((JavaElement) getParent()).getHandleMemento(buff);
081: char delimiter = getHandleMementoDelimiter();
082: buff.append(delimiter);
083: escapeMementoName(buff, getElementName());
084: for (int i = 0; i < this .parameterTypes.length; i++) {
085: buff.append(delimiter);
086: escapeMementoName(buff, this .parameterTypes[i]);
087: }
088: if (this .occurrenceCount > 1) {
089: buff.append(JEM_COUNT);
090: buff.append(this .occurrenceCount);
091: }
092: }
093:
094: /**
095: * @see JavaElement#getHandleMemento()
096: */
097: protected char getHandleMementoDelimiter() {
098: return JavaElement.JEM_METHOD;
099: }
100:
101: /* (non-Javadoc)
102: * @see org.eclipse.jdt.core.IMethod#getKey()
103: */
104: public String getKey() {
105: try {
106: return getKey(this , false/*don't open*/);
107: } catch (JavaModelException e) {
108: // happen only if force open is true
109: return null;
110: }
111: }
112:
113: /**
114: * @see IMethod
115: */
116: public int getNumberOfParameters() {
117: return this .parameterTypes == null ? 0
118: : this .parameterTypes.length;
119: }
120:
121: /**
122: * @see IMethod
123: */
124: public String[] getParameterNames() throws JavaModelException {
125: SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
126: char[][] names = info.getArgumentNames();
127: return CharOperation.toStrings(names);
128: }
129:
130: /**
131: * @see IMethod
132: */
133: public String[] getParameterTypes() {
134: return this .parameterTypes;
135: }
136:
137: public ITypeParameter getTypeParameter(String typeParameterName) {
138: return new TypeParameter(this , typeParameterName);
139: }
140:
141: public ITypeParameter[] getTypeParameters()
142: throws JavaModelException {
143: SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
144: return info.typeParameters;
145: }
146:
147: /**
148: * @see IMethod#getTypeParameterSignatures()
149: * @since 3.0
150: * @deprecated
151: */
152: public String[] getTypeParameterSignatures()
153: throws JavaModelException {
154: ITypeParameter[] typeParameters = getTypeParameters();
155: int length = typeParameters.length;
156: String[] typeParameterSignatures = new String[length];
157: for (int i = 0; i < length; i++) {
158: TypeParameter typeParameter = (TypeParameter) typeParameters[i];
159: TypeParameterElementInfo info = (TypeParameterElementInfo) typeParameter
160: .getElementInfo();
161: char[][] bounds = info.bounds;
162: if (bounds == null) {
163: typeParameterSignatures[i] = Signature
164: .createTypeParameterSignature(typeParameter
165: .getElementName(),
166: CharOperation.NO_STRINGS);
167: } else {
168: int boundsLength = bounds.length;
169: char[][] boundSignatures = new char[boundsLength][];
170: for (int j = 0; j < boundsLength; j++) {
171: boundSignatures[j] = Signature
172: .createCharArrayTypeSignature(bounds[j],
173: false);
174: }
175: typeParameterSignatures[i] = new String(Signature
176: .createTypeParameterSignature(typeParameter
177: .getElementName().toCharArray(),
178: boundSignatures));
179: }
180: }
181: return typeParameterSignatures;
182: }
183:
184: /*
185: * @see JavaElement#getPrimaryElement(boolean)
186: */
187: public IJavaElement getPrimaryElement(boolean checkOwner) {
188: if (checkOwner) {
189: CompilationUnit cu = (CompilationUnit) getAncestor(COMPILATION_UNIT);
190: if (cu.isPrimary())
191: return this ;
192: }
193: IJavaElement primaryParent = this .parent
194: .getPrimaryElement(false);
195: return ((IType) primaryParent).getMethod(this .name,
196: this .parameterTypes);
197: }
198:
199: public String[] getRawParameterNames() throws JavaModelException {
200: return getParameterNames();
201: }
202:
203: /**
204: * @see IMethod
205: */
206: public String getReturnType() throws JavaModelException {
207: SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
208: return Signature.createTypeSignature(info.getReturnTypeName(),
209: false);
210: }
211:
212: /**
213: * @see IMethod
214: */
215: public String getSignature() throws JavaModelException {
216: SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
217: return Signature.createMethodSignature(this .parameterTypes,
218: Signature.createTypeSignature(info.getReturnTypeName(),
219: false));
220: }
221:
222: /**
223: * @see org.eclipse.jdt.internal.core.JavaElement#hashCode()
224: */
225: public int hashCode() {
226: int hash = super .hashCode();
227: for (int i = 0, length = this .parameterTypes.length; i < length; i++) {
228: hash = Util.combineHashCodes(hash, this .parameterTypes[i]
229: .hashCode());
230: }
231: return hash;
232: }
233:
234: /**
235: * @see IMethod
236: */
237: public boolean isConstructor() throws JavaModelException {
238: if (!this .getElementName().equals(this .parent.getElementName())) {
239: // faster than reaching the info
240: return false;
241: }
242: SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
243: return info.isConstructor();
244: }
245:
246: /**
247: * @see IMethod#isMainMethod()
248: */
249: public boolean isMainMethod() throws JavaModelException {
250: return this .isMainMethod(this );
251: }
252:
253: /* (non-Javadoc)
254: * @see org.eclipse.jdt.core.IMethod#isResolved()
255: */
256: public boolean isResolved() {
257: return false;
258: }
259:
260: /**
261: * @see IMethod#isSimilar(IMethod)
262: */
263: public boolean isSimilar(IMethod method) {
264: return areSimilarMethods(this .getElementName(), this
265: .getParameterTypes(), method.getElementName(), method
266: .getParameterTypes(), null);
267: }
268:
269: /**
270: */
271: public String readableName() {
272:
273: StringBuffer buffer = new StringBuffer(super .readableName());
274: buffer.append('(');
275: int length;
276: if (this .parameterTypes != null
277: && (length = this .parameterTypes.length) > 0) {
278: for (int i = 0; i < length; i++) {
279: buffer.append(Signature
280: .toString(this .parameterTypes[i]));
281: if (i < length - 1) {
282: buffer.append(", "); //$NON-NLS-1$
283: }
284: }
285: }
286: buffer.append(')');
287: return buffer.toString();
288: }
289:
290: public JavaElement resolved(Binding binding) {
291: SourceRefElement resolvedHandle = new ResolvedSourceMethod(
292: this .parent, this .name, this .parameterTypes,
293: new String(binding.computeUniqueKey()));
294: resolvedHandle.occurrenceCount = this .occurrenceCount;
295: return resolvedHandle;
296: }
297:
298: /**
299: * @private Debugging purposes
300: */
301: protected void toStringInfo(int tab, StringBuffer buffer,
302: Object info, boolean showResolvedInfo) {
303: buffer.append(tabString(tab));
304: if (info == null) {
305: toStringName(buffer);
306: buffer.append(" (not open)"); //$NON-NLS-1$
307: } else if (info == NO_INFO) {
308: toStringName(buffer);
309: } else {
310: SourceMethodElementInfo methodInfo = (SourceMethodElementInfo) info;
311: int flags = methodInfo.getModifiers();
312: if (Flags.isStatic(flags)) {
313: buffer.append("static "); //$NON-NLS-1$
314: }
315: if (!methodInfo.isConstructor()) {
316: buffer.append(methodInfo.getReturnTypeName());
317: buffer.append(' ');
318: }
319: toStringName(buffer, flags);
320: }
321: }
322:
323: protected void toStringName(StringBuffer buffer) {
324: toStringName(buffer, 0);
325: }
326:
327: protected void toStringName(StringBuffer buffer, int flags) {
328: buffer.append(getElementName());
329: buffer.append('(');
330: String[] parameters = getParameterTypes();
331: int length;
332: if (parameters != null && (length = parameters.length) > 0) {
333: boolean isVarargs = Flags.isVarargs(flags);
334: for (int i = 0; i < length; i++) {
335: try {
336: if (i < length - 1) {
337: buffer
338: .append(Signature
339: .toString(parameters[i]));
340: buffer.append(", "); //$NON-NLS-1$
341: } else if (isVarargs) {
342: // remove array from signature
343: String parameter = parameters[i].substring(1);
344: buffer.append(Signature.toString(parameter));
345: buffer.append(" ..."); //$NON-NLS-1$
346: } else {
347: buffer
348: .append(Signature
349: .toString(parameters[i]));
350: }
351: } catch (IllegalArgumentException e) {
352: // parameter signature is malformed
353: buffer.append("*** invalid signature: "); //$NON-NLS-1$
354: buffer.append(parameters[i]);
355: }
356: }
357: }
358: buffer.append(')');
359: if (this .occurrenceCount > 1) {
360: buffer.append("#"); //$NON-NLS-1$
361: buffer.append(this.occurrenceCount);
362: }
363: }
364: }
|