• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.internal.bytecode;
2 
3 import org.robolectric.internal.IShadow;
4 import org.robolectric.util.ReflectionHelpers;
5 
6 public class ShadowImpl implements IShadow {
7 
8   private final ProxyMaker PROXY_MAKER =
9       new ProxyMaker(
10           new ProxyMaker.MethodMapper() {
11             @Override
12             public String getName(String className, String methodName) {
13               return directMethodName(className, methodName);
14             }
15           });
16 
17   @Override
18   @SuppressWarnings("TypeParameterUnusedInFormals")
extract(Object instance)19   public <T> T extract(Object instance) {
20     return (T) ((ShadowedObject) instance).$$robo$getData();
21   }
22 
newInstanceOf(Class<T> clazz)23   @Override public <T> T newInstanceOf(Class<T> clazz) {
24     return ReflectionHelpers.callConstructor(clazz);
25   }
26 
newInstance(Class<T> clazz, Class[] parameterTypes, Object[] params)27   @Override public <T> T newInstance(Class<T> clazz, Class[] parameterTypes, Object[] params) {
28     return ReflectionHelpers.callConstructor(clazz, ReflectionHelpers.ClassParameter.fromComponentLists(parameterTypes, params));
29   }
30 
directlyOn(T shadowedObject, Class<T> clazz)31   @Override public <T> T directlyOn(T shadowedObject, Class<T> clazz) {
32     return createProxy(shadowedObject, clazz);
33   }
34 
createProxy(T shadowedObject, Class<T> clazz)35   private <T> T createProxy(T shadowedObject, Class<T> clazz) {
36     try {
37       return PROXY_MAKER.createProxy(clazz, shadowedObject);
38     } catch (Exception e) {
39       throw new RuntimeException("error creating direct call proxy for " + clazz, e);
40     }
41   }
42 
43   @Override @SuppressWarnings(value = {"unchecked", "TypeParameterUnusedInFormals"})
directlyOn(Object shadowedObject, String clazzName, String methodName, ReflectionHelpers.ClassParameter... paramValues)44   public <R> R directlyOn(Object shadowedObject, String clazzName, String methodName, ReflectionHelpers.ClassParameter... paramValues) {
45     try {
46       Class<Object> aClass = (Class<Object>) shadowedObject.getClass().getClassLoader().loadClass(clazzName);
47       return directlyOn(shadowedObject, aClass, methodName, paramValues);
48     } catch (ClassNotFoundException e) {
49       throw new RuntimeException(e);
50     }
51   }
52 
53   @Override @SuppressWarnings(value = {"unchecked", "TypeParameterUnusedInFormals"})
directlyOn(T shadowedObject, Class<T> clazz, String methodName, ReflectionHelpers.ClassParameter... paramValues)54   public <R, T> R directlyOn(T shadowedObject, Class<T> clazz, String methodName, ReflectionHelpers.ClassParameter... paramValues) {
55     String directMethodName = directMethodName(clazz.getName(), methodName);
56     return (R) ReflectionHelpers.callInstanceMethod(clazz, shadowedObject, directMethodName, paramValues);
57   }
58 
59   @Override @SuppressWarnings(value = {"unchecked", "TypeParameterUnusedInFormals"})
directlyOn(Class<T> clazz, String methodName, ReflectionHelpers.ClassParameter... paramValues)60   public <R, T> R directlyOn(Class<T> clazz, String methodName, ReflectionHelpers.ClassParameter... paramValues) {
61     String directMethodName = directMethodName(clazz.getName(), methodName);
62     return (R) ReflectionHelpers.callStaticMethod(clazz, directMethodName, paramValues);
63   }
64 
65   @Override @SuppressWarnings(value = {"unchecked", "TypeParameterUnusedInFormals"})
invokeConstructor(Class<? extends R> clazz, R instance, ReflectionHelpers.ClassParameter... paramValues)66   public <R> R invokeConstructor(Class<? extends R> clazz, R instance, ReflectionHelpers.ClassParameter... paramValues) {
67     String directMethodName =
68         directMethodName(clazz.getName(), ShadowConstants.CONSTRUCTOR_METHOD_NAME);
69     return (R) ReflectionHelpers.callInstanceMethod(clazz, instance, directMethodName, paramValues);
70   }
71 
72   @Override
directMethodName(String className, String methodName)73   public String directMethodName(String className, String methodName) {
74      return ShadowConstants.ROBO_PREFIX
75       + className.replace('.', '_').replace('$', '_')
76       + "$" + methodName;
77   }
78 
79 }
80