23
23
import groovy .lang .GroovyRuntimeException ;
24
24
import org .codehaus .groovy .reflection .ReflectionCache ;
25
25
import org .codehaus .groovy .reflection .stdclasses .CachedSAMClass ;
26
- import org .codehaus .groovy .runtime .DefaultGroovyMethods ;
27
- import org .codehaus .groovy .runtime .InvokerHelper ;
28
- import org .codehaus .groovy .runtime .InvokerInvocationException ;
29
- import org .codehaus .groovy .runtime .IteratorClosureAdapter ;
30
- import org .codehaus .groovy .runtime .MethodClosure ;
31
- import org .codehaus .groovy .runtime .NullObject ;
32
- import org .codehaus .groovy .runtime .ResourceGroovyMethods ;
33
- import org .codehaus .groovy .runtime .StringGroovyMethods ;
26
+ import org .codehaus .groovy .runtime .*;
34
27
35
28
import java .io .File ;
36
29
import java .io .IOException ;
49
42
import java .util .List ;
50
43
import java .util .Map ;
51
44
import java .util .Objects ;
45
+ import java .util .function .Supplier ;
52
46
53
47
/**
54
48
* Class providing various type conversions, coercions and boxing/unboxing operations.
@@ -248,20 +242,22 @@ private static Object continueCastOnCollection(Object object, Class type) {
248
242
return new LinkedHashSet ((Collection ) object );
249
243
}
250
244
251
- if (object .getClass ().isArray ()) {
252
- Collection answer ;
245
+ Supplier <Collection > newCollection = () -> {
253
246
if (type .isAssignableFrom (ArrayList .class ) && Modifier .isAbstract (type .getModifiers ())) {
254
- answer = new ArrayList ();
247
+ return new ArrayList ();
255
248
} else if (type .isAssignableFrom (LinkedHashSet .class ) && Modifier .isAbstract (type .getModifiers ())) {
256
- answer = new LinkedHashSet ();
249
+ return new LinkedHashSet ();
257
250
} else {
258
251
try {
259
- answer = (Collection ) type .getDeclaredConstructor ().newInstance ();
252
+ return (Collection ) type .getDeclaredConstructor ().newInstance ();
260
253
} catch (Exception e ) {
261
254
throw new GroovyCastException ("Could not instantiate instance of: " + type .getName () + ". Reason: " + e );
262
255
}
263
256
}
257
+ };
264
258
259
+ if (object .getClass ().isArray ()) {
260
+ Collection answer = newCollection .get ();
265
261
// we cannot just wrap in a List as we support primitive type arrays
266
262
int length = Array .getLength (object );
267
263
for (int i = 0 ; i < length ; i += 1 ) {
@@ -270,6 +266,14 @@ private static Object continueCastOnCollection(Object object, Class type) {
270
266
return answer ;
271
267
}
272
268
269
+ if (object instanceof Iterable // GROOVY-11378
270
+ && !(object instanceof Collection )) { // GROOVY-7867
271
+ Collection answer = newCollection .get ();
272
+ Iterator iterator = ((Iterable ) object ).iterator ();
273
+ while (iterator .hasNext ()) answer .add (iterator .next ());
274
+ return answer ;
275
+ }
276
+
273
277
return continueCastOnNumber (object , type );
274
278
}
275
279
@@ -442,22 +446,24 @@ public static Collection asCollection(Object value) {
442
446
return map .entrySet ();
443
447
} else if (value .getClass ().isArray ()) {
444
448
return arrayAsCollection (value );
445
- } else if (value instanceof MethodClosure ) {
446
- MethodClosure method = (MethodClosure ) value ;
447
- IteratorClosureAdapter adapter = new IteratorClosureAdapter (method .getDelegate ());
448
- method .call (adapter );
449
- return adapter .asList ();
450
449
} else if (value instanceof String || value instanceof GString ) {
451
450
return StringGroovyMethods .toList ((CharSequence ) value );
451
+ } else if (value instanceof Iterable ) { // GROOVY-10378
452
+ return DefaultGroovyMethods .toList ((Iterable <?>) value );
453
+ } else if (value instanceof Class && ((Class ) value ).isEnum ()) {
454
+ Object [] values = (Object []) InvokerHelper .invokeMethod (value , "values" , EMPTY_OBJECT_ARRAY );
455
+ return Arrays .asList (values );
452
456
} else if (value instanceof File ) {
453
457
try {
454
458
return ResourceGroovyMethods .readLines ((File ) value );
455
459
} catch (IOException e ) {
456
460
throw new GroovyRuntimeException ("Error reading file: " + value , e );
457
461
}
458
- } else if (value instanceof Class && ((Class ) value ).isEnum ()) {
459
- Object [] values = (Object []) InvokerHelper .invokeMethod (value , "values" , EMPTY_OBJECT_ARRAY );
460
- return Arrays .asList (values );
462
+ } else if (value instanceof MethodClosure ) {
463
+ MethodClosure method = (MethodClosure ) value ;
464
+ IteratorClosureAdapter <?> adapter = new IteratorClosureAdapter <>(method .getDelegate ());
465
+ method .call (adapter );
466
+ return adapter .asList ();
461
467
} else {
462
468
// let's assume it's a collection of 1
463
469
return Collections .singletonList (value );
0 commit comments