/* Copyright (C) 2004 - 2008 Versant Inc. http://www.db4o.com
This file is part of the sharpen open source java to c# translator.
sharpen is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published
by the Free Software Foundation and as clarified by db4objects' GPL
interpretation policy, available at
http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
Suite 350, San Mateo, CA 94403, USA.
sharpen is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/**
* Portions of this file were taken from Eclipse:
* /org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/Bindings.java
* and are subject to the CPL.
*
* Original copyright notice on file follows:
* /*******************************************************************************
* * Copyright (c) 2000, orporation and others.
* * All rights reserved. This program and the accompanying materials
* * are made available under the terms of the Common Public License v1.0
* * which accompanies this distribution, and is available at
* * http://www.eclipse.org/legal/cpl-v10.html
* *
* * Contributors:
* * IBM Corporation - initial API and implementation
* * Dmitry Stalnov (dstalnov@fusionone.com) - contributed fix for
* * bug "inline method - doesn't handle implicit cast" (see
* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=24941).
* *******************************************************************************
*/
package sharpen.core.framework;
import org.eclipse.jdt.core.dom.*;
public class BindingUtils {
/**
* Finds the method in the given <code>type</code> that is overrideen by the specified <code>method<code> . Returns <code>null</code> if no such method exits.
* @param type The type to search the method in
* @param method The specified method that would override the result
* @return the method binding representing the method oevrriding the specified <code>method<code>
*/
public static IMethodBinding findOverriddenMethodInType(ITypeBinding type, IMethodBinding method) {
for (Object o : type.getDeclaredMethods()) {
IMethodBinding existing = (IMethodBinding)o;
if (existing.isSubsignature(method)
|| method.isSubsignature(existing)) {
return existing;
}
}
return null;
}
public static IMethodBinding findOverriddenMethodInTypeOrSuperclasses(ITypeBinding type, IMethodBinding method) {
IMethodBinding found = findOverriddenMethodInType(type, method);
if (null != found) {
return found;
}
ITypeBinding superClass = type.getSuperclass();
if (null != superClass) {
return findOverriddenMethodInTypeOrSuperclasses(superClass, method);
}
return null;
}
/**
* Finds a method in the hierarchy of <code>type</code> that is overridden by </code>binding</code>.
* Returns <code>null</code> if no such method exists. First the super class is examined and than the implemented interfaces.
* @param type The type to search the method in
* @param binding The method that overrides
* @return the method binding overridden the method
*/
public static IMethodBinding findOverriddenMethodInHierarchy(ITypeBinding type, IMethodBinding binding) {
return findOverriddenMethodInHierarchy(type, binding, true);
}
public static IMethodBinding findOverriddenMethodInHierarchy(ITypeBinding type, IMethodBinding binding, boolean considerInterfaces, boolean considerItself) {
final ITypeBinding superClass= type.getSuperclass();
if (superClass != null) {
final IMethodBinding superClassMethod= findOverriddenMethodInHierarchy(superClass, binding, true, true);
if (superClassMethod != null) return superClassMethod;
}
if (considerItself) {
final IMethodBinding method = BindingUtils.findOverriddenMethodInType(type, binding);
if (method != null) return method;
}
if (considerInterfaces) {
final ITypeBinding[] interfaces= type.getInterfaces();
for (int i= 0; i < interfaces.length; i++) {
final IMethodBinding interfaceMethod= findOverriddenMethodInHierarchy(interfaces[i], binding, true, true);
if (interfaceMethod != null) return interfaceMethod;
}
}
return null;
}
public static IMethodBinding findOverriddenMethodInHierarchy(ITypeBinding type, IMethodBinding binding, boolean considerInterfaces) {
return findOverriddenMethodInHierarchy(type, binding, considerInterfaces, true);
}
/**
* Finds the method that is defines the given method. The returned method might not be visible.
* @param method The method to find
* @param typeResolver TODO
* @return the method binding representing the method
*/
public static IMethodBinding findMethodDefininition(IMethodBinding method, AST typeResolver) {
if (null == method) {
return null;
}
IMethodBinding definition = null;
ITypeBinding type= method.getDeclaringClass();
ITypeBinding[] interfaces= type.getInterfaces();
for (int i= 0; i < interfaces.length; i++) {
IMethodBinding res= findOverriddenMethodInHierarchy(interfaces[i], method);
if (res != null) {
definition = res; // methods from interfaces are always public and therefore visible
break;
}
}
if (type.getSuperclass() != null) {
IMethodBinding res= findOverriddenMethodInHierarchy(type.getSuperclass(), method);
if (res != null && !Modifier.isPrivate(res.getModifiers())) {
definition = res;
}
} else if (type.isInterface() && null != typeResolver) {
IMethodBinding res = findOverriddenMethodInHierarchy(typeResolver.resolveWellKnownType("java.lang.Object"), method);
if (res != null) {
definition = res;
}
}
IMethodBinding def = findMethodDefininition(definition, typeResolver);
if (def != null) {
return def;
}
return definition;
}
public static boolean isVisibleInHierarchy(IMethodBinding member, IPackageBinding pack) {
int otherflags= member.getModifiers();
ITypeBinding declaringType= member.getDeclaringClass();
if (Modifier.isPublic(otherflags) || Modifier.isProtected(otherflags) || (declaringType != null && declaringType.isInterface())) {
return true;
} else if (Modifier.isPrivate(otherflags)) {
return false;
}
return pack == declaringType.getPackage();
}
public static String qualifiedName(IMethodBinding binding) {
return qualifiedName(binding.getDeclaringClass()) + "."
+ binding.getName();
}
public static String qualifiedSignature(IMethodBinding binding) {
StringBuffer buf = new StringBuffer();
buf.append(qualifiedName(binding.getDeclaringClass())).append(".").append(binding.getName()).append("(");
ITypeBinding[] parameterTypes = binding.getParameterTypes();
for (int i = 0; i < parameterTypes.length; i++) {
if (i != 0) buf.append(",");
buf.append(qualifiedName(parameterTypes[i]));
}
buf.append(")");
return buf.toString();
}
public static String qualifiedName(final ITypeBinding declaringClass) {
return declaringClass.getTypeDeclaration().getQualifiedName();
}
public static String qualifiedName(IVariableBinding binding) {
ITypeBinding declaringClass = binding.getDeclaringClass();
if (null == declaringClass) {
return binding.getName();
}
return qualifiedName(declaringClass) + "." + binding.getName();
}
public static boolean isStatic(IMethodBinding binding) {
return Modifier.isStatic(binding.getModifiers());
}
public static boolean isStatic(MethodInvocation invocation) {
return isStatic(invocation.resolveMethodBinding());
}
}