1 package org.robolectric.internal.bytecode; 2 3 import java.lang.reflect.InvocationTargetException; 4 import org.robolectric.internal.IShadow; 5 import org.robolectric.util.ReflectionHelpers; 6 7 public class ShadowImpl implements IShadow { 8 9 @Override 10 @SuppressWarnings("TypeParameterUnusedInFormals") extract(Object instance)11 public <T> T extract(Object instance) { 12 return (T) ((ShadowedObject) instance).$$robo$getData(); 13 } 14 15 @Override newInstanceOf(Class<T> clazz)16 public <T> T newInstanceOf(Class<T> clazz) { 17 return ReflectionHelpers.callConstructor(clazz); 18 } 19 20 @Override newInstance(Class<T> clazz, Class<?>[] parameterTypes, Object[] params)21 public <T> T newInstance(Class<T> clazz, Class<?>[] parameterTypes, Object[] params) { 22 return ReflectionHelpers.callConstructor( 23 clazz, ReflectionHelpers.ClassParameter.fromComponentLists(parameterTypes, params)); 24 } 25 26 @Override 27 @SuppressWarnings(value = {"unchecked", "TypeParameterUnusedInFormals"}) directlyOn( Object shadowedObject, String clazzName, String methodName, ReflectionHelpers.ClassParameter<?>... paramValues)28 public <R> R directlyOn( 29 Object shadowedObject, 30 String clazzName, 31 String methodName, 32 ReflectionHelpers.ClassParameter<?>... paramValues) { 33 try { 34 Class<Object> aClass = 35 (Class<Object>) shadowedObject.getClass().getClassLoader().loadClass(clazzName); 36 return directlyOn(shadowedObject, aClass, methodName, paramValues); 37 } catch (ClassNotFoundException e) { 38 throw new RuntimeException(e); 39 } 40 } 41 42 @Override 43 @SuppressWarnings(value = {"unchecked", "TypeParameterUnusedInFormals"}) directlyOn( T shadowedObject, Class<T> clazz, String methodName, ReflectionHelpers.ClassParameter<?>... paramValues)44 public <R, T> R directlyOn( 45 T shadowedObject, 46 Class<T> clazz, 47 String methodName, 48 ReflectionHelpers.ClassParameter<?>... paramValues) { 49 String directMethodName = directMethodName(clazz.getName(), methodName); 50 return (R) 51 ReflectionHelpers.callInstanceMethod(clazz, shadowedObject, directMethodName, paramValues); 52 } 53 54 @Override 55 @SuppressWarnings(value = {"unchecked", "TypeParameterUnusedInFormals"}) directlyOn( Class<T> clazz, String methodName, ReflectionHelpers.ClassParameter<?>... paramValues)56 public <R, T> R directlyOn( 57 Class<T> clazz, String methodName, ReflectionHelpers.ClassParameter<?>... paramValues) { 58 String directMethodName = directMethodName(clazz.getName(), methodName); 59 return (R) ReflectionHelpers.callStaticMethod(clazz, directMethodName, paramValues); 60 } 61 62 @Override 63 @SuppressWarnings(value = {"unchecked", "TypeParameterUnusedInFormals"}) invokeConstructor( Class<? extends R> clazz, R instance, ReflectionHelpers.ClassParameter<?>... paramValues)64 public <R> R invokeConstructor( 65 Class<? extends R> clazz, R instance, ReflectionHelpers.ClassParameter<?>... paramValues) { 66 String directMethodName = 67 directMethodName(clazz.getName(), ShadowConstants.CONSTRUCTOR_METHOD_NAME); 68 return (R) ReflectionHelpers.callInstanceMethod(clazz, instance, directMethodName, paramValues); 69 } 70 71 @Override directMethodName(String className, String methodName)72 public String directMethodName(String className, String methodName) { 73 return ShadowConstants.ROBO_PREFIX 74 + className.replace('.', '_').replace('$', '_') 75 + "$" 76 + methodName; 77 } 78 79 @Override directNativeMethodName(String className, String methodName)80 public String directNativeMethodName(String className, String methodName) { 81 return ShadowConstants.ROBO_PREFIX + methodName + "$nativeBinding"; 82 } 83 84 @Override directInitialize(Class<?> clazz)85 public void directInitialize(Class<?> clazz) { 86 try { 87 RobolectricInternals.performStaticInitialization(clazz); 88 } catch (InvocationTargetException | IllegalAccessException e) { 89 throw new RuntimeException("failed to initialize " + clazz, e); 90 } 91 } 92 } 93