Groovy — проверьте код закрытия перед выполнением

У меня есть Groovy script, который позволяет пользователю определять некоторые динамические свойства и методы, а затем выполняет определяемое пользователем закрытие. Скрипт будет выглядеть так:

// init properties and methods dynamically at runtime
context.prop1 = "Some test value"
context.method1 = { String input ->
    "exec " + input.toUpperCase()
}

// "this" is set to the context variable from above
run {
    println method1( prop1 )
}

Таким образом, в начале скрипта context инициализируется с определенными пользователем свойствами (например, prop1) и методами (например, method1). Затем контекст используется в качестве указателя this при закрытии цикла. Я достиг этого путем динамического расширения метакласса контекста и установки контекста в качестве делегата закрытия запуска (с DELEGATE_FIRST в качестве стратегии разрешения).

В настоящее время я борюсь с проверкой типов. Перед выполнением закрытия прогона я хотел бы проверить, действительно ли method1 ожидает prop1. Я просмотрел аннотацию DelegatesTo. , но, похоже, это не работает для динамически расширяемых объектов. Я также играл с AST, но, поскольку мои знания по этой теме ограничены, я не нашел решения. Если то, чего я хочу достичь, возможно, любые указатели в правильном направлении будут очень признательны.


person WeSt    schedule 09.07.2015    source источник


Ответы (1)


Вы хотите добавить метод в контекст во время выполнения, а затем ввести проверку перед выполнением этого метода.

Проверка типов выполняется во время компиляции. То есть до того, как что-либо из вашей программы будет выполнено. Обычно нет никаких шансов, что это когда-либо сможет проверить что-либо, что произойдет только во время выполнения, если у вас нет способа статически объявить это и дать компилятору возможность выполнить проверку. Но это означает, что обычно вам придется выполнять статическую компиляцию.

Один из способов — использовать расширения для проверки типов. , но я думаю, что в вашем случае это может быть излишним. Более простым способом было бы использование модулей расширения. И самым простым способом было бы использовать базовый класс пользовательского скрипта.

Но для любого из этих решений вам понадобится статическая компиляция, чтобы действительно иметь проверку типов, то же самое для DelegatesTo (который больше используется в сочетании с модулями расширения). Для DSL с проверкой типов сочетание расширений проверки типов и модулей расширения может работать очень хорошо. Но вы, конечно, потеряете более динамичные особенности языка и некоторую простоту.

person blackdrag    schedule 09.07.2015