使使用过的类别为@TypeChecked 所知
Make used categories known to @TypeChecked
是否可以让编译器知道在 groovy 中执行闭包时使用的类别?
一个小例子:
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
注解让编译器知道闭包是用不同的委托执行的,但我找不到相应的使用类别的注解。
在之后我实现了一个小的POC扩展模块。
首先我查看了涉及的类型
1
的类型是 int
1.minute
是类型 groovy.time.TimeDuration
1.minute.from
是 groovy.time.BaseDuration.From
类型的匿名 class
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
}
}
}
}
它只查看未解析的属性。
- 如果 属性 名称是
minute
并且 属性 从中读取的表达式类型是 int
,结果将是类型 TimeDuration
.
- 如果 属性 名称是
from
并且 属性 从中读取的表达式类型是 TimeDuration
,结果将是类型 BaseDuration.From
.
请注意,这只是一个 POC。没有逻辑验证缺少的属性是否在使用 TimeCategory
.
调用的闭包中
要让编译器使用扩展名,请将限定名称添加到 TypeChecked
注释中(下例中的 type.PrecompiledExtension
)。请注意,用 TypeChecked
注释的 class 无法调用 GroovyUtil.use
,因此我将调用移到了基础 class.
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
class 必须在 Example
class 之前编译。对于 POC,我在第一次编译过程中禁用了 TypeChecked
,然后在第二次编译过程中再次启用它。
这适用于编译器,但 IntelliJ 不会选择它。
不,@TypeChecked
不支持类别。您可以使用 extension module or write your own type checked extensions
是否可以让编译器知道在 groovy 中执行闭包时使用的类别?
一个小例子:
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
注解让编译器知道闭包是用不同的委托执行的,但我找不到相应的使用类别的注解。
在
首先我查看了涉及的类型
1
的类型是int
1.minute
是类型groovy.time.TimeDuration
1.minute.from
是groovy.time.BaseDuration.From
类型的匿名 class
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
}
}
}
}
它只查看未解析的属性。
- 如果 属性 名称是
minute
并且 属性 从中读取的表达式类型是int
,结果将是类型TimeDuration
. - 如果 属性 名称是
from
并且 属性 从中读取的表达式类型是TimeDuration
,结果将是类型BaseDuration.From
.
请注意,这只是一个 POC。没有逻辑验证缺少的属性是否在使用 TimeCategory
.
要让编译器使用扩展名,请将限定名称添加到 TypeChecked
注释中(下例中的 type.PrecompiledExtension
)。请注意,用 TypeChecked
注释的 class 无法调用 GroovyUtil.use
,因此我将调用移到了基础 class.
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
class 必须在 Example
class 之前编译。对于 POC,我在第一次编译过程中禁用了 TypeChecked
,然后在第二次编译过程中再次启用它。
这适用于编译器,但 IntelliJ 不会选择它。
不,@TypeChecked
不支持类别。您可以使用 extension module or write your own type checked extensions