Groovy: как получить статически выведенный тип возврата из AST - PullRequest
0 голосов
/ 14 мая 2018

Я использую Groovy, чтобы позволить пользователям создавать сценарии и настраивать определенные части моего Java-приложения. Я использую статическую компиляцию всех пользовательских сценариев.

Мой вопрос: если мой код ожидает получения, например, значение типа boolean, как результат пользовательского сценария, есть ли способ проверить, будет ли предоставленный пользовательский сценарий всегда возвращать булево значение без фактического выполнения сценария? Другими словами, как я могу получить доступ к результатам вывода типов, выполняемых статическим компилятором groovy? Я хотел бы иметь возможность сказать пользователю «эй, ваш скрипт не всегда возвращает логическое значение», пока он редактирует содержимое скрипта.

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Прямого пути нет, но это возможно. Boolean особенно сложен, так как компилятор с радостью применяет все виды приведений типов (например, преобразует int в boolean без жалоб). У меня была точно такая же проблема, и я сделал следующие шаги:

  1. ASTTransformation для установки типа возвращаемого значения в логическое значение (необязательно, был артефактом полуработающей более ранней итерации)
  2. ASTTransformation для материализации всех возвращаемых операторов
  3. TypeCheckingExtension, чтобы посетить ReturnStatements и убедиться, что они имеют тип boolean
  4. ASTTransformation для выполнения статического преобразования типов с помощью TypeCheckingExtension

Для 1:

Расширить ClassCodeVisitorSupport, в visitMethod указать все методы, которые вы хотите вернуть логическое (например, проверить соответствие соглашений об именах)

Установите returnType для MethodNode на ClassHelper.boolean_TYPE

Для 2:

Для тех же методов, что и выше, вызовите org.codehaus.groovy.classgen.ReturnAdder.visitMethod

Для 3:

Расширить AbstractTypeCheckingExtension, переопределить afterVisitMethod. На этом этапе AbstractTypeCheckingExtension выведет нижнюю границу всех выражений внутри метода. Используйте ClassCodeVisitorSupport подкласс и переопределите visitReturnStatement. Используйте getType(statement.expression), чтобы получить предполагаемый тип. Обратите внимание, что это может отличаться от statement.expression.type (тип в соответствии с AST). Вызовите addStaticTypeError для не булева типа.

Для 4:

Продлить StaticTypesTransformation Переопределите newVisitor и создайте новый StaticTypeCheckingVisitor и вызовите addTypeCheckingExtension, чтобы добавить TypeCheckingExtension

Проект GitHub

https://github.com/MeneDev/groovy-dsl-building-blocks-enforce-return-type

Может даже использоваться в качестве зависимости;)

0 голосов
/ 14 мая 2018

Не с "Типичным" groovy - это разница между типизацией groovy во время выполнения и статической типизацией java во время компиляции.

Например, будет ли следующий метод возвращать логическое значение?

def value(v) {
    return v;
}

В версии 2.0, однако, есть аннотация @CompileStatic, которая, я думаю, заставит знать все типы во время компиляции. Не уверен, как бы вы принудительно включили это «Вкл» для кода скрипта вашего клиента.

...