calabash-android 0.4.0.pre6 → 0.4.0.pre7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. data/bin/calabash-android +7 -0
  2. data/bin/calabash-android-build.rb +1 -1
  3. data/bin/calabash-android-console.rb +1 -1
  4. data/bin/calabash-android-run.rb +1 -1
  5. data/calabash-android.gemspec +1 -0
  6. data/irbrc +2 -0
  7. data/lib/calabash-android/helpers.rb +4 -2
  8. data/lib/calabash-android/lib/TestServer.apk +0 -0
  9. data/lib/calabash-android/operations.rb +31 -22
  10. data/lib/calabash-android/version.rb +1 -1
  11. data/test-server/instrumentation-backend/.classpath +0 -1
  12. data/test-server/instrumentation-backend/antlr/UIQuery.g +11 -2
  13. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Command.java +4 -3
  14. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/FranklyResult.java +95 -0
  15. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +7 -1
  16. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +15 -23
  17. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/location/FakeGPSLocation.java +13 -10
  18. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/CalabashChromeClient.java +136 -36
  19. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpBodyHtml.java +38 -18
  20. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpHtml.java +38 -16
  21. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/EnterTextByCssSelector.java +94 -66
  22. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteAsyncJavascript.java +55 -33
  23. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteJavascript.java +54 -31
  24. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/JavaScriptOperation.java +44 -0
  25. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/PressByCssSelector.java +52 -27
  26. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/QueryHelper.java +39 -32
  27. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ScrollTo.java +56 -41
  28. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetPropertyByCssSelector.java +50 -25
  29. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetText.java +19 -22
  30. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/CompletedFuture.java +40 -0
  31. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/InvocationOperation.java +201 -0
  32. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Operation.java +7 -0
  33. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/PropertyOperation.java +56 -0
  34. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Query.java +144 -72
  35. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQuery.tokens +15 -12
  36. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQueryResultVoid.java +22 -0
  37. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +38 -11
  38. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryLexer.java +226 -109
  39. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryParser.java +237 -84
  40. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/PartialFutureList.java +100 -0
  41. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryAST.java +1 -1
  42. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTClassName.java +26 -22
  43. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +170 -102
  44. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryEvaluator.java +54 -155
  45. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +97 -2
  46. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryVisibility.java +32 -0
  47. metadata +27 -5
  48. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Query.java +0 -24
  49. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Touch.java +0 -44
  50. data/test-server/instrumentation-backend/tests/sh/calaba/instrumentationbackend/query/tests/UIQueryTest.java +0 -134
@@ -1,7 +1,6 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import java.util.HashMap;
5
4
  import java.util.List;
6
5
  import java.util.Map;
7
6
 
@@ -9,60 +8,76 @@ import sh.calaba.instrumentationbackend.InstrumentationBackend;
9
8
  import sh.calaba.instrumentationbackend.Result;
10
9
  import sh.calaba.instrumentationbackend.actions.Action;
11
10
  import sh.calaba.instrumentationbackend.actions.Actions;
12
- import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
13
- import sh.calaba.org.codehaus.jackson.type.TypeReference;
14
11
  import android.test.TouchUtils;
15
12
  import android.webkit.WebView;
16
13
 
17
14
 
18
15
  public class ScrollTo implements Action {
19
-
20
- @Override
16
+
17
+ @Override
21
18
  public Result execute(String... args) {
22
19
  //TODO: Should do horizontal scrolling if needed
23
- String queryResult = QueryHelper.executeJavascriptInWebview("calabash.js", args[1], args[0]);
24
- CalabashChromeClient calabashChromeClient = CalabashChromeClient.findAndPrepareWebViews().get(0);
25
- final WebView webView = calabashChromeClient.getWebView();
26
- webView.scrollTo(0, 0);
27
- QueryHelper.getScreenCoordinatesForCenter(findFirstRect(queryResult));
28
- int scrolledTo = webView.getScrollY();
29
- while (!isVisible(findFirstRect(queryResult), calabashChromeClient)) {
30
- TouchUtils.dragQuarterScreenUp(Actions.parentTestCase, InstrumentationBackend.solo.getCurrentActivity());
31
- if (scrolledTo != webView.getScrollY()) {
32
- scrolledTo = webView.getScrollY();
33
- } else {
34
- return new Result(false, "Tried scrolling but the center of the element never became visible.");
35
- }
36
- }
37
-
38
- return new Result(true, "");
20
+ final String uiQuery = "webView " + args[0] + ":'"+ args[1] + "'";
21
+
22
+ CalabashChromeClient calabashChromeClient = CalabashChromeClient.findAndPrepareWebViews().get(0);
23
+ WebView webView = calabashChromeClient.getWebView();
24
+
25
+ scrollToTop(webView);
26
+
27
+ while (keepScrolling(uiQuery, webView)) {
28
+ TouchUtils.dragQuarterScreenUp(Actions.parentTestCase, InstrumentationBackend.solo.getCurrentActivity());
29
+ }
30
+
31
+ return new Result(isVisible(uiQuery, webView), "");
39
32
  }
40
33
 
34
+ private void scrollToTop(final WebView webView) {
35
+ InstrumentationBackend.instrumentation.runOnMainSync(new Runnable() {
36
+ @Override
37
+ public void run() {
38
+ webView.scrollTo(0, 0);
39
+ }
40
+ });
41
+ }
41
42
 
43
+ private boolean keepScrolling(String uiQuery, WebView webView) {
44
+ int centerY = getCenterY(uiQuery, webView);
45
+ System.out.println("Keep scrolling centerY: "+ centerY);
42
46
 
43
- private Map<String, Object> findFirstRect(String queryResult) {
44
- try {
45
- List<HashMap<String,Object>> p = new ObjectMapper().readValue(queryResult, new TypeReference<List<HashMap<String,Object>>>(){});
46
-
47
- if (p.isEmpty()) {
48
- throw new RuntimeException("No element found");
49
- }
50
- System.out.println(p);
51
- final Map<String, Object> firstRect = QueryHelper.findFirstVisibleRectangle(p);
52
- return firstRect;
53
- } catch (Exception e) {
54
- throw new RuntimeException(e);
55
- }
47
+ int[] location = new int[2];
48
+ webView.getLocationOnScreen(location);
49
+ int top = location[1];
50
+ int bottom = top + webView.getHeight();
56
51
 
57
- }
52
+ System.out.println("isVisible top: "+ top);
53
+ System.out.println("isVisible bottom: "+ bottom);
54
+
55
+ return centerY > bottom;
56
+ }
57
+
58
+ private boolean isVisible(String uiQuery, WebView webView) {
59
+ int centerY = getCenterY(uiQuery, webView);
60
+ System.out.println("isVisible centerY: "+ centerY);
61
+
62
+ int[] location = new int[2];
63
+ webView.getLocationOnScreen(location);
64
+ int top = location[1];
65
+ int bottom = top + webView.getHeight();
66
+ System.out.println("isVisible top: "+ top);
67
+ System.out.println("isVisible bottom: "+ bottom);
68
+
69
+ return top < centerY && centerY < bottom;
70
+ }
58
71
 
59
- private boolean isVisible(Map<String, Object> rectangle, CalabashChromeClient calabashChromeClient) {
60
- WebView webView = calabashChromeClient.getWebView();
61
- int windowTop = webView.getScrollY();
62
- int windowBottom = webView.getScrollY() + webView.getHeight();
63
- int centerY = (int) ((Integer)rectangle.get("center_y") * webView.getScale());
72
+ @SuppressWarnings({ "rawtypes", "unchecked" })
73
+ private int getCenterY(String uiQuery, WebView webView) {
74
+ List queryResult = new sh.calaba.instrumentationbackend.query.Query(uiQuery).executeQuery();
75
+ if (queryResult.isEmpty()) {
76
+ throw new RuntimeException("Query found no elements");
77
+ }
78
+ final Map<String, Object> firstVisibleRectangle = QueryHelper.findFirstVisibleRectangle(queryResult);
64
79
 
65
- return windowTop < centerY && centerY < windowBottom;
80
+ return Math.round((Float)firstVisibleRectangle.get("center_y"));
66
81
  }
67
82
 
68
83
  @Override
@@ -1,42 +1,67 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import sh.calaba.instrumentationbackend.InstrumentationBackend;
4
+ import java.util.ArrayList;
5
+ import java.util.List;
6
+ import java.util.concurrent.Callable;
7
+
5
8
  import sh.calaba.instrumentationbackend.Result;
6
- import sh.calaba.instrumentationbackend.TestHelpers;
7
9
  import sh.calaba.instrumentationbackend.actions.Action;
10
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
11
+ import sh.calaba.instrumentationbackend.query.ast.UIQueryUtils;
8
12
  import android.webkit.WebView;
9
13
 
10
14
 
11
15
  public class SetPropertyByCssSelector implements Action {
12
16
 
13
- @Override
17
+ @SuppressWarnings({ "unchecked", "rawtypes" })
18
+ @Override
14
19
  public Result execute(String... args) {
15
- String cssSelector = args[0];
16
- String propertyName = args[1];
17
- String value = args[2];
18
-
19
- for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
20
- WebView webView = ccc.getWebView();
20
+ final String cssSelector = args[0];
21
+ final String propertyName = args[1];
22
+ final String value = args[2];
23
+
24
+ List<WebFuture> webResults = (List<WebFuture>) UIQueryUtils.evaluateSyncInMainThread(new Callable() {
21
25
 
22
- final String assignment = "document.querySelector(\"" + cssSelector + "\")." + propertyName + " = " + value + ";";
23
- System.out.println(assignment);
24
- webView.loadUrl("javascript:(function() {" +
25
- assignment +
26
- "prompt('calabash:true');" +
27
- "})()");
28
- String r = ccc.getResult();
29
- System.out.println("setPropertyByCssSelector: " + r);
30
- if ("true".equals(r)) {
31
- TestHelpers.wait(0.3);
32
- return Result.successResult();
33
- }
34
- }
26
+ public Object call() throws Exception {
27
+
28
+ List<WebFuture> webResults = new ArrayList();
29
+ for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
30
+ WebView webView = ccc.getWebView();
31
+
32
+ final String assignment = "document.querySelector(\"" + cssSelector + "\")." + propertyName + " = " + value + ";";
33
+ System.out.println(assignment);
34
+ webView.loadUrl("javascript:(function() {" +
35
+ assignment +
36
+ "prompt('calabash:true');" +
37
+ "})()");
38
+ webResults.add(ccc.getResult());
39
+ }
35
40
 
36
- return new Result(false,"No WebView found");
37
- }
41
+ return webResults;
42
+
43
+ }
44
+ });
45
+
46
+ List<String> allResults = new ArrayList<String>(webResults.size());
47
+ boolean success = false;
48
+ for (WebFuture f : webResults) {
49
+ String result = f.getAsString();
50
+ allResults.add(result);
51
+ if ("true".equals(result)) {
52
+ success = true;
53
+ }
54
+ }
55
+
56
+ if (allResults.size() == 0) {
57
+ return new Result(false, "No WebView found");
58
+ }
59
+ else {
60
+ return new Result(success, allResults);
61
+ }
62
+ }
38
63
 
39
- @Override
64
+ @Override
40
65
  public String key() {
41
66
  return "set_property_by_css_selector";
42
67
  }
@@ -1,14 +1,12 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import java.util.HashMap;
5
4
  import java.util.List;
6
5
  import java.util.Map;
7
6
 
8
7
  import sh.calaba.instrumentationbackend.Result;
9
8
  import sh.calaba.instrumentationbackend.actions.Action;
10
- import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
11
- import sh.calaba.org.codehaus.jackson.type.TypeReference;
9
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
12
10
 
13
11
 
14
12
  public class SetText implements Action {
@@ -18,26 +16,25 @@ public class SetText implements Action {
18
16
  * args[1]: xpath or css selector
19
17
  * args[2]: text to enter into the first selected element
20
18
  */
21
- @Override
22
- public Result execute(String... args) {
23
- try {
24
- String queryResult = QueryHelper.executeJavascriptInWebview("calabash.js", args[1], args[0]);
25
- List<HashMap<String,Object>> p = new ObjectMapper().readValue(queryResult, new TypeReference<List<HashMap<String,Object>>>(){});
26
-
27
- if (p.isEmpty()) {
28
- throw new RuntimeException("No element found");
29
- }
30
- Map<String, Object> firstElement = QueryHelper.findFirstVisibleElement(p);
31
- //TODO: Hack! Should be serialized instead of removed
32
- firstElement.remove("class");
33
- firstElement.remove("html");
34
- String firstElementJson = QueryHelper.toJsonString(firstElement);
35
-
36
- String result = QueryHelper.executeJavascriptInWebview("set_text.js", firstElementJson, args[2]);
37
- return new Result(true, result);
38
- } catch (Exception e) {
39
- throw new RuntimeException(e);
19
+ @SuppressWarnings({ "rawtypes", "unchecked"})
20
+ @Override
21
+ public Result execute(final String... args) {
22
+ final String uiQuery = "webView " + args[0] + ":'"+ args[1] + "'";
23
+ List queryResult = new sh.calaba.instrumentationbackend.query.Query(uiQuery).executeQuery();
24
+ if (queryResult.isEmpty()) {
25
+ throw new RuntimeException("No element found");
40
26
  }
27
+ Map<String, Object> firstElement = QueryHelper.findFirstVisibleElement(queryResult);
28
+ //TODO: Hack! Should be serialized instead of removed
29
+ CalabashChromeClient client = CalabashChromeClient.findAndPrepareWebViews().get(0);
30
+ firstElement.remove("class");
31
+ firstElement.remove("webView");
32
+ firstElement.remove("html");
33
+ String firstElementJson = QueryHelper.toJsonString(firstElement);
34
+
35
+ WebFuture result = QueryHelper.executeAsyncJavascriptInWebviews(client.getWebView(),"set_text.js", firstElementJson, args[2]);
36
+
37
+ return new Result(true,result.getAsString());
41
38
  }
42
39
 
43
40
  @Override
@@ -0,0 +1,40 @@
1
+ package sh.calaba.instrumentationbackend.query;
2
+
3
+ import java.util.concurrent.ExecutionException;
4
+ import java.util.concurrent.Future;
5
+ import java.util.concurrent.TimeUnit;
6
+ import java.util.concurrent.TimeoutException;
7
+
8
+ public class CompletedFuture<T> implements Future<T> {
9
+ private final T result;
10
+
11
+ public CompletedFuture(final T result) {
12
+ this.result = result;
13
+ }
14
+
15
+ @Override
16
+ public boolean cancel(final boolean b) {
17
+ return false;
18
+ }
19
+
20
+ @Override
21
+ public boolean isCancelled() {
22
+ return false;
23
+ }
24
+
25
+ @Override
26
+ public boolean isDone() {
27
+ return true;
28
+ }
29
+
30
+ @Override
31
+ public T get() throws InterruptedException, ExecutionException {
32
+ return this.result;
33
+ }
34
+
35
+ @Override
36
+ public T get(long timeout, TimeUnit unit) throws InterruptedException,
37
+ ExecutionException, TimeoutException {
38
+ return get();
39
+ }
40
+ }
@@ -0,0 +1,201 @@
1
+ package sh.calaba.instrumentationbackend.query;
2
+
3
+ import java.lang.reflect.Method;
4
+ import java.util.List;
5
+ import java.util.concurrent.atomic.AtomicReference;
6
+
7
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
8
+
9
+ public class InvocationOperation implements Operation {
10
+
11
+ private final String methodName;
12
+ @SuppressWarnings("rawtypes")
13
+ private final List arguments;
14
+ private final Class<?>[] classes;
15
+ private final Class<?>[] classesWithCharseq;
16
+
17
+ @SuppressWarnings("rawtypes")
18
+ public InvocationOperation(String methodName, List arguments) {
19
+ this.methodName = methodName;
20
+ this.arguments = arguments;
21
+ this.classes = extractArgumentTypes(false);
22
+ this.classesWithCharseq = extractArgumentTypes(true);
23
+ }
24
+
25
+ @SuppressWarnings("rawtypes")
26
+ @Override
27
+ public Object apply(final Object o) throws Exception {
28
+ final AtomicReference ref = new AtomicReference();
29
+ final AtomicReference<Exception> refEx = new AtomicReference<Exception>();
30
+
31
+ InstrumentationBackend.instrumentation.runOnMainSync(new Runnable() {
32
+
33
+ @SuppressWarnings("unchecked")
34
+ @Override
35
+ public void run() {
36
+ try {
37
+ Method method = o.getClass().getMethod(InvocationOperation.this.methodName, InvocationOperation.this.classes);
38
+ method.setAccessible(true);
39
+ try {
40
+ Object result;
41
+ if( method.getReturnType().equals(Void.TYPE)){
42
+ invokeMethod(o, method);
43
+ result = "<VOID>";
44
+ }
45
+ else {
46
+ result = invokeMethod(o, method);
47
+ }
48
+ ref.set(result);
49
+ return;
50
+ } catch (Exception e) {
51
+ refEx.set(e);
52
+ return;
53
+ }
54
+ } catch (NoSuchMethodException e) {
55
+ try {
56
+ Method method = o.getClass().getMethod(InvocationOperation.this.methodName, InvocationOperation.this.classesWithCharseq);
57
+ method.setAccessible(true);
58
+ try {
59
+ Object result;
60
+ if( method.getReturnType().equals(Void.TYPE)){
61
+ invokeMethod(o, method);
62
+ result = "<VOID>";
63
+ }
64
+ else {
65
+ result = invokeMethod(o, method);
66
+ }
67
+ ref.set(result);
68
+ return;
69
+ } catch (Exception ee) {
70
+ refEx.set(e);
71
+ return;
72
+ }
73
+ } catch (NoSuchMethodException ee) {
74
+ System.out.println("Method not found with correct argument types. Trying to type convert.");
75
+ }
76
+ }
77
+ //Warning: Slow path
78
+ Method[] methods = o.getClass().getMethods();
79
+ for (Method m : methods) {
80
+ if (m.getName().equals(InvocationOperation.this.methodName)) {
81
+ Class<?>[] parameterTypes = m.getParameterTypes();
82
+ if (parameterTypes.length == InvocationOperation.this.classes.length && areArgumentsConvertibleTo(parameterTypes)) {
83
+ try {
84
+ Object result;
85
+ if( m.getReturnType().equals(Void.TYPE)){
86
+ invokeMethod(o, m);
87
+ result = "<VOID>";
88
+ }
89
+ else {
90
+ result = invokeMethod(o, m);
91
+ }
92
+ ref.set(result);
93
+ return;
94
+ } catch (Exception e) {
95
+ refEx.set(e);
96
+ return;
97
+ }
98
+
99
+ }
100
+ }
101
+ }
102
+
103
+ }
104
+
105
+ });
106
+
107
+ if (refEx.get() != null) {
108
+ throw refEx.get();
109
+ }
110
+ return ref.get();
111
+ }
112
+
113
+ @SuppressWarnings("rawtypes")
114
+ private Class[] extractArgumentTypes(boolean convertStringCharSeq) {
115
+ Class[] types = new Class[arguments.size()];
116
+ for (int i=0;i<arguments.size(); i++) {
117
+ Object o = arguments.get(i);
118
+ if (o != null) {
119
+ Class<?> c = o.getClass();
120
+ if (convertStringCharSeq && c.equals(String.class)) {
121
+ c = CharSequence.class;//Android API specific optimization
122
+ }
123
+ types[i] = c;
124
+ }
125
+ else {
126
+ types[i] = null;
127
+ }
128
+ }
129
+ return types;
130
+ }
131
+
132
+ //parameterType.length == this.classes.length
133
+ //Note: right now we don't do any clever mapping, we
134
+ //only use Java's sub type relation: isAssigableFrom
135
+ private boolean areArgumentsConvertibleTo(Class<?>[] parameterTypes) {
136
+ for (int i=0; i < parameterTypes.length; i++) {
137
+ Class<?> typei = parameterTypes[i];
138
+ if (this.classes[i] == null) {
139
+ if (typei.isPrimitive()) {
140
+ //Can't pass null as primitive
141
+ return false;
142
+ }
143
+ continue; //can always pass null (unless primitive)
144
+ }
145
+ if (!typei.isAssignableFrom(this.classes[i])) {
146
+ return false;
147
+ }
148
+ }
149
+ return true;
150
+ }
151
+
152
+ private Object invokeMethod(Object o, Method m) throws Exception {
153
+ List<?> a = this.arguments;
154
+ int size = a.size();
155
+ switch(size) {
156
+ case 0:
157
+ return m.invoke(o);
158
+ case 1:
159
+ return m.invoke(o,a.get(0));
160
+ case 2:
161
+ return m.invoke(o,a.get(0),a.get(1));
162
+ case 3:
163
+ return m.invoke(o,a.get(0),a.get(1),a.get(2));
164
+ case 4:
165
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3));
166
+ case 5:
167
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4));
168
+ case 6:
169
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5));
170
+ case 7:
171
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6));
172
+ case 8:
173
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7));
174
+ case 9:
175
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8));
176
+ case 10:
177
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9));
178
+ case 11:
179
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10));
180
+ case 12:
181
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11));
182
+ case 13:
183
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11),a.get(12));
184
+ case 14:
185
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11),a.get(12),a.get(13));
186
+ case 15:
187
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11),a.get(12),a.get(13),a.get(14));
188
+ case 16:
189
+ return m.invoke(o,a.get(0),a.get(1),a.get(2),a.get(3),a.get(4),a.get(5),a.get(6),a.get(7),a.get(8),a.get(9),a.get(10),a.get(11),a.get(12),a.get(13),a.get(14),a.get(15));
190
+ }
191
+ throw new UnsupportedOperationException("Method with more than 16 arguments are not supported");
192
+
193
+ }
194
+
195
+
196
+ @Override
197
+ public String getName() {
198
+ return "InvocationOp["+this.methodName+", arguments = " + this.arguments + "]";
199
+ }
200
+
201
+ }