Установка аргументов компилятора в виде списка строк в новом языковом плагине
Я разрабатываю плагин для нового языка, и я пытался добавить поддержку компиляции в компилятор. Я использовал org.gradle.api.tasks.compile.CompileOptions
класс в качестве отправной точки и реализовал свой собственный класс следующим образом:
class SvCompileOptions extends AbstractOptions {
private List<String> compilerArgs = Lists.newArrayList();
@Input
public List<String> getCompilerArgs() {
return compilerArgs;
}
public void setCompilerArgs(List<String> compilerArgs) {
this.compilerArgs = compilerArgs;
}
}
В моем файле build.gradle я попытался сделать следующее:
compileSv {
options.compilerArgs += [ "-foo" ]
}
(compileSv - это задача со свойством options типа SvCompileOptions.)
Я получаю следующую ошибку:
A problem occurred evaluating project ':uvc2'.
> java.lang.AbstractMethodError (no error message)
Если я заменю строку на:
compileSv {
options.compilerArgs.add("-foo")
}
тогда все работает нормально, но это не очень градлеско.
Может кто-нибудь указать, что я делаю не так?
Согласно предложению @tim_yates, я добавил функцию для добавления к compilerArgs
:
class SvCompileOptions extends AbstractOptions {
void compilerArgs(String... args) {
this.compilerArgs.addAll(args as List)
}
}
Согласно предложению @Opal, я создал простой пример:
// File 'build.gradle'
buildscript {
dependencies {
classpath 'com.google.guava:guava:16+'
}
repositories {
mavenCentral()
}
}
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
class SvCompileOptions extends AbstractOptions {
private List<String> compilerArgs = Lists.newArrayList();
@Input
public List<String> getCompilerArgs() {
return compilerArgs;
}
public void setCompilerArgs(List<String> compilerArgs) {
this.compilerArgs = compilerArgs;
}
void compilerArgs(String... args) {
this.compilerArgs.addAll(args as List)
}
}
class SvCompile extends DefaultTask {
@TaskAction
protected void compile() {
println options.compilerArgs
}
@Nested
SvCompileOptions options = new SvCompileOptions()
}
task compileSv(type: SvCompile)
compileSv {
options.compilerArgs 'foo', 'bar'
}
Код добавляет аргументы в пустой список и печатает [foo, bar]
как и ожидалось. Если мы попытаемся перезаписать аргументы, используя следующее:
compileSv {
options.compilerArgs = ['one', 'two']
}
выводится сообщение об ошибке:
* What went wrong:
A problem occurred evaluating root project 'so_compile_options2'.
> SvCompileOptions.setProperty(Ljava/lang/String;Ljava/lang/Object;)V
Я не уверен, почему сообщение об ошибке отличается, когда классы встроены в build.gradle
, но я бы предположил, что это то, что приводит к AbstractMethodError
Я видел.
Как отметил @Opal, эта проблема вызвана тем, что внутри AbstractOptions
учебный класс. Я попытался добавить следующие методы в класс параметров компиляции, но сообщение об ошибке все еще там:
class SvCompileOptions extends AbstractOptions {
private static final ImmutableSet<String> EXCLUDE_FROM_ANT_PROPERTIES =
ImmutableSet.of("compilerArgs");
@Override
protected boolean excludeFromAntProperties(String fieldName) {
return EXCLUDE_FROM_ANT_PROPERTIES.contains(fieldName);
}
// ...
}
Кажется, что функция exclude вообще не вызывается, как будто я добавляю в нее фиктивный отпечаток, который никогда не будет выдан.
2 ответа
После ценной информации от @Opal, которая простирается от AbstractOptions
является источником проблемы и найти проблему на странице Gradle Github, связанную с удалением AbstractOptions
В целом, я думаю, что лучше всего просто не использовать базовый класс.
После интеграции предложения @tim_yates для метода 'append' я перейду к следующей реализации:
class SvCompileOptions {
private List<String> compilerArgs = Lists.newArrayList();
@Input
public List<String> getCompilerArgs() {
return compilerArgs;
}
// Overwrites
public void setCompilerArgs(List<String> compilerArgs) {
this.compilerArgs = compilerArgs;
}
// Appends
void compilerArgs(String... args) {
this.compilerArgs.addAll(args as List)
}
}
Это позволяет пользователю добавлять аргументы:
compileSv {
options.compilerArgs 'foo', 'bar'
}
и перезаписать их
compileSv {
options.compilerArgs = ['one', 'two']
}
Это должно работать
options.compilerArgs << "-foo"
Идиоматический способ сделать это, если вы хотите добавить несколько значений (что вы, вероятно, будете делать в какой-то момент), это изменить свой класс на:
class SvCompileOptions extends AbstractOptions {
@Input
List<String> compilerArgs = Lists.newArrayList();
def args(String... args) {
this.compilerArgs += args.toList()
}
}
Затем вы можете сделать:
compileSv {
options.args "-foo", "-bar"
}