Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.walkmod.javalang.compiler.reflection.MethodInspector Maven / Gradle / Ivy
package org.walkmod.javalang.compiler.reflection;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.walkmod.javalang.ast.SymbolData;
import org.walkmod.javalang.compiler.ArrayFilter;
import org.walkmod.javalang.compiler.CompositeBuilder;
import org.walkmod.javalang.compiler.Predicate;
import org.walkmod.javalang.compiler.symbols.SymbolType;
import org.walkmod.javalang.exceptions.NoSuchExpressionTypeException;
public class MethodInspector {
private static GenericBuilderFromGenericClasses b1 = new GenericBuilderFromGenericClasses();
public static Method findMethod(Class scope,
T[] args, String name) {
Map typeMapping = new HashMap();
ArrayFilter filter = new ArrayFilter(null );
CompatibleArgsPredicate pred = new CompatibleArgsPredicate(
args);
filter.appendPredicate(
new MethodsByNamePredicate(name))
.appendPredicate(new InvokableMethodsPredicate())
.appendPredicate(pred);
try {
SymbolType result = MethodInspector.findMethodType(new SymbolType(scope), args, filter, null , typeMapping);
if (result != null ){
return result.getMethod();
}
} catch (Exception e) {
throw new NoSuchExpressionTypeException(e);
}
return null ;
}
public static SymbolType findMethodType(SymbolType scope,
T[] args, ArrayFilter filter,
CompositeBuilder builder,
Map typeMapping) throws Exception {
SymbolType result = null ;
List> bounds = scope.getBoundClasses();
b1.setParameterizedTypes(scope.getParameterizedTypes());
Iterator> it = bounds.iterator();
List> preds = filter.getPredicates();
List> tmp = null ;
if (preds != null ) {
tmp = new LinkedList>();
for (Predicate pred : preds) {
if (pred instanceof TypeMappingPredicate) {
tmp.add((TypeMappingPredicate) pred);
}
}
}
Class[] argClasses = SymbolType.toClassArray(args);
while (it.hasNext() && result == null ) {
Class bound = it.next();
if (scope.getArrayCount() != 0 ) {
bound = Array.newInstance(bound, scope.getArrayCount())
.getClass();
}
b1.setClazz(bound);
Map mapping = b1.build(typeMapping);
if (tmp != null ) {
for (TypeMappingPredicate pred : tmp) {
pred.setTypeMapping(mapping);
}
}
result = findMethodType(bound, argClasses, filter, builder,
mapping, false );
if (scope.getArrayCount() != 0 && result != null ) {
Method method = result.getMethod();
if (method != null && method.getName().equals("clone" )) {
result.setArrayCount(scope.getArrayCount());
}
}
}
return result;
}
public static boolean isGeneric(Method m) {
boolean isGeneric = m.getTypeParameters().length > 0
&& !m.getReturnType().equals(void .class );
if (!isGeneric) {
return ClassInspector.isGeneric(m.getGenericReturnType());
}
return isGeneric;
}
public static SymbolType findMethodType(Class clazz, Class[] args,
ArrayFilter filter, CompositeBuilder builder,
Map typeMapping, boolean throwException)
throws Exception {
ExecutableSorter sorter = new ExecutableSorter();
List auxList = sorter.sort(clazz.getDeclaredMethods(), args);
Method[] auxArray = new Method[auxList.size()];
auxList.toArray(auxArray);
filter.setElements(auxArray);
Method aux = filter.filterOne();
SymbolType result = null ;
if (aux != null ) {
if (builder != null ) {
builder.build(aux);
}
result = SymbolType.valueOf(aux, typeMapping);
}
if (result == null ) {
Class superClass = clazz.getSuperclass();
if (superClass != null ) {
result = findMethodType(superClass, args, filter, builder,
typeMapping, false );
}
if (result == null ) {
Type[] types = clazz.getGenericInterfaces();
if (types.length > 0 ) {
for (int i = 0 ; i < types.length && result == null ; i++) {
Class type = SymbolType.valueOf(types[i],
typeMapping).getClazz();
result = findMethodType(type, args, filter,
builder, typeMapping, false );
}
}
if (result == null && clazz.isInterface()) {
result = findMethodType(Object.class , args, filter,
builder, typeMapping, false );
}
}
if (result == null ) {
if (clazz.isMemberClass()) {
result = findMethodType(clazz.getDeclaringClass(), args,
filter, builder, typeMapping, false );
} else if (clazz.isAnonymousClass()) {
result = findMethodType(clazz.getEnclosingClass(), args,
filter, builder, typeMapping, false );
}
}
}
if (result == null && throwException) {
throw new NoSuchMethodException("The method cannot be found" );
}
return result;
}
public static Set getInhertitedDefaultMethods(Class interf,
Class clazz) {
Set result = new HashSet();
if (!clazz.isInterface()) {
Method[] declMethods = clazz.getDeclaredMethods();
Set methods = getVisibleDefaultMethods(interf, clazz);
Iterator it = methods.iterator();
while (it.hasNext()) {
Method current = it.next();
boolean found = false ;
Class[] params2 = current.getParameterTypes();
for (int j = 0 ; j < declMethods.length && !found; j++) {
if (declMethods[j].getName().equals(current.getName())) {
Class[] params1 = declMethods[j].getParameterTypes();
if (params1.length == params2.length) {
boolean compatible = true ;
for (int k = 0 ; k < params2.length && compatible; k++) {
compatible = params1[k]
.isAssignableFrom(params2[k]);
}
found = compatible;
}
}
}
if (!found) {
result.add(current);
}
}
}
return result;
}
private static Set getVisibleDefaultMethods(Class clazz,
Class invocationClass) {
Set result = new HashSet();
HashMap> aux = new HashMap>();
if (clazz == null || clazz.equals(Object.class )) {
return result;
}
Method[] declMethods = clazz.getDeclaredMethods();
for (int i = 0 ; i < declMethods.length; i++) {
int modifiers = declMethods[i].getModifiers();
boolean isDefault = Modifier.isPublic(modifiers)
&& !Modifier.isStatic(modifiers)
&& !Modifier.isAbstract(modifiers);
boolean isVisible = clazz.getName().equals(
invocationClass.getName());
boolean samePackage = clazz.getPackage() == null
&& invocationClass.getPackage() == null ;
samePackage = samePackage
|| (clazz.getPackage() != null
&& invocationClass.getPackage() != null && clazz
.getPackage().getName()
.equals(invocationClass.getPackage().getName()));
isVisible = isVisible || Modifier.isPublic(modifiers)
|| (!Modifier.isPrivate(modifiers) && samePackage);
if (isVisible && isDefault && !declMethods[i].isBridge()
&& !declMethods[i].isSynthetic()) {
result.add(declMethods[i]);
Set auxSet = aux.get(declMethods[i].getName());
if (auxSet == null ) {
auxSet = new HashSet();
}
auxSet.add(declMethods[i]);
aux.put(declMethods[i].getName(), auxSet);
}
}
if (clazz.isInterface()) {
Class[] interfaces = clazz.getInterfaces();
for (int i = 0 ; i < interfaces.length; i++) {
Set auxSet = getVisibleDefaultMethods(interfaces[i],
invocationClass);
result.addAll(auxSet);
}
}
return result;
}
public static Method getLambdaMethod(Class clazz, int paramsSize) {
if (clazz == null || clazz.equals(Object.class )) {
return null ;
}
boolean isAbstract = Modifier.isAbstract(clazz.getModifiers());
if (!clazz.isInterface() && !isAbstract) {
return null ;
}
Method[] declMethods = clazz.getDeclaredMethods();
for (int i = 0 ; i < declMethods.length; i++) {
int modifiers = declMethods[i].getModifiers();
boolean isDefault = Modifier.isPublic(modifiers)
&& !Modifier.isStatic(modifiers)
&& !Modifier.isAbstract(modifiers);
if (!isDefault
&& declMethods[i].getParameterTypes().length == paramsSize) {
return declMethods[i];
}
}
Method result = getLambdaMethod(clazz.getSuperclass(), paramsSize);
if (isAbstract) {
Class[] interfaces = clazz.getInterfaces();
for (int i = 0 ; i < interfaces.length && result == null ; i++) {
result = getLambdaMethod(interfaces[i], paramsSize);
}
}
return result;
}
public static Set getVisibleMethods(Class clazz,
Class invocationClass) {
Set result = new HashSet();
HashMap> aux = new HashMap>();
if (clazz == null || clazz.equals(Object.class )) {
return result;
}
Method[] declMethods = clazz.getDeclaredMethods();
for (int i = 0 ; i < declMethods.length; i++) {
boolean isVisible = clazz.getName().equals(
invocationClass.getName());
int modifiers = declMethods[i].getModifiers();
boolean samePackage = clazz.getPackage() == null
&& invocationClass.getPackage() == null ;
samePackage = samePackage
|| (clazz.getPackage() != null
&& invocationClass.getPackage() != null && clazz
.getPackage().getName()
.equals(invocationClass.getPackage().getName()));
isVisible = isVisible || Modifier.isPublic(modifiers)
|| (!Modifier.isPrivate(modifiers) && samePackage);
if (isVisible && !declMethods[i].isBridge()
&& !declMethods[i].isSynthetic()) {
result.add(declMethods[i]);
Set auxSet = aux.get(declMethods[i].getName());
if (auxSet == null ) {
auxSet = new HashSet();
}
auxSet.add(declMethods[i]);
aux.put(declMethods[i].getName(), auxSet);
}
}
if (clazz.isInterface()) {
Class[] interfaces = clazz.getInterfaces();
for (int i = 0 ; i < interfaces.length; i++) {
Set auxSet = getVisibleMethods(interfaces[i],
invocationClass);
result.addAll(auxSet);
}
} else {
Set superClassMethods = getVisibleMethods(
clazz.getSuperclass(), invocationClass);
for (Method superMethod : superClassMethods) {
Set auxSet = aux.get(superMethod.getName());
boolean found = false ;
if (auxSet == null ) {
auxSet = new HashSet();
} else {
Class[] superParams = superMethod.getParameterTypes();
Iterator it = auxSet.iterator();
while (it.hasNext() && !found) {
Method prev = it.next();
Class[] prevParams = prev.getParameterTypes();
if (prevParams.length == superParams.length) {
if (prevParams.length > 0 ) {
boolean compatibleArgs = false ;
for (int i = 0 ; i < prevParams.length
&& compatibleArgs; i++) {
compatibleArgs = superParams[i]
.isAssignableFrom(prevParams[i]);
}
found = compatibleArgs;
} else {
found = true ;
}
}
}
}
if (!found) {
aux.put(superMethod.getName(), auxSet);
result.add(superMethod);
}
}
}
return result;
}
public static Set getInheritedMethods(Class clazz) {
Set result = new HashSet();
HashMap> aux = new HashMap>();
if (clazz == null || clazz.equals(Object.class )) {
return result;
}
Method[] declMethods = clazz.getDeclaredMethods();
for (int i = 0 ; i < declMethods.length; i++) {
if (!Modifier.isPrivate(declMethods[i].getModifiers())
&& !Modifier.isAbstract(declMethods[i].getModifiers())
&& !declMethods[i].isBridge()
&& !declMethods[i].isSynthetic()) {
result.add(declMethods[i]);
Set auxSet = aux.get(declMethods[i].getName());
if (auxSet == null ) {
auxSet = new HashSet();
}
auxSet.add(declMethods[i]);
aux.put(declMethods[i].getName(), auxSet);
}
}
Set superClassMethods = getInheritedMethods(clazz
.getSuperclass());
for (Method superMethod : superClassMethods) {
Set auxSet = aux.get(superMethod.getName());
boolean found = false ;
if (auxSet == null ) {
auxSet = new HashSet();
} else {
Class[] superParams = superMethod.getParameterTypes();
Iterator it = auxSet.iterator();
while (it.hasNext() && !found) {
Method prev = it.next();
Class[] prevParams = prev.getParameterTypes();
if (prevParams.length == superParams.length) {
if (prevParams.length > 0 ) {
boolean compatibleArgs = false ;
for (int i = 0 ; i < prevParams.length
&& compatibleArgs; i++) {
compatibleArgs = superParams[i]
.isAssignableFrom(prevParams[i]);
}
found = compatibleArgs;
} else {
found = true ;
}
}
}
}
if (!found) {
aux.put(superMethod.getName(), auxSet);
result.add(superMethod);
}
}
return result;
}
}