Skip to content
Snippets Groups Projects
Commit 5e56685d authored by jlanuti's avatar jlanuti
Browse files

Fixes for method signature resolutions

parent a4ebcec2
No related branches found
No related tags found
No related merge requests found
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));
}
}
}
......@@ -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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment