### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/internal/core/BinaryMethod.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java,v retrieving revision 1.87 diff -u -r1.87 BinaryMethod.java --- model/org/eclipse/jdt/internal/core/BinaryMethod.java 6 Apr 2006 01:47:51 -0000 1.87 +++ model/org/eclipse/jdt/internal/core/BinaryMethod.java 25 Apr 2006 03:37:01 -0000 @@ -25,6 +25,15 @@ */ /* package */ class BinaryMethod extends BinaryMember implements IMethod { + private static final char[] BOOLEAN = "boolean".toCharArray(); //$NON-NLS-1$ + private static final char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$ + private static final char[] CHAR = "char".toCharArray(); //$NON-NLS-1$ + private static final char[] DOUBLE = "double".toCharArray(); //$NON-NLS-1$ + private static final char[] FLOAT = "float".toCharArray(); //$NON-NLS-1$ + private static final char[] INT = "int".toCharArray(); //$NON-NLS-1$ + private static final char[] LONG = "long".toCharArray(); //$NON-NLS-1$ + private static final char[] SHORT = "short".toCharArray(); //$NON-NLS-1$ + private static final char[] VOID = "void".toCharArray(); //$NON-NLS-1$ /** * The parameter type signatures of the method - stored locally @@ -491,7 +500,15 @@ if (this.isConstructor()) { methodName = typeQualifiedName; } - String anchor = Signature.toString(this.getSignature().replace('/', '.'), methodName, null, true, false, Flags.isVarargs(this.getFlags())); + IBinaryMethod info = (IBinaryMethod) getElementInfo(); + char[] genericSignature = info.getGenericSignature(); + String anchor = null; + if (genericSignature != null) { + CharOperation.replace(genericSignature, '/', '.'); + anchor = toString(genericSignature, methodName, Flags.isVarargs(this.getFlags())); + } else { + anchor = Signature.toString(this.getSignature().replace('/', '.'), methodName, null, true, false, Flags.isVarargs(this.getFlags())); + } if (declaringTypeIsMember) { int depth = 0; @@ -544,4 +561,305 @@ if (indexOfNextMethod == -1) throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.UNKNOWN_JAVADOC_FORMAT, this)); return contents.substring(indexOfEndLink + JavadocConstants.ANCHOR_SUFFIX_LENGTH, indexOfNextMethod); } +public String toString(char[] methodSignature, String methodName, boolean isVarArgs) { + return new String(toCharArray(methodSignature, methodName.toCharArray(), isVarArgs)); +} +public char[] toCharArray(char[] methodSignature, char[] methodName, boolean isVargArgs) { + int firstParen = CharOperation.indexOf(Signature.C_PARAM_START, methodSignature); + if (firstParen == -1) { + throw new IllegalArgumentException(); + } + + StringBuffer buffer = new StringBuffer(methodSignature.length + 10); + + // selector + if (methodName != null) { + buffer.append(methodName); + } + + // parameters + buffer.append('('); + char[][] pts = getParameterTypes(methodSignature); + for (int i = 0, max = pts.length; i < max; i++) { + if (i == max - 1) { + appendTypeSignature(pts[i], 0 , buffer, isVargArgs); + } else { + appendTypeSignature(pts[i], 0 , buffer, false); + } + if (i != pts.length - 1) { + buffer.append(','); + buffer.append(' '); + } + } + buffer.append(')'); + char[] result = new char[buffer.length()]; + buffer.getChars(0, buffer.length(), result, 0); + return result; +} +public char[][] getParameterTypes(char[] methodSignature) throws IllegalArgumentException { + try { + int count = getParameterCount(methodSignature); + char[][] result = new char[count][]; + if (count == 0) { + return result; + } + int i = CharOperation.indexOf(Signature.C_PARAM_START, methodSignature); + if (i < 0) { + throw new IllegalArgumentException(); + } else { + i++; + } + int t = 0; + for (;;) { + if (methodSignature[i] == Signature.C_PARAM_END) { + return result; + } + int e = Util.scanTypeSignature(methodSignature, i); + if (e < 0) { + throw new IllegalArgumentException(); + } + result[t] = CharOperation.subarray(methodSignature, i, e + 1); + t++; + i = e + 1; + } + } catch (ArrayIndexOutOfBoundsException e) { + throw new IllegalArgumentException(); + } +} +private int appendTypeSignature(char[] string, int start, StringBuffer buffer, boolean isVarArgs) { + // need a minimum 1 char + if (start >= string.length) { + throw new IllegalArgumentException(); + } + char c = string[start]; + if (isVarArgs) { + switch (c) { + case Signature.C_ARRAY : + return appendArrayTypeSignature(string, start, buffer, true); + case Signature.C_RESOLVED : + case Signature.C_TYPE_VARIABLE : + case Signature.C_BOOLEAN : + case Signature.C_BYTE : + case Signature.C_CHAR : + case Signature.C_DOUBLE : + case Signature.C_FLOAT : + case Signature.C_INT : + case Signature.C_LONG : + case Signature.C_SHORT : + case Signature.C_VOID : + case Signature.C_STAR: + case Signature.C_EXTENDS: + case Signature.C_SUPER: + case Signature.C_CAPTURE: + default: + throw new IllegalArgumentException(); // a var args is an array type + } + } else { + switch (c) { + case Signature.C_ARRAY : + return appendArrayTypeSignature(string, start, buffer, false); + case Signature.C_RESOLVED : + return appendClassTypeSignature(string, start, buffer); + case Signature.C_TYPE_VARIABLE : + int e = Util.scanTypeVariableSignature(string, start); + buffer.append(string, start + 1, e - start - 1); + return e; + case Signature.C_BOOLEAN : + buffer.append(BOOLEAN); + return start; + case Signature.C_BYTE : + buffer.append(BYTE); + return start; + case Signature.C_CHAR : + buffer.append(CHAR); + return start; + case Signature.C_DOUBLE : + buffer.append(DOUBLE); + return start; + case Signature.C_FLOAT : + buffer.append(FLOAT); + return start; + case Signature.C_INT : + buffer.append(INT); + return start; + case Signature.C_LONG : + buffer.append(LONG); + return start; + case Signature.C_SHORT : + buffer.append(SHORT); + return start; + case Signature.C_VOID : + buffer.append(VOID); + return start; + case Signature.C_CAPTURE : + return appendCaptureTypeSignature(string, start, buffer); + case Signature.C_STAR: + case Signature.C_EXTENDS: + case Signature.C_SUPER: + return appendTypeArgumentSignature(string, start, buffer); + default : + throw new IllegalArgumentException(); + } + } +} +public int getParameterCount(char[] methodSignature) throws IllegalArgumentException { + try { + int count = 0; + int i = CharOperation.indexOf(Signature.C_PARAM_START, methodSignature); + if (i < 0) { + throw new IllegalArgumentException(); + } else { + i++; + } + for (;;) { + if (methodSignature[i] == Signature.C_PARAM_END) { + return count; + } + int e= Util.scanTypeSignature(methodSignature, i); + if (e < 0) { + throw new IllegalArgumentException(); + } else { + i = e + 1; + } + count++; + } + } catch (ArrayIndexOutOfBoundsException e) { + throw new IllegalArgumentException(); + } +} +private int appendArrayTypeSignature(char[] string, int start, StringBuffer buffer, boolean isVarArgs) { + int length = string.length; + // need a minimum 2 char + if (start >= length - 1) { + throw new IllegalArgumentException(); + } + char c = string[start]; + if (c != Signature.C_ARRAY) { + throw new IllegalArgumentException(); + } + + int index = start; + c = string[++index]; + while(c == Signature.C_ARRAY) { + // need a minimum 2 char + if (index >= length - 1) { + throw new IllegalArgumentException(); + } + c = string[++index]; + } + + int e = appendTypeSignature(string, index, buffer, false); + + for(int i = 1, dims = index - start; i < dims; i++) { + buffer.append('[').append(']'); + } + + if (isVarArgs) { + buffer.append('.').append('.').append('.'); + } else { + buffer.append('[').append(']'); + } + return e; +} +private int appendClassTypeSignature(char[] string, int start, StringBuffer buffer) { + // need a minimum 3 chars "Lx;" + if (start >= string.length - 2) { + throw new IllegalArgumentException(); + } + // must start in "L" or "Q" + char c = string[start]; + if (c != Signature.C_RESOLVED && c != Signature.C_UNRESOLVED) { + throw new IllegalArgumentException(); + } + int p = start + 1; + while (true) { + if (p >= string.length) { + throw new IllegalArgumentException(); + } + c = string[p]; + switch(c) { + case Signature.C_SEMICOLON : + // all done + return p; + case Signature.C_GENERIC_START : + int e = searchGenericEnd(string, p + 1); + // once we hit type arguments there are no more package prefixes + p = e; + break; + case Signature.C_DOT : + buffer.append('.'); + break; + case '/' : + buffer.append('/'); + break; + case Signature.C_DOLLAR : + // once we hit "$" there are no more package prefixes + /** + * Convert '$' in resolved type signatures into '.'. + * NOTE: This assumes that the type signature is an inner type + * signature. This is true in most cases, but someone can define a + * non-inner type name containing a '$'. + */ + buffer.append('.'); + break; + default : + buffer.append(c); + } + p++; + } +} +private int appendTypeArgumentSignature(char[] string, int start, StringBuffer buffer) { + // need a minimum 1 char + if (start >= string.length) { + throw new IllegalArgumentException(); + } + char c = string[start]; + switch(c) { + case Signature.C_STAR : + return start; + case Signature.C_EXTENDS : + return appendTypeSignature(string, start + 1, buffer, false); + case Signature.C_SUPER : + return appendTypeSignature(string, start + 1, buffer, false); + default : + return appendTypeSignature(string, start, buffer, false); + } +} +private int appendCaptureTypeSignature(char[] string, int start, StringBuffer buffer) { + // need a minimum 2 char + if (start >= string.length - 1) { + throw new IllegalArgumentException(); + } + char c = string[start]; + if (c != Signature.C_CAPTURE) { + throw new IllegalArgumentException(); + } + return appendTypeArgumentSignature(string, start + 1, buffer); +} +private int searchGenericEnd(char[] string, int start) { + if (start >= string.length) { + throw new IllegalArgumentException(); + } + if (string[start] == Signature.C_GENERIC_END) { + return start; + } + int length = string.length; + int balance = 1; + start++; + while (start <= length) { + switch(string[start]) { + case Signature.C_GENERIC_END : + balance--; + if (balance == 0) { + return start; + } + break; + case Signature.C_GENERIC_START : + balance++; + break; + } + start++; + } + return start; +} }