gradle: fileCollection.plus () devuelve la interfaz contradictoria de ArrayList

Aug 21 2020

gradle: fileCollection.plus () devuelve ArrayList interfaz contradictoria.

def foo = files([]);  // foo: gradle FileCollection
println foo.class
foo = foo.plus(sourceSets.main.java.srcDirs);    // foo: java.util.ArrayList
println foo.class

Pero debería devolver un FileCollection:

https://docs.gradle.org/current/javadoc/org/gradle/api/file/FileCollection.html#plus-org.gradle.api.file.FileCollection-

Respuestas

BjørnVester Aug 21 2020 at 10:45

El plusmétodo está sobrecargado y está buscando el incorrecto.

La API para FileCollection.plus a la que se vinculó tiene la firma:

FileCollection plus (colección FileCollection)

Devuelve un FileCollection que contiene la unión de esta colección y la colección dada. La colección devuelta está activa y realiza un seguimiento de los cambios en ambas colecciones de origen.

Pero está pasando un ArrayListcomo parámetro. An ArrayListno es un FileCollection.

Sin embargo, a FileCollectiontambién es an Iterable, por lo que lo que realmente está invocando es el método estándar de Groovy Interable.plus con esta firma:

Colección pública plus (derecho Iterable)

Crea una colección como una unión de dos iterables. Si el iterable de la izquierda es un Conjunto, entonces la colección devuelta será un Conjunto, de lo contrario una Lista. Esta operación siempre creará un nuevo objeto para el resultado, mientras que los operandos permanecen sin cambios.

Debido a que el iterable "izquierdo" no es un Set(es un FileCollection), obtienes un Listrespaldo, y Groovy simplemente usa un ArrayListen la implementación.