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