gradle: fileCollection.plus () retorna uma interface contraditória de ArrayList

Aug 21 2020

gradle: fileCollection.plus () retorna a interface contraditória ArrayList.

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

Mas deve retornar um FileCollection:

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

Respostas

BjørnVester Aug 21 2020 at 10:45

O plusmétodo está sobrecarregado e você está olhando para o método errado.

A API para FileCollection.plus que você vinculou tem a assinatura:

FileCollection plus (coleção FileCollection)

Retorna um FileCollection que contém a união desta coleção com a coleção fornecida. A coleção retornada é ativa e controla as alterações em ambas as coleções de origem.

Mas você está passando um ArrayListcomo parâmetro. Um ArrayListnão é um FileCollection.

No entanto, a FileCollectiontambém é um Iterable, então o que você está realmente invocando é o método padrão do Groovy Interable.plus com esta assinatura:

Coleção pública mais (direito iterável)

Crie uma coleção como uma união de dois iteráveis. Se o iterável esquerdo for um Conjunto, a coleção retornada será um Conjunto, caso contrário, uma Lista. Esta operação sempre criará um novo objeto para o resultado, enquanto os operandos permanecem inalterados.

Como o iterável "esquerdo" não é a Set(é a FileCollection), você recebe um Listretorno e o Groovy simplesmente usa um ArrayListna implementação.