Как поместить аннотацию в getter или setter, автоматически сгенерированный Groovy-компилятором? - PullRequest
1 голос
/ 10 июля 2011

Groovy автоматически генерирует геттеры и сеттеры, поэтому, например, когда я набираю:

int someField

, я получаю поле + геттер + сеттер.Теперь я хочу поместить аннотацию на установщик (например, @ Require / Ensures from GContracts):

@Ensures({someField >= 0 && someField <= 100})
int someField

И тогда я получаю сообщение об ошибке: Аннотация groovy.lang.GrUnit не допускается для элемента FIELD - GrUnit иGContracts распознает аннотации только для методов.Обходной путь для этого - явное получение кода:

@Requires({...})
void setSomeField(int newValue) { ... }

Есть ли лучшее решение для этого?В Scala есть элегантное решение для этого: http://www.scala -lang.org / api / current / scala / annotation / target / package.html

Есть ли что-то подобное в Groovy?Или в качестве альтернативы: может быть, есть какое-то решение для GContracts, позволяющее такие аннотации?

Ответы [ 2 ]

4 голосов
/ 12 июля 2011

В Groovy есть 9 фаз компиляции.Получатели и установщики создаются очень поздно на этапах компиляции и создаются после выполнения GContracts.

Если вы хотите, чтобы ваш код выглядел так, как если бы сгенерированные получатели / установщики аннотировались, вам придется самостоятельно создавать пары получатель / установщик и комментировать их.В частности, добавьте два новых FieldNodes в ClassNode (если они еще не существуют).Узел поля - это AnnotatedNode, поэтому вы можете добавлять любые аннотации, какие захотите.Пока вы делаете это в фазе до запуска GContracts, GContracts никогда не должен знать другого.

Тем не менее, это звучит как запрос функции GContracts.

2 голосов
/ 13 июля 2011

Как вы заметили, GContracts не предоставляет аннотации полей (текущая версия: 1.2.4). Он даже не выполняет преобразования AST для синтетических (сгенерированных) методов, которые могли быть добавлены до запуска GContracts.

В двух словах: простой обходной путь - добавить пользовательский метод установки.

С другой стороны, если вы аннотируете класс с @Invariant, содержащим инвариант класса, он предварительно сгенерирует методы установки для всех свойств, чтобы проверить инвариант класса до и после выполнения метода установки.

При этом, возможно, стоит подумать о включении @Requires и @Ensures в этот процесс - я создал проблему: http://gcontracts.lighthouseapp.com/projects/71511-gcontracts-core/tickets/32

...