2016-06-21 2 views
1

Можно ли сообщить компилятору о категориях, используемых при выполнении закрытия в groovy?Использовать категории, известные @TypeChecked

Небольшой пример:

class Example { 
    static time = evaluateTime { 
     println 1.minute.from.now 
    } 

    static def evaluateTime(Closure<Void> cl) { 
     GroovyUtil.use(TimeCategory, cl) 
    } 
} 

это работает отлично при выполнении, но IntelliJ будет серо-вне minute и если я добавляю TypeChecked аннотацию, я получаю ошибки компилятора.

@TypeChecked() 
class Example { 
    static time = evaluateTime { 
     println 1.minute.from.now 
    } 

    static def evaluateTime(Closure<Void> cl) { 
     GroovyUtil.use(TimeCategory, cl) 
    } 
} 

В подобном случае я нашел DelegatesTo аннотацию, чтобы компилятор знал, что замыкание выполняется с другим делегатом, но я не могу найти соответствующую аннотацию для использования категории.

Will P's advice Я реализовал небольшой модуль расширения POC.

Сначала я смотрел на типы участвует

  • 1 имеет тип int
  • 1.minute имеет тип groovy.time.TimeDuration
  • 1.minute.from является анонимным классом типа groovy.time.BaseDuration.From
  • groovy.time.BaseDuration.From имеет now свойство (getNow способ)

Таким образом, я пришел с этим расширением

class PrecompiledExtension extends GroovyTypeCheckingExtensionSupport.TypeCheckingDSL { 
    @Override 
    Object run() { 
     unresolvedProperty { pexp -> 
      if ('minute' == pexp.propertyAsString && 
        getType(pexp.objectExpression) == classNodeFor(int)) { 
       storeType(pexp, classNodeFor(TimeDuration)) 
       handled = true 
      } 
      if ('from' == pexp.propertyAsString && 
        getType(pexp.objectExpression) == classNodeFor(TimeDuration)) { 
       storeType(pexp, classNodeFor(BaseDuration.From)) 
       handled = true 
      } 
     } 
    } 
} 

Он смотрит на только неразрешенных Properties.

  • Если имя свойства minute и тип выражения свойство считывается из является int, то результат будет иметь тип TimeDuration.
  • Если имя свойства равно from, а тип выражения, из которого считывается свойство, равен TimeDuration, результат будет иметь тип BaseDuration.From.

Обратите внимание, что это только ПОС. Не существует логической проверки того, что недостающие свойства находятся в замыкании, которое вызывается с использованием TimeCategory.

Чтобы компилятор использовал расширение, добавьте квалифицированное имя в TypeChecked Аннотация (type.PrecompiledExtension в примере ниже). Обратите внимание, что класс, аннотированный с помощью TypeChecked, не может вызвать GroovyUtil.use, поэтому я перевел вызов базовому классу.

class ExampleBase { 
    static def evaluateTime(@DelegatesTo(TimeCategory) Closure<Void> cl) { 
     GroovyUtil.use(TimeCategory, cl) 
    } 
} 

@TypeChecked(extensions = "type.PrecompiledExtension") 
class Example extends ExampleBase { 

    static time = evaluateTime { 
     TimeDuration minute = 1.minute 
     BaseDuration.From from = minute.from  

     println 1.minute.from.now 
    } 
} 

Обратите внимание, что type.PrecompiledExtension класс должен быть составлен до Example класса. Для POC я отключил TypeChecked для первого прохода компиляции, а затем снова включил его для второго прохода.

Это работает для компилятора, но IntelliJ не заберет это.

ответ

 Смежные вопросы

  • Нет связанных вопросов^_^