From 5e56685de5514aaac4c6c6fb43af91a62b36bf64 Mon Sep 17 00:00:00 2001 From: jlanuti <jlanuti> Date: Fri, 12 Jan 2007 21:10:57 +0000 Subject: [PATCH] Fixes for method signature resolutions --- .../component/internal/SignatureHelper.java | 95 +++++++++++++++++++ .../action/Scan4APIRefCompatibility.java | 53 ++++++++++- 2 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 archive/releng.builder/tools/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/SignatureHelper.java diff --git a/archive/releng.builder/tools/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/SignatureHelper.java b/archive/releng.builder/tools/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/SignatureHelper.java new file mode 100644 index 000000000..72f2ceb9c --- /dev/null +++ b/archive/releng.builder/tools/apitools/org.eclipse.wtp.releng.tools.component.core/src/org/eclipse/wtp/releng/tools/component/internal/SignatureHelper.java @@ -0,0 +1,95 @@ +package org.eclipse.wtp.releng.tools.component.internal; + +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; + +/** + * This is a helper class for use with org.eclipse.jdt.core.Signature. The Signature class does + * not make it easy to resolve the real qualified names of type signatures, so this helper class + * has been added for help in the scans. + */ +public class SignatureHelper { + + /** + * Constants + */ + public static final char C_WHITESPACE = ' '; + public static final char C_COMMA = ','; + + /** + * This is a helper method to return the fully qualified resolved signature type name of + * a given type signature character array. + * + * @param typeSignature char[] + * @param relativeType IType + * @return resolved signature type class name + */ + public static String getSignatureResolvedName(char[] typeSignature, IType relativeType) { + StringBuffer buffer = new StringBuffer(); + try { + computeSignatureResolvedName(typeSignature, relativeType, buffer); + } catch (JavaModelException jme) { + jme.printStackTrace(); + } + return buffer.toString(); + } + + private static void computeSignatureResolvedName(char[] typeSignature, IType relativeType, StringBuffer buffer) throws JavaModelException{ + char[] erasureType = Signature.getTypeErasure(typeSignature); + if (erasureType != null) { + computeSignatureResolvedNameNoNesting(erasureType, relativeType, buffer); + } else { + char[] variableName = Signature.getTypeVariable(typeSignature); + if (variableName != null) { + buffer.append(variableName); + } + } + char[][] typeArgs = Signature.getTypeArguments(typeSignature); + if (typeArgs != null && typeArgs.length > 0) { + buffer.append(Signature.C_GENERIC_START); + for (int i = 0; i < typeArgs.length; i++) { + computeSignatureResolvedName(typeArgs[i], relativeType, buffer); + if (i + 1 < typeArgs.length) { + buffer.append(C_COMMA); + buffer.append(C_WHITESPACE); + } + } + buffer.append(Signature.C_GENERIC_END); + } + } + + private static void computeSignatureResolvedNameNoNesting(char[] typeSignature, IType relativeType, StringBuffer buffer) throws JavaModelException{ + switch (Signature.getTypeSignatureKind(typeSignature)) { + case Signature.CLASS_TYPE_SIGNATURE: + if (typeSignature[0] == Signature.C_RESOLVED) { + buffer.append(Signature.toCharArray(typeSignature)); + break; + } + buffer.append(Signature.toQualifiedName(relativeType.resolveType(new String(Signature.toCharArray(typeSignature)))[0])); + break; + case Signature.WILDCARD_TYPE_SIGNATURE : + //Check the next char to see what the type signature is. + if (typeSignature.length > 1 && typeSignature[1] == Signature.C_UNRESOLVED){ + //Resolve the unresolved type. + char[] wildcardType = new char[typeSignature.length - 3]; + System.arraycopy(typeSignature, 2, wildcardType, 0, wildcardType.length); + String resolvedType = Signature.toQualifiedName(relativeType.resolveType(new String(wildcardType))[0]); + char[] resolvedTypeChars = resolvedType.toCharArray(); + //We actually resolved something. + if (resolvedTypeChars.length > (typeSignature.length - 3)) { + char[] result = new char[resolvedTypeChars.length + 3]; + result[0] = typeSignature[0]; + result[1] = Signature.C_RESOLVED; + //Copy the resolved chars. + System.arraycopy(resolvedTypeChars, 0, result, 2, resolvedTypeChars.length); + result[result.length - 1] = Signature.C_SEMICOLON; + buffer.append(Signature.toCharArray(result)); + break; + } + } + default: + buffer.append(Signature.getSignatureSimpleName(typeSignature)); + } + } +} diff --git a/archive/releng.builder/tools/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/adopter/action/Scan4APIRefCompatibility.java b/archive/releng.builder/tools/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/adopter/action/Scan4APIRefCompatibility.java index a5e58f2a4..8c1d5edb8 100644 --- a/archive/releng.builder/tools/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/adopter/action/Scan4APIRefCompatibility.java +++ b/archive/releng.builder/tools/apitools/org.eclipse.wtp.releng.tools.component.ui/src/org/eclipse/wtp/releng/tools/component/ui/internal/adopter/action/Scan4APIRefCompatibility.java @@ -14,6 +14,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -69,6 +70,7 @@ import org.eclipse.wtp.releng.tools.component.adopters.References; import org.eclipse.wtp.releng.tools.component.api.ClassAPI; import org.eclipse.wtp.releng.tools.component.api.FieldAPI; import org.eclipse.wtp.releng.tools.component.api.MethodAPI; +import org.eclipse.wtp.releng.tools.component.internal.SignatureHelper; import org.eclipse.wtp.releng.tools.component.ui.Message; import org.eclipse.wtp.releng.tools.component.ui.internal.adopter.preference.UsageReportsPrefPage; import org.eclipse.wtp.releng.tools.component.ui.internal.adopter.view.BreakageReportView; @@ -427,8 +429,9 @@ public class Scan4APIRefCompatibility extends Action implements IActionDelegate if (type != null) { IMethod method = type.getMethod(name, paramTypes); - if (method.exists()) + if (method.exists() || sourceMethodExists(method, type)) return true; + if (type.isClass()) { String superClassName = type.getSuperclassName(); @@ -452,6 +455,33 @@ public class Scan4APIRefCompatibility extends Action implements IActionDelegate } return false; } + + /** + * Because the scans are done in binary and the method type is source, we need to do some more + * work to try and match the method signatures. See Signature for further info. + * @param method + * @param type + * @return boolean + * @throws JavaModelException + */ + private boolean sourceMethodExists(IMethod method, IType type) throws JavaModelException { + IMethod[] similarMethods = findSimilarMethods(method, type); + for (int i=0; i<similarMethods.length; i++) { + boolean foundMatch = true; + String[] similarParameterTypes = similarMethods[i].getParameterTypes(); + for (int j=0; j<similarParameterTypes.length; j++) { + String similarParamSignature = SignatureHelper.getSignatureResolvedName(similarParameterTypes[j].toCharArray(), type); + String methodParamSignature = SignatureHelper.getSignatureResolvedName(method.getParameterTypes()[j].toCharArray(), type); + if (!similarParamSignature.equals(methodParamSignature)) { + foundMatch = false; + break; + } + } + if (foundMatch) + return true; + } + return false; + } private boolean fieldExists(IJavaProject javaProject, IType type, String name) throws JavaModelException, CoreException { @@ -510,4 +540,25 @@ public class Scan4APIRefCompatibility extends Action implements IActionDelegate } } } + + /** + * Finds a method in the given type. + * This searches for methods with the same name and signature. Parameter types are only + * compared by the simple name, no resolving for the fully qualified type name is done + * @param method + * @param type + * @return Similar methods + * @throws JavaModelException + */ + public static IMethod[] findSimilarMethods(IMethod method, IType type) throws JavaModelException { + IMethod[] methods = type.getMethods(); + List similarMethods = new ArrayList(); + boolean isConstructor= method.isConstructor(); + for (int i= 0; i < methods.length; i++) { + IMethod otherMethod= methods[i]; + if (otherMethod.isConstructor() == isConstructor && method.isSimilar(otherMethod)) + similarMethods.add(otherMethod); + } + return (IMethod[]) similarMethods.toArray(new IMethod[similarMethods.size()]); + } } \ No newline at end of file -- GitLab