/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser; import gw.internal.gosu.parser.java.classinfo.JavaSourceUtil; import gw.lang.parser.TypeVarToTypeMap; import gw.lang.reflect.IAnnotationInfo; import gw.lang.reflect.java.*; import gw.lang.reflect.IType; import gw.lang.reflect.TypeSystem; import gw.lang.reflect.FunctionType; import gw.lang.reflect.gs.IGenericTypeVariable; import gw.internal.gosu.ir.transform.AbstractElementTransformer; import gw.lang.reflect.module.IModule; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.TypeVariable; import java.lang.reflect.Type; import java.lang.annotation.Annotation; import java.util.Arrays; public class MethodJavaClassMethod implements IJavaClassMethod, IJavaClassBytecodeMethod { private Method _method; private IModule _module; public MethodJavaClassMethod(Method method, IModule module) { _method = method; _module = module; } @Override public IType getReturnType() { return TypeSystem.get(_method.getReturnType()); } @Override public IJavaClassInfo getReturnClassInfo() { return JavaSourceUtil.getClassInfo( _method.getReturnType(), _module ); } @Override public String getName() { return _method.getName(); } @Override public IJavaClassInfo getEnclosingClass() { return JavaSourceUtil.getClassInfo( _method.getDeclaringClass(), _module ); } @Override public IJavaClassInfo[] getParameterTypes() { Class<?>[] rawTypes = _method.getParameterTypes(); IJavaClassInfo[] types = new IJavaClassInfo[rawTypes.length]; for (int i = 0; i < rawTypes.length; i++) { types[i] = JavaSourceUtil.getClassInfo(rawTypes[i], _module); } return types; } @Override public int getModifiers() { return _method.getModifiers(); } @Override public boolean isSynthetic() { return _method.isSynthetic(); } @Override public boolean isBridge() { return _method.isBridge(); } @Override public IJavaClassInfo[] getExceptionTypes() { Class<?>[] rawTypes = _method.getExceptionTypes(); IJavaClassInfo[] types = new IJavaClassInfo[rawTypes.length]; for (int i = 0; i < rawTypes.length; i++) { types[i] = JavaSourceUtil.getClassInfo(rawTypes[i], _module); } return types; } @Override public Object getDefaultValue() { return _method.getDefaultValue(); } @Override public String getReturnTypeName() { return _method.getReturnType().getName(); } @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) { return _method.isAnnotationPresent( annotationClass ); } @Override public IAnnotationInfo getAnnotation(Class annotationClass) { Annotation annotation = _method.getAnnotation(annotationClass); return annotation != null ? new ClassAnnotationInfo(annotation, this) : null; } @Override public IAnnotationInfo[] getDeclaredAnnotations() { Annotation[] annotations = _method.getDeclaredAnnotations(); IAnnotationInfo[] declaredAnnotations = new IAnnotationInfo[annotations.length]; for (int i = 0; i < declaredAnnotations.length; i++) { declaredAnnotations[i] = new ClassAnnotationInfo(annotations[i], this); } return declaredAnnotations; } public void setAccessible(boolean accessible) { _method.setAccessible(accessible); } @Override public Object invoke(Object ctx, Object[] args) throws InvocationTargetException, IllegalAccessException { return _method.invoke(ctx, args); } @Override public IGenericTypeVariable[] getTypeVariables(IJavaMethodInfo javaMethodInfo) { TypeVariable<Method>[] typeVars = _method.getTypeParameters(); IType declClass = TypeSystem.get( _method.getDeclaringClass() ); TypeVarToTypeMap actualParamByVarName = TypeLord.mapTypeByVarName( declClass, declClass ); FunctionType functionType = new FunctionType(javaMethodInfo, true); return GenericTypeVariable.convertTypeVars( functionType, typeVars, actualParamByVarName ); } @Override public IJavaClassType[] getGenericParameterTypes() { Type[] rawTypes = _method.getGenericParameterTypes(); IJavaClassType[] types = new IJavaClassType[rawTypes.length]; for (int i = 0; i < rawTypes.length; i++) { Type rawType = rawTypes[i]; IJavaClassType type = TypeJavaClassType.createType(rawType, _module); types[i] = type; } return types; } @Override public IJavaClassType getGenericReturnType() { return TypeJavaClassType.createType(_method.getGenericReturnType(), _module); } public Class[] getJavaParameterTypes() { return _method.getParameterTypes(); } @Override public int hashCode() { int result = Arrays.hashCode( getParameterTypes() ); result = 31 * result + getReturnType().hashCode(); result = 31 * result + getName().hashCode(); return result; } public boolean equals( Object o ) { if( !(o instanceof IJavaClassMethod) ) { return false; } IJavaClassMethod jcm = (IJavaClassMethod)o; return getName().equals( jcm.getName() ) && getReturnType() == jcm.getReturnType() && Arrays.equals( getParameterTypes(), jcm.getParameterTypes() ); } @Override public int compareTo( IJavaClassMethod o ) { return getName().compareTo( o.getName() ); } public Method getJavaMethod() { return _method; } public String toString() { return _method.toString(); } }