1 /*
2 * Copyright 2003-2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.codehaus.groovy.runtime;
17
18 import groovy.lang;
19 import org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack;
20 import org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed;
21 import org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack;
22 import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
23 import org.codehaus.groovy.runtime.wrappers.GroovyObjectWrapper;
24 import org.codehaus.groovy.runtime.wrappers.PojoWrapper;
25 import org.codehaus.groovy.runtime.wrappers.Wrapper;
26
27 import java.util;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31 /**
32 * A static helper class to interface bytecode and runtime
33 *
34 * @author Jochen Theodorou
35 * @version $Revision: 14182 $
36 */
37 public class ScriptBytecodeAdapter {
38 public static final Object[] EMPTY_ARGS = {};
39 private static final Integer ZERO = Integer.valueOf(0);
40 private static final Integer MINUS_ONE = Integer.valueOf(-1);
41 private static final Integer ONE = Integer.valueOf(1);
42
43 // --------------------------------------------------------
44 // exception handling
45 // --------------------------------------------------------
46 public static Throwable unwrap(GroovyRuntimeException gre) {
47 if (gre instanceof MissingPropertyExceptionNoStack) {
48 MissingPropertyExceptionNoStack noStack = (MissingPropertyExceptionNoStack) gre;
49 return new MissingPropertyException(noStack.getProperty(), noStack.getType());
50 }
51
52 if (gre instanceof MissingMethodExceptionNoStack) {
53 MissingMethodExceptionNoStack noStack = (MissingMethodExceptionNoStack) gre;
54 return new MissingMethodException(noStack.getMethod(), noStack.getType(), noStack.getArguments(), noStack.isStatic());
55 }
56
57 Throwable th = gre;
58 if (th.getCause() != null && th.getCause() != gre) th = th.getCause();
59 if (th != gre && (th instanceof GroovyRuntimeException)) return unwrap((GroovyRuntimeException) th);
60 return th;
61 }
62
63 // --------------------------------------------------------
64 // methods for this
65 // --------------------------------------------------------
66 public static Object invokeMethodOnCurrentN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
67 Object result = null;
68 boolean intercepting = receiver instanceof GroovyInterceptable;
69 try {
70 try {
71 // if it's a pure interceptable object (even intercepting toString(), clone(), ...)
72 if (intercepting) {
73 result = receiver.invokeMethod(messageName, messageArguments);
74 }
75 //else if there's a statically typed method or a GDK method
76 else {
77 result = receiver.getMetaClass().invokeMethod(senderClass, receiver, messageName, messageArguments, false, true);
78 }
79 } catch (MissingMethodException e) {
80 if (e instanceof MissingMethodExecutionFailed) {
81 throw (MissingMethodException)e.getCause();
82 } else if (!intercepting && receiver.getClass() == e.getType() && e.getMethod().equals(messageName)) {
83 // in case there's nothing else, invoke the object's own invokeMethod()
84 result = receiver.invokeMethod(messageName, messageArguments);
85 } else {
86 throw e;
87 }
88 }
89 } catch (GroovyRuntimeException gre) {
90 throw unwrap(gre);
91 }
92 return result;
93 }
94
95 public static Object invokeMethodOnCurrentNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
96 return invokeMethodOnCurrentN(senderClass, receiver, messageName, messageArguments);
97 }
98
99 public static Object invokeMethodOnCurrentNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
100 List answer = new ArrayList();
101 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
102 answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
103 }
104 return answer;
105 }
106
107 public static Object invokeMethodOnCurrent0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
108 return invokeMethodOnCurrentN(senderClass, receiver, messageName, EMPTY_ARGS);
109 }
110
111 public static Object invokeMethodOnCurrent0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
112 return invokeMethodOnCurrentNSafe(senderClass, receiver, messageName, EMPTY_ARGS);
113 }
114
115 public static Object invokeMethodOnCurrent0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
116 return invokeMethodOnCurrentNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS);
117 }
118
119 // --------------------------------------------------------
120 // methods for super
121 // --------------------------------------------------------
122 public static Object invokeMethodOnSuperN(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
123 MetaClass metaClass = receiver.getMetaClass();
124 // ignore interception and missing method fallback
125 Object result = null;
126 try {
127 result = metaClass.invokeMethod(senderClass, receiver, messageName, messageArguments, true, true);
128 } catch (GroovyRuntimeException gre) {
129 throw unwrap(gre);
130 }
131 return result;
132 }
133
134 public static Object invokeMethodOnSuperNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
135 return invokeMethodOnSuperN(senderClass, receiver, messageName, messageArguments);
136 }
137
138 public static Object invokeMethodOnSuperNSpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
139 List answer = new ArrayList();
140 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
141 answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
142 }
143 return answer;
144 }
145
146 public static Object invokeMethodOnSuper0(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
147 return invokeMethodOnSuperN(senderClass, receiver, messageName, EMPTY_ARGS);
148 }
149
150 public static Object invokeMethodOnSuper0Safe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
151 return invokeMethodOnSuperNSafe(senderClass, receiver, messageName, EMPTY_ARGS);
152 }
153
154 public static Object invokeMethodOnSuper0SpreadSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
155 return invokeMethodOnSuperNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS);
156 }
157
158 // --------------------------------------------------------
159 // normal method invocation
160 // --------------------------------------------------------
161 public static Object invokeMethodN(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable {
162 try {
163 return InvokerHelper.invokeMethod(receiver, messageName, messageArguments);
164 } catch (GroovyRuntimeException gre) {
165 throw unwrap(gre);
166 }
167 }
168
169 public static Object invokeMethodNSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable {
170 if (receiver == null) return null;
171 return invokeMethodN(senderClass, receiver, messageName, messageArguments);
172 }
173
174 public static Object invokeMethodNSpreadSafe(Class senderClass, Object receiver, String messageName, Object[] messageArguments) throws Throwable {
175 if (receiver == null) return null;
176 List answer = new ArrayList();
177 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
178 answer.add(invokeMethodNSafe(senderClass, it.next(), messageName, messageArguments));
179 }
180 return answer;
181 }
182
183 private static Object[] getBoxedItems(Object receiver) {
184 return DefaultTypeTransformation.primitiveArrayToList(receiver).toArray();
185 }
186
187 public static Object invokeMethod0(Class senderClass, Object receiver, String messageName) throws Throwable {
188 return invokeMethodN(senderClass, receiver, messageName, EMPTY_ARGS);
189 }
190
191 public static Object invokeMethod0Safe(Class senderClass, Object receiver, String messageName) throws Throwable {
192 if (receiver == null) return null;
193 return invokeMethodNSafe(senderClass, receiver, messageName, EMPTY_ARGS);
194 }
195
196 public static Object invokeMethod0SpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
197 return invokeMethodNSpreadSafe(senderClass, receiver, messageName, EMPTY_ARGS);
198 }
199
200 // --------------------------------------------------------
201 // static normal method invocation
202 // --------------------------------------------------------
203 public static Object invokeStaticMethodN(Class senderClass, Class receiver, String messageName, Object[] messageArguments) throws Throwable {
204 try {
205 return InvokerHelper.invokeStaticMethod(receiver, messageName, messageArguments);
206 } catch (GroovyRuntimeException gre) {
207 throw unwrap(gre);
208 }
209 }
210
211 public static Object invokeStaticMethod0(Class senderClass, Class receiver, String messageName) throws Throwable {
212 return invokeStaticMethodN(senderClass, receiver, messageName, EMPTY_ARGS);
213 }
214
215 // --------------------------------------------------------
216 // normal constructor invocation (via new)
217 // --------------------------------------------------------
218 public static Object invokeNewN(Class senderClass, Class receiver, Object arguments) throws Throwable {
219 try {
220 return InvokerHelper.invokeConstructorOf(receiver, arguments);
221 } catch (GroovyRuntimeException gre) {
222 throw unwrap(gre);
223 }
224 }
225
226 public static Object invokeNew0(Class senderClass, Class receiver) throws Throwable {
227 return invokeNewN(senderClass, receiver, EMPTY_ARGS);
228 }
229
230 // --------------------------------------------------------
231 // special constructor invocation (via this/super)
232 // --------------------------------------------------------
233
234 public static int selectConstructorAndTransformArguments(Object[] arguments, int numberOfConstructors, Class which) throws Throwable {
235 MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(which);
236 try {
237 return metaClass.selectConstructorAndTransformArguments(numberOfConstructors, arguments);
238 } catch (GroovyRuntimeException gre) {
239 throw unwrap(gre);
240 }
241 }
242
243 // --------------------------------------------------------
244 // field handling super: get
245 // --------------------------------------------------------
246
247 public static Object getFieldOnSuper(Class senderClass, Object receiver, String messageName) throws Throwable {
248 try {
249 if (receiver instanceof Class) {
250 return InvokerHelper.getAttribute(receiver, messageName);
251 } else {
252 MetaClass mc = ((GroovyObject) receiver).getMetaClass();
253 return mc.getAttribute(senderClass, receiver, messageName, true);
254 }
255 } catch (GroovyRuntimeException gre) {
256 throw unwrap(gre);
257 }
258 }
259
260 public static Object getFieldOnSuperSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
261 return getFieldOnSuper(senderClass, receiver, messageName);
262 }
263
264 public static Object getFieldOnSuperSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
265 List answer = new ArrayList();
266 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
267 answer.add(getFieldOnSuper(senderClass, it.next(), messageName));
268 }
269 return answer;
270 }
271
272 // --------------------------------------------------------
273 // field handling super: set
274 // --------------------------------------------------------
275
276 public static void setFieldOnSuper(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
277 try {
278 if (receiver instanceof Class) {
279 InvokerHelper.setAttribute(receiver, messageName, messageArgument);
280 } else {
281 MetaClass mc = ((GroovyObject) receiver).getMetaClass();
282 mc.setAttribute(senderClass, receiver, messageName, messageArgument, true, true);
283 }
284 } catch (GroovyRuntimeException gre) {
285 throw unwrap(gre);
286 }
287 }
288
289 public static void setFieldOnSuperSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
290 setFieldOnSuper(messageArgument, senderClass, receiver, messageName);
291 }
292
293 public static void setFieldOnSuperSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
294 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
295 setFieldOnSuper(messageArgument, senderClass, it.next(), messageName);
296 }
297 }
298
299 // --------------------------------------------------------
300 // normal field handling : get
301 // --------------------------------------------------------
302
303 public static Object getField(Class senderClass, Object receiver, String messageName) throws Throwable {
304 try {
305 return InvokerHelper.getAttribute(receiver, messageName);
306 } catch (GroovyRuntimeException gre) {
307 throw unwrap(gre);
308 }
309 }
310
311 public static Object getFieldSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
312 if (receiver == null) return null;
313 return getField(senderClass, receiver, messageName);
314 }
315
316 public static Object getFieldSpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
317 if (receiver == null) return null;
318 List answer = new ArrayList();
319 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
320 answer.add(getFieldSafe(senderClass, it.next(), messageName));
321 }
322 return answer;
323 }
324
325 // --------------------------------------------------------
326 // normal field handling : set
327 // --------------------------------------------------------
328
329 public static void setField(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
330 try {
331 InvokerHelper.setAttribute(receiver, messageName, messageArgument);
332 } catch (GroovyRuntimeException gre) {
333 throw unwrap(gre);
334 }
335 }
336
337 public static void setFieldSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
338 if (receiver == null) return;
339 setField(messageArgument, senderClass, receiver, messageName);
340 }
341
342 public static void setFieldSpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
343 if (receiver == null) return;
344 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
345 setFieldSafe(messageArgument, senderClass, it.next(), messageName);
346 }
347 }
348
349 // --------------------------------------------------------
350 // normal GroovyObject field handling : get
351 // --------------------------------------------------------
352
353 public static Object getGroovyObjectField(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
354 try {
355 return receiver.getMetaClass().getAttribute(receiver, messageName);
356 } catch (GroovyRuntimeException gre) {
357 throw unwrap(gre);
358 }
359 }
360
361 public static Object getGroovyObjectFieldSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
362 if (receiver == null) return null;
363 try {
364 return receiver.getMetaClass().getAttribute(receiver, messageName);
365 } catch (GroovyRuntimeException gre) {
366 throw unwrap(gre);
367 }
368 }
369
370 public static Object getGroovyObjectFieldSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
371 if (receiver == null) return null;
372 List answer = new ArrayList();
373 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
374 answer.add(getFieldSafe(senderClass, it.next(), messageName));
375 }
376 return answer;
377 }
378
379 // --------------------------------------------------------
380 // normal field handling : set
381 // --------------------------------------------------------
382
383 public static void setGroovyObjectField(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
384 try {
385 receiver.getMetaClass().setAttribute(receiver, messageName, messageArgument);
386 } catch (GroovyRuntimeException gre) {
387 throw unwrap(gre);
388 }
389 }
390
391 public static void setGroovyObjectFieldSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
392 if (receiver == null) return;
393 try {
394 receiver.getMetaClass().setAttribute(receiver, messageName, messageArgument);
395 } catch (GroovyRuntimeException gre) {
396 throw unwrap(gre);
397 }
398 }
399
400 public static void setGroovyObjectFieldSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
401 if (receiver == null) return;
402 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
403 setFieldSafe(messageArgument, senderClass, it.next(), messageName);
404 }
405 }
406
407 // --------------------------------------------------------
408 // Property handling super: get
409 // --------------------------------------------------------
410
411 public static Object getPropertyOnSuper(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
412 return invokeMethodOnSuperN(senderClass, receiver, "getProperty", new Object[]{messageName});
413 }
414
415 public static Object getPropertyOnSuperSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
416 return getPropertyOnSuper(senderClass, receiver, messageName);
417 }
418
419 public static Object getPropertyOnSuperSpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
420 List answer = new ArrayList();
421 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
422 answer.add(getPropertySafe(senderClass, it.next(), messageName));
423 }
424 return answer;
425 }
426
427 // --------------------------------------------------------
428 // Property handling super: set
429 // --------------------------------------------------------
430
431 public static void setPropertyOnSuper(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
432 try {
433 InvokerHelper.setAttribute(receiver, messageName, messageArgument);
434 } catch (GroovyRuntimeException gre) {
435 throw unwrap(gre);
436 }
437 }
438
439 public static void setPropertyOnSuperSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
440 setPropertyOnSuper(messageArgument, senderClass, receiver, messageName);
441 }
442
443 public static void setPropertyOnSuperSpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
444 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
445 setPropertySafe(messageArgument, senderClass, it.next(), messageName);
446 }
447 }
448
449 // --------------------------------------------------------
450 // normal Property handling : get
451 // --------------------------------------------------------
452
453 public static Object getProperty(Class senderClass, Object receiver, String messageName) throws Throwable {
454 try {
455 return InvokerHelper.getProperty(receiver, messageName);
456 } catch (GroovyRuntimeException gre) {
457 throw unwrap(gre);
458 }
459 }
460
461 public static Object getPropertySafe(Class senderClass, Object receiver, String messageName) throws Throwable {
462 if (receiver == null) return null;
463 return getProperty(senderClass, receiver, messageName);
464 }
465
466 public static Object getPropertySpreadSafe(Class senderClass, Object receiver, String messageName) throws Throwable {
467 if (receiver == null) return null;
468
469 List answer = new ArrayList();
470 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
471 answer.add(getPropertySafe(senderClass, it.next(), messageName));
472 }
473 return answer;
474 }
475
476 // --------------------------------------------------------
477 // normal Property handling : set
478 // --------------------------------------------------------
479
480 public static void setProperty(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
481 try {
482 if (receiver==null) receiver=NullObject.getNullObject();
483 InvokerHelper.setProperty(receiver, messageName, messageArgument);
484 } catch (GroovyRuntimeException gre) {
485 throw unwrap(gre);
486 }
487 }
488
489 public static void setPropertySafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
490 if (receiver == null) return;
491 setProperty(messageArgument, senderClass, receiver, messageName);
492 }
493
494 public static void setPropertySpreadSafe(Object messageArgument, Class senderClass, Object receiver, String messageName) throws Throwable {
495 if (receiver == null) return;
496
497 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
498 setPropertySafe(messageArgument, senderClass, it.next(), messageName);
499 }
500 }
501
502 // --------------------------------------------------------
503 // normal GroovyObject Property handling : get
504 // --------------------------------------------------------
505
506 public static Object getGroovyObjectProperty(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
507 return receiver.getProperty(messageName);
508 }
509
510 public static Object getGroovyObjectPropertySafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
511 if (receiver == null) return null;
512 return getGroovyObjectProperty(senderClass, receiver, messageName);
513 }
514
515 public static Object getGroovyObjectPropertySpreadSafe(Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
516 if (receiver == null) return null;
517
518 List answer = new ArrayList();
519 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
520 answer.add(getPropertySafe(senderClass, it.next(), messageName));
521 }
522 return answer;
523 }
524
525 // --------------------------------------------------------
526 // normal GroovyObject Property handling : set
527 // --------------------------------------------------------
528
529 public static void setGroovyObjectProperty(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
530 receiver.setProperty(messageName, messageArgument);
531 }
532
533 public static void setGroovyObjectPropertySafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
534 if (receiver == null) return;
535 receiver.setProperty(messageName, messageArgument);
536 }
537
538 public static void setGroovyObjectPropertySpreadSafe(Object messageArgument, Class senderClass, GroovyObject receiver, String messageName) throws Throwable {
539 if (receiver == null) return;
540
541 for (Iterator it = InvokerHelper.asIterator(receiver); it.hasNext();) {
542 setPropertySafe(messageArgument, senderClass, it.next(), messageName);
543 }
544 }
545
546 // **********************************************************************************
547 // **********************************************************************************
548 // ************** methods not covered by the new MOP **************
549 // **********************************************************************************
550 // **********************************************************************************
551
552 // --------------------------------------------------------
553 // Closures
554 // --------------------------------------------------------
555
556 /**
557 * Returns the method pointer for the given object name
558 *
559 * @param object the object containing the method
560 * @param methodName the name of the method of interest
561 * @return the resulting Closure
562 */
563 public static Closure getMethodPointer(Object object, String methodName) {
564 return InvokerHelper.getMethodPointer(object, methodName);
565 }
566
567 // TODO: set sender class
568 public static Object invokeClosure(Object closure, Object[] arguments) throws Throwable {
569 return invokeMethodN(closure.getClass(), closure, "call", arguments);
570 }
571
572 // --------------------------------------------------------
573 // type conversion
574 // --------------------------------------------------------
575
576 /**
577 * Provides a hook for type coercion of the given object to the required type
578 *
579 * @param type of object to convert the given object to
580 * @param object the object to be converted
581 * @return the original object or a new converted value
582 * @throws Throwable if the coercion fails
583 */
584 public static Object asType(Object object, Class type) throws Throwable {
585 if (object == null) object = NullObject.getNullObject();
586 return invokeMethodN(object.getClass(), object, "asType", new Object[]{type});
587 }
588
589 /**
590 * Provides a hook for type casting of the given object to the required type
591 *
592 * @param type of object to convert the given object to
593 * @param object the object to be converted
594 * @return the original object or a new converted value
595 * @throws Throwable if the type casting fails
596 */
597 public static Object castToType(Object object, Class type) throws Throwable {
598 return DefaultTypeTransformation.castToType(object, type);
599 }
600
601 public static Tuple createTuple(Object[] array) {
602 return new Tuple(array);
603 }
604
605 public static List createList(Object[] values) {
606 return InvokerHelper.createList(values);
607 }
608
609 public static Wrapper createPojoWrapper(Object val, Class clazz) {
610 return new PojoWrapper(val, clazz);
611 }
612
613 public static Wrapper createGroovyObjectWrapper(GroovyObject val, Class clazz) {
614 return new GroovyObjectWrapper(val, clazz);
615 }
616
617 public static Map createMap(Object[] values) {
618 return InvokerHelper.createMap(values);
619 }
620
621
622 //TODO: refactor
623 public static List createRange(Object from, Object to, boolean inclusive) throws Throwable {
624 if (from instanceof Integer && to instanceof Integer) {
625 int ito = (Integer) to;
626 int ifrom = (Integer) from;
627 if (!inclusive) {
628 if (ifrom == ito) {
629 return new EmptyRange((Comparable) from);
630 }
631 if (ifrom > ito) {
632 ito++;
633 } else {
634 ito--;
635 }
636 }
637 return new IntRange(ifrom, ito);
638 }
639 if (!inclusive) {
640 if (compareEqual(from, to)) {
641 return new EmptyRange((Comparable) from);
642 }
643 if (compareGreaterThan(from, to)) {
644 to = invokeMethod0(ScriptBytecodeAdapter.class, to, "next");
645 } else {
646 to = invokeMethod0(ScriptBytecodeAdapter.class, to, "previous");
647 }
648 }
649
650 if (from instanceof Integer && to instanceof Integer)
651 return new IntRange(DefaultTypeTransformation.intUnbox(from), DefaultTypeTransformation.intUnbox(to));
652 else
653 return new ObjectRange((Comparable) from, (Comparable) to);
654 }
655
656 //assert
657 public static void assertFailed(Object expression, Object message) {
658 InvokerHelper.assertFailed(expression, message);
659 }
660
661 //isCase
662 //TODO: set sender class
663 public static boolean isCase(Object switchValue, Object caseExpression) throws Throwable {
664 if (caseExpression == null) {
665 return switchValue == null;
666 }
667 return DefaultTypeTransformation.castToBoolean(invokeMethodN(caseExpression.getClass(), caseExpression, "isCase", new Object[]{switchValue}));
668 }
669
670 //compare
671 public static boolean compareIdentical(Object left, Object right) {
672 return left == right;
673 }
674
675 public static boolean compareEqual(Object left, Object right) {
676 return DefaultTypeTransformation.compareEqual(left, right);
677 }
678
679 public static boolean compareNotEqual(Object left, Object right) {
680 return !compareEqual(left, right);
681 }
682
683 public static Integer compareTo(Object left, Object right) {
684 int answer = DefaultTypeTransformation.compareTo(left, right);
685 if (answer == 0) {
686 return ZERO;
687 } else {
688 return answer > 0 ? ONE : MINUS_ONE;
689 }
690 }
691
692 public static boolean compareLessThan(Object left, Object right) {
693 return compareTo(left, right).intValue() < 0;
694 }
695
696 public static boolean compareLessThanEqual(Object left, Object right) {
697 return compareTo(left, right).intValue() <= 0;
698 }
699
700 public static boolean compareGreaterThan(Object left, Object right) {
701 return compareTo(left, right).intValue() > 0;
702 }
703
704 public static boolean compareGreaterThanEqual(Object left, Object right) {
705 return compareTo(left, right).intValue() >= 0;
706 }
707
708 //regexpr
709 public static Pattern regexPattern(Object regex) {
710 return DefaultGroovyMethods.bitwiseNegate(regex.toString());
711 }
712
713 public static Matcher findRegex(Object left, Object right) throws Throwable {
714 return InvokerHelper.findRegex(left, right);
715 }
716
717 public static boolean matchRegex(Object left, Object right) {
718 return InvokerHelper.matchRegex(left, right);
719 }
720
721
722 //spread expressions
723 public static Object[] despreadList(Object[] args, Object[] spreads, int[] positions) {
724 List ret = new ArrayList();
725 int argsPos = 0;
726 int spreadPos = 0;
727 for (int pos = 0; pos < positions.length; pos++) {
728 for (; argsPos < positions[pos]; argsPos++) {
729 ret.add(args[argsPos]);
730 }
731 Object value = spreads[spreadPos];
732 if (value == null) {
733 ret.add(null);
734 } else if (value instanceof List) {
735 ret.addAll((List) value);
736 } else if (value.getClass().isArray()) {
737 ret.addAll(DefaultTypeTransformation.primitiveArrayToList(value));
738 } else {
739 throw new IllegalArgumentException("cannot spread the type " + value.getClass().getName() + " with value " + value);
740 }
741 spreadPos++;
742 }
743 for (; argsPos < args.length; argsPos++) {
744 ret.add(args[argsPos]);
745 }
746 return ret.toArray();
747 }
748
749 public static Object spreadMap(Object value) {
750 return InvokerHelper.spreadMap(value);
751 }
752
753 public static Object unaryMinus(Object value) throws Throwable {
754 return InvokerHelper.unaryMinus(value);
755 }
756
757 public static Object unaryPlus(Object value) {
758 return InvokerHelper.unaryPlus(value);
759 }
760
761 public static Object bitwiseNegate(Object value) {
762 return InvokerHelper.bitwiseNegate(value);
763 }
764
765 public static MetaClass initMetaClass(Object object) {
766 return InvokerHelper.getMetaClass(object.getClass());
767 }
768 }