| /******************************************************************************* |
| * Copyright (c) 2000, 2014 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.core; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.jdt.core.Flags; |
| import org.eclipse.jdt.core.IAnnotation; |
| import org.eclipse.jdt.core.ILocalVariable; |
| import org.eclipse.jdt.core.IMemberValuePair; |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.ITypeParameter; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.Signature; |
| import org.eclipse.jdt.core.compiler.CharOperation; |
| import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; |
| import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation; |
| import org.eclipse.jdt.internal.compiler.env.IBinaryMethod; |
| import org.eclipse.jdt.internal.compiler.env.IBinaryType; |
| import org.eclipse.jdt.internal.compiler.lookup.Binding; |
| import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; |
| import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo; |
| import org.eclipse.jdt.internal.core.util.Util; |
| |
| /** |
| * @see IMethod |
| */ |
| |
| /* package */ class BinaryMethod extends BinaryMember implements IMethod { |
| /** |
| * The parameter type signatures of the method - stored locally |
| * to perform equality test. <code>CharOperation.NO_STRINGS</code> indicates no |
| * parameters. |
| */ |
| protected String[] parameterTypes; |
| protected String [] erasedParamaterTypes; // lazily initialized via call to getErasedParameterTypes |
| |
| /** |
| * The parameter names for the method. |
| */ |
| protected String[] parameterNames; |
| |
| protected String[] exceptionTypes; |
| protected String returnType; |
| |
| protected BinaryMethod(JavaElement parent, String name, String[] paramTypes) { |
| super(parent, name); |
| // Assertion disabled since bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=179011 |
| // Assert.isTrue(name.indexOf('.') == -1); |
| if (paramTypes == null) { |
| this.parameterTypes= CharOperation.NO_STRINGS; |
| } else { |
| this.parameterTypes= paramTypes; |
| } |
| } |
| public boolean equals(Object o) { |
| if (!(o instanceof BinaryMethod)) return false; |
| return super.equals(o) && Util.equalArraysOrNull(getErasedParameterTypes(), ((BinaryMethod)o).getErasedParameterTypes()); |
| } |
| public IAnnotation[] getAnnotations() throws JavaModelException { |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| IBinaryAnnotation[] binaryAnnotations = info.getAnnotations(); |
| return getAnnotations(binaryAnnotations, info.getTagBits()); |
| } |
| public ILocalVariable[] getParameters() throws JavaModelException { |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| int length = this.parameterTypes.length; |
| if (length == 0) { |
| return LocalVariable.NO_LOCAL_VARIABLES; |
| } |
| ILocalVariable[] localVariables = new ILocalVariable[length]; |
| char[][] argumentNames = info.getArgumentNames(); |
| if (argumentNames == null || argumentNames.length < length) { |
| argumentNames = new char[length][]; |
| for (int j = 0; j < length; j++) { |
| argumentNames[j] = ("arg" + j).toCharArray(); //$NON-NLS-1$ |
| } |
| } |
| int startIndex = 0; |
| try { |
| if (isConstructor()) { |
| IType declaringType = this.getDeclaringType(); |
| if (declaringType.isEnum()) { |
| startIndex = 2; |
| } else if (declaringType.isMember() |
| && !Flags.isStatic(declaringType.getFlags())) { |
| startIndex = 1; |
| } |
| } |
| } catch(JavaModelException e) { |
| // ignore |
| } |
| for (int i= 0; i < length; i++) { |
| if (i < startIndex) { |
| LocalVariable localVariable = new LocalVariable( |
| this, |
| new String(argumentNames[i]), |
| 0, |
| -1, |
| 0, |
| -1, |
| this.parameterTypes[i], |
| null, |
| -1, |
| true); |
| localVariables[i] = localVariable; |
| localVariable.annotations = Annotation.NO_ANNOTATIONS; |
| } else { |
| LocalVariable localVariable = new LocalVariable( |
| this, |
| new String(argumentNames[i]), |
| 0, |
| -1, |
| 0, |
| -1, |
| this.parameterTypes[i], |
| null, |
| -1, |
| true); |
| localVariables[i] = localVariable; |
| IAnnotation[] annotations = getAnnotations(localVariable, info.getParameterAnnotations(i - startIndex)); |
| localVariable.annotations = annotations; |
| } |
| } |
| return localVariables; |
| } |
| private IAnnotation[] getAnnotations(JavaElement annotationParent, IBinaryAnnotation[] binaryAnnotations) { |
| if (binaryAnnotations == null) return Annotation.NO_ANNOTATIONS; |
| int length = binaryAnnotations.length; |
| IAnnotation[] annotations = new IAnnotation[length]; |
| for (int i = 0; i < length; i++) { |
| annotations[i] = Util.getAnnotation(annotationParent, binaryAnnotations[i], null); |
| } |
| return annotations; |
| } |
| public IMemberValuePair getDefaultValue() throws JavaModelException { |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| Object defaultValue = info.getDefaultValue(); |
| if (defaultValue == null) |
| return null; |
| MemberValuePair memberValuePair = new MemberValuePair(getElementName()); |
| memberValuePair.value = Util.getAnnotationMemberValue(this, memberValuePair, defaultValue); |
| return memberValuePair; |
| } |
| /* |
| * @see IMethod |
| */ |
| public String[] getExceptionTypes() throws JavaModelException { |
| if (this.exceptionTypes == null) { |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| char[] genericSignature = info.getGenericSignature(); |
| if (genericSignature != null) { |
| char[] dotBasedSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.'); |
| this.exceptionTypes = Signature.getThrownExceptionTypes(new String(dotBasedSignature)); |
| } |
| if (this.exceptionTypes == null || this.exceptionTypes.length == 0) { |
| char[][] eTypeNames = info.getExceptionTypeNames(); |
| if (eTypeNames == null || eTypeNames.length == 0) { |
| this.exceptionTypes = CharOperation.NO_STRINGS; |
| } else { |
| eTypeNames = ClassFile.translatedNames(eTypeNames); |
| this.exceptionTypes = new String[eTypeNames.length]; |
| for (int j = 0, length = eTypeNames.length; j < length; j++) { |
| // 1G01HRY: ITPJCORE:WINNT - method.getExceptionType not in correct format |
| int nameLength = eTypeNames[j].length; |
| char[] convertedName = new char[nameLength + 2]; |
| System.arraycopy(eTypeNames[j], 0, convertedName, 1, nameLength); |
| convertedName[0] = 'L'; |
| convertedName[nameLength + 1] = ';'; |
| this.exceptionTypes[j] = new String(convertedName); |
| } |
| } |
| } |
| } |
| return this.exceptionTypes; |
| } |
| /* |
| * @see IJavaElement |
| */ |
| public int getElementType() { |
| return METHOD; |
| } |
| /* |
| * @see IMember |
| */ |
| public int getFlags() throws JavaModelException { |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| int modifiers = info.getModifiers(); |
| if (((IType) this.parent).isInterface() && (modifiers & (ClassFileConstants.AccAbstract | ClassFileConstants.AccStatic)) == 0) |
| modifiers |= ExtraCompilerModifiers.AccDefaultMethod; |
| return modifiers; |
| } |
| /* |
| * @see JavaElement#getHandleMemento(StringBuffer) |
| */ |
| protected void getHandleMemento(StringBuffer buff) { |
| ((JavaElement) getParent()).getHandleMemento(buff); |
| char delimiter = getHandleMementoDelimiter(); |
| buff.append(delimiter); |
| escapeMementoName(buff, getElementName()); |
| for (int i = 0; i < this.parameterTypes.length; i++) { |
| buff.append(delimiter); |
| escapeMementoName(buff, this.parameterTypes[i]); |
| } |
| if (this.occurrenceCount > 1) { |
| buff.append(JEM_COUNT); |
| buff.append(this.occurrenceCount); |
| } |
| } |
| /* |
| * @see JavaElement#getHandleMemento() |
| */ |
| protected char getHandleMementoDelimiter() { |
| return JavaElement.JEM_METHOD; |
| } |
| public String getKey(boolean forceOpen) throws JavaModelException { |
| return getKey(this, forceOpen); |
| } |
| /* |
| * @see IMethod |
| */ |
| public int getNumberOfParameters() { |
| return this.parameterTypes == null ? 0 : this.parameterTypes.length; |
| } |
| /* |
| * @see IMethod |
| * Look for source attachment information to retrieve the actual parameter names as stated in source. |
| */ |
| public String[] getParameterNames() throws JavaModelException { |
| if (this.parameterNames != null) |
| return this.parameterNames; |
| |
| // force source mapping if not already done |
| IType type = (IType) getParent(); |
| SourceMapper mapper = getSourceMapper(); |
| if (mapper != null) { |
| char[][] paramNames = mapper.getMethodParameterNames(this); |
| |
| // map source and try to find parameter names |
| if(paramNames == null) { |
| IBinaryType info = (IBinaryType) ((BinaryType) getDeclaringType()).getElementInfo(); |
| char[] source = mapper.findSource(type, info); |
| if (source != null){ |
| mapper.mapSource(type, source, info); |
| } |
| paramNames = mapper.getMethodParameterNames(this); |
| } |
| |
| // if parameter names exist, convert parameter names to String array |
| if(paramNames != null) { |
| String[] names = new String[paramNames.length]; |
| for (int i = 0; i < paramNames.length; i++) { |
| names[i] = new String(paramNames[i]); |
| } |
| return this.parameterNames = names; |
| } |
| } |
| |
| // try to see if we can retrieve the names from the attached javadoc |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=316937 |
| // Use Signature#getParameterCount() only if the argument names are not already available. |
| int paramCount = Signature.getParameterCount(new String(info.getMethodDescriptor())); |
| if (this.isConstructor()) { |
| final IType declaringType = this.getDeclaringType(); |
| if (declaringType.isMember() |
| && !Flags.isStatic(declaringType.getFlags())) { |
| paramCount--; // remove synthetic argument from constructor param count |
| } |
| } |
| |
| if (paramCount != 0) { |
| // don't try to look for javadoc for synthetic methods |
| int modifiers = getFlags(); |
| if ((modifiers & ClassFileConstants.AccSynthetic) != 0) { |
| return this.parameterNames = getRawParameterNames(paramCount); |
| } |
| JavadocContents javadocContents = null; |
| IType declaringType = getDeclaringType(); |
| PerProjectInfo projectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(getJavaProject().getProject()); |
| synchronized (projectInfo.javadocCache) { |
| javadocContents = (JavadocContents) projectInfo.javadocCache.get(declaringType); |
| if (javadocContents == null) { |
| projectInfo.javadocCache.put(declaringType, BinaryType.EMPTY_JAVADOC); |
| } |
| } |
| |
| String methodDoc = null; |
| if (javadocContents == null) { |
| long timeOut = 50; // default value |
| try { |
| String option = getJavaProject().getOption(JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC, true); |
| if (option != null) { |
| timeOut = Long.parseLong(option); |
| } |
| } catch(NumberFormatException e) { |
| // ignore |
| } |
| if (timeOut == 0) { |
| // don't try to fetch the values and don't cache either (https://bugs.eclipse.org/bugs/show_bug.cgi?id=329671) |
| return getRawParameterNames(paramCount); |
| } |
| final class ParametersNameCollector { |
| String javadoc; |
| public void setJavadoc(String s) { |
| this.javadoc = s; |
| } |
| public String getJavadoc() { |
| return this.javadoc; |
| } |
| } |
| /* |
| * The declaring type is not in the cache yet. The thread wil retrieve the javadoc contents |
| */ |
| final ParametersNameCollector nameCollector = new ParametersNameCollector(); |
| Thread collect = new Thread() { |
| public void run() { |
| try { |
| // this call has a side-effect on the per project info cache |
| nameCollector.setJavadoc(BinaryMethod.this.getAttachedJavadoc(null)); |
| } catch (JavaModelException e) { |
| // ignore |
| } |
| synchronized(nameCollector) { |
| nameCollector.notify(); |
| } |
| } |
| }; |
| collect.start(); |
| synchronized(nameCollector) { |
| try { |
| nameCollector.wait(timeOut); |
| } catch (InterruptedException e) { |
| // ignore |
| } |
| } |
| methodDoc = nameCollector.getJavadoc(); |
| } else if (javadocContents != BinaryType.EMPTY_JAVADOC){ |
| // need to extract the part relative to the binary method since javadoc contains the javadoc for the declaring type |
| try { |
| methodDoc = javadocContents.getMethodDoc(this); |
| } catch(JavaModelException e) { |
| javadocContents = null; |
| } |
| } |
| if (methodDoc != null) { |
| final int indexOfOpenParen = methodDoc.indexOf('('); |
| if (indexOfOpenParen != -1) { |
| final int indexOfClosingParen = methodDoc.indexOf(')', indexOfOpenParen); |
| if (indexOfClosingParen != -1) { |
| final char[] paramsSource = |
| CharOperation.replace( |
| methodDoc.substring(indexOfOpenParen + 1, indexOfClosingParen).toCharArray(), |
| " ".toCharArray(), //$NON-NLS-1$ |
| new char[] {' '}); |
| final char[][] params = splitParameters(paramsSource, paramCount); |
| final int paramsLength = params.length; |
| String[] names = new String[paramsLength]; |
| for (int i = 0; i < paramsLength; i++) { |
| final char[] param = params[i]; |
| int indexOfSpace = CharOperation.lastIndexOf(' ', param); |
| if (indexOfSpace != -1) { |
| names[i] = String.valueOf(param, indexOfSpace + 1, param.length - indexOfSpace -1); |
| } else { |
| names[i] = "arg" + i; //$NON-NLS-1$ |
| } |
| } |
| return this.parameterNames = names; |
| } |
| } |
| } |
| // let's see if we can retrieve them from the debug infos |
| char[][] argumentNames = info.getArgumentNames(); |
| if (argumentNames != null && argumentNames.length == paramCount) { |
| String[] names = new String[paramCount]; |
| for (int i = 0; i < paramCount; i++) { |
| names[i] = new String(argumentNames[i]); |
| } |
| return this.parameterNames = names; |
| } |
| } |
| // If still no parameter names, produce fake ones, but don't cache them (https://bugs.eclipse.org/bugs/show_bug.cgi?id=329671) |
| return getRawParameterNames(paramCount); |
| } |
| private char[][] splitParameters(char[] parametersSource, int paramCount) { |
| // we have generic types as one of the parameter types |
| char[][] params = new char[paramCount][]; |
| int paramIndex = 0; |
| int index = 0; |
| int balance = 0; |
| int length = parametersSource.length; |
| int start = 0; |
| while(index < length) { |
| switch (parametersSource[index]) { |
| case '<': |
| balance++; |
| index++; |
| while(index < length && parametersSource[index] != '>') { |
| index++; |
| } |
| break; |
| case '>' : |
| balance--; |
| index++; |
| break; |
| case ',' : |
| if (balance == 0 && paramIndex < paramCount) { |
| params[paramIndex++] = CharOperation.subarray(parametersSource, start, index); |
| start = index + 1; |
| } |
| index++; |
| break; |
| case '&' : |
| if ((index + 4) < length) { |
| if (parametersSource[index + 1] == 'l' |
| && parametersSource[index + 2] == 't' |
| && parametersSource[index + 3] == ';') { |
| balance++; |
| index += 4; |
| } else if (parametersSource[index + 1] == 'g' |
| && parametersSource[index + 2] == 't' |
| && parametersSource[index + 3] == ';') { |
| balance--; |
| index += 4; |
| } else { |
| index++; |
| } |
| } else { |
| index++; |
| } |
| break; |
| default: |
| index++; |
| } |
| } |
| if (paramIndex < paramCount) { |
| params[paramIndex++] = CharOperation.subarray(parametersSource, start, index); |
| } |
| if (paramIndex != paramCount) { |
| // happens only for constructors with synthetic enclosing type in the signature |
| System.arraycopy(params, 0, (params = new char[paramIndex][]), 0, paramIndex); |
| } |
| return params; |
| } |
| /* |
| * @see IMethod |
| */ |
| public String[] getParameterTypes() { |
| return this.parameterTypes; |
| } |
| |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=299384 |
| private String [] getErasedParameterTypes() { |
| if (this.erasedParamaterTypes == null) { |
| int paramCount = this.parameterTypes.length; |
| String [] erasedTypes = new String [paramCount]; |
| boolean erasureNeeded = false; |
| for (int i = 0; i < paramCount; i++) { |
| String parameterType = this.parameterTypes[i]; |
| if ((erasedTypes[i] = Signature.getTypeErasure(parameterType)) != parameterType) |
| erasureNeeded = true; |
| } |
| this.erasedParamaterTypes = erasureNeeded ? erasedTypes : this.parameterTypes; |
| } |
| return this.erasedParamaterTypes; |
| } |
| private String getErasedParameterType(int index) { |
| return getErasedParameterTypes()[index]; |
| } |
| |
| public ITypeParameter getTypeParameter(String typeParameterName) { |
| return new TypeParameter(this, typeParameterName); |
| } |
| |
| public ITypeParameter[] getTypeParameters() throws JavaModelException { |
| String[] typeParameterSignatures = getTypeParameterSignatures(); |
| int length = typeParameterSignatures.length; |
| if (length == 0) return TypeParameter.NO_TYPE_PARAMETERS; |
| ITypeParameter[] typeParameters = new ITypeParameter[length]; |
| for (int i = 0; i < typeParameterSignatures.length; i++) { |
| String typeParameterName = Signature.getTypeVariable(typeParameterSignatures[i]); |
| typeParameters[i] = new TypeParameter(this, typeParameterName); |
| } |
| return typeParameters; |
| } |
| |
| /** |
| * @see IMethod#getTypeParameterSignatures() |
| * @since 3.0 |
| * @deprecated |
| */ |
| public String[] getTypeParameterSignatures() throws JavaModelException { |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| char[] genericSignature = info.getGenericSignature(); |
| if (genericSignature == null) |
| return CharOperation.NO_STRINGS; |
| char[] dotBasedSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.'); |
| char[][] typeParams = Signature.getTypeParameters(dotBasedSignature); |
| return CharOperation.toStrings(typeParams); |
| } |
| |
| public String[] getRawParameterNames() throws JavaModelException { |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| int paramCount = Signature.getParameterCount(new String(info.getMethodDescriptor())); |
| return getRawParameterNames(paramCount); |
| } |
| private String[] getRawParameterNames(int paramCount) { |
| String[] result = new String[paramCount]; |
| for (int i = 0; i < paramCount; i++) { |
| result[i] = "arg" + i; //$NON-NLS-1$ |
| } |
| return result; |
| } |
| |
| /* |
| * @see IMethod |
| */ |
| public String getReturnType() throws JavaModelException { |
| if (this.returnType == null) { |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| this.returnType = getReturnType(info); |
| } |
| return this.returnType; |
| } |
| private String getReturnType(IBinaryMethod info) { |
| char[] genericSignature = info.getGenericSignature(); |
| char[] signature = genericSignature == null ? info.getMethodDescriptor() : genericSignature; |
| char[] dotBasedSignature = CharOperation.replaceOnCopy(signature, '/', '.'); |
| String returnTypeName= Signature.getReturnType(new String(dotBasedSignature)); |
| return new String(ClassFile.translatedName(returnTypeName.toCharArray())); |
| } |
| /* |
| * @see IMethod |
| */ |
| public String getSignature() throws JavaModelException { |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| return new String(info.getMethodDescriptor()); |
| } |
| /** |
| * @see org.eclipse.jdt.internal.core.JavaElement#hashCode() |
| */ |
| public int hashCode() { |
| int hash = super.hashCode(); |
| for (int i = 0, length = this.parameterTypes.length; i < length; i++) { |
| hash = Util.combineHashCodes(hash, getErasedParameterType(i).hashCode()); |
| } |
| return hash; |
| } |
| /* |
| * @see IMethod |
| */ |
| public boolean isConstructor() throws JavaModelException { |
| if (!getElementName().equals(this.parent.getElementName())) { |
| // faster than reaching the info |
| return false; |
| } |
| IBinaryMethod info = (IBinaryMethod) getElementInfo(); |
| return info.isConstructor(); |
| } |
| /* |
| * @see IMethod#isMainMethod() |
| */ |
| public boolean isMainMethod() throws JavaModelException { |
| return this.isMainMethod(this); |
| } |
| /* |
| * @see IMethod#isLambdaMethod() |
| */ |
| public boolean isLambdaMethod() { |
| return false; |
| } |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.core.IMethod#isResolved() |
| */ |
| public boolean isResolved() { |
| return false; |
| } |
| /* |
| * @see IMethod#isSimilar(IMethod) |
| */ |
| public boolean isSimilar(IMethod method) { |
| return |
| areSimilarMethods( |
| getElementName(), getParameterTypes(), |
| method.getElementName(), method.getParameterTypes(), |
| null); |
| } |
| |
| public String readableName() { |
| |
| StringBuffer buffer = new StringBuffer(super.readableName()); |
| buffer.append("("); //$NON-NLS-1$ |
| String[] paramTypes = this.parameterTypes; |
| int length; |
| if (paramTypes != null && (length = paramTypes.length) > 0) { |
| for (int i = 0; i < length; i++) { |
| buffer.append(Signature.toString(paramTypes[i])); |
| if (i < length - 1) { |
| buffer.append(", "); //$NON-NLS-1$ |
| } |
| } |
| } |
| buffer.append(")"); //$NON-NLS-1$ |
| return buffer.toString(); |
| } |
| public JavaElement resolved(Binding binding) { |
| SourceRefElement resolvedHandle = new ResolvedBinaryMethod(this.parent, this.name, this.parameterTypes, new String(binding.computeUniqueKey())); |
| resolvedHandle.occurrenceCount = this.occurrenceCount; |
| return resolvedHandle; |
| }/* |
| * @private Debugging purposes |
| */ |
| protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) { |
| buffer.append(tabString(tab)); |
| if (info == null) { |
| toStringName(buffer); |
| buffer.append(" (not open)"); //$NON-NLS-1$ |
| } else if (info == NO_INFO) { |
| toStringName(buffer); |
| } else { |
| IBinaryMethod methodInfo = (IBinaryMethod) info; |
| int flags = methodInfo.getModifiers(); |
| if (Flags.isStatic(flags)) { |
| buffer.append("static "); //$NON-NLS-1$ |
| } |
| if (!methodInfo.isConstructor()) { |
| buffer.append(Signature.toString(getReturnType(methodInfo))); |
| buffer.append(' '); |
| } |
| toStringName(buffer, flags); |
| } |
| } |
| protected void toStringName(StringBuffer buffer) { |
| toStringName(buffer, 0); |
| } |
| protected void toStringName(StringBuffer buffer, int flags) { |
| buffer.append(getElementName()); |
| buffer.append('('); |
| String[] parameters = getParameterTypes(); |
| int length; |
| if (parameters != null && (length = parameters.length) > 0) { |
| boolean isVarargs = Flags.isVarargs(flags); |
| for (int i = 0; i < length; i++) { |
| try { |
| if (i < length - 1) { |
| buffer.append(Signature.toString(parameters[i])); |
| buffer.append(", "); //$NON-NLS-1$ |
| } else if (isVarargs) { |
| // remove array from signature |
| String parameter = parameters[i].substring(1); |
| buffer.append(Signature.toString(parameter)); |
| buffer.append(" ..."); //$NON-NLS-1$ |
| } else { |
| buffer.append(Signature.toString(parameters[i])); |
| } |
| } catch (IllegalArgumentException e) { |
| // parameter signature is malformed |
| buffer.append("*** invalid signature: "); //$NON-NLS-1$ |
| buffer.append(parameters[i]); |
| } |
| } |
| } |
| buffer.append(')'); |
| if (this.occurrenceCount > 1) { |
| buffer.append("#"); //$NON-NLS-1$ |
| buffer.append(this.occurrenceCount); |
| } |
| } |
| public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException { |
| JavadocContents javadocContents = ((BinaryType) this.getDeclaringType()).getJavadocContents(monitor); |
| if (javadocContents == null) return null; |
| return javadocContents.getMethodDoc(this); |
| } |
| } |