Auto Service 可以帮我们注册 Annotation processor 到 java 的 service loader 里面,我们的 processor 就可以在 build 的时候被呼叫。首先要在 processor module 里面 (processor/src/main/resources/META-INF/services/
) 加入一个名为 javax.annotation.processing.Processor
的 configuration 档案。这个档案要写你的 processor 的完整路径,包含 package name ,完整档案可以参考这边。
tw.ktrssreader.processor.RssAnnotationProcessor
设定好 auto service 之後,我们就可以来撰写 processor 了!我们只要透过 @AutoService
来标注我们的 processor ,在 compile 的时候就会呼叫内部的 process
方法。除了要覆写 process
方法外,我们还要覆写 getSupportedAnnotationTypes
来指定要处理哪些 annotation ,在这边我们要指定之前订好的四个 annotation : RssTag
、 RssRawData
、 RssAttribute
和 RssValue
。
@AutoService(Processor::class)
class RssAnnotationProcessor : AbstractProcessor() {
override fun getSupportedAnnotationTypes(): MutableSet<String> {
return mutableSetOf(
RssTag::class.java.canonicalName,
RssRawData::class.java.canonicalName,
RssAttribute::class.java.canonicalName,
RssValue::class.java.canonicalName
)
}
override fun process(typeElementSet: MutableSet<out TypeElement>?, roundEnvironment: RoundEnvironment?): Boolean {
...
}
}
接下来我们来看 process 方法里的 RoundEnvironment
,他指的是被 annotation 标注的程序码资讯。我们可以从中获得被标注的元素。在产生程序码之前,我们需要做的就是先获得标注的结构和资讯,所以我们可以先实作一个方法来拿到标注有 @RssTag
且它的名称是 channel
的类别,先判别第一层结构。
private inline fun generateParsers(roundEnv: RoundEnvironment?, crossinline action: (Boolean, Element) -> Unit) {
roundEnv?.getElementsAnnotatedWith(RssTag::class.java)?.forEach{
if (it?.kind == ElementKind.CLASS) {
val rssTag = it.getAnnotation(RssTag::class.java)
val isRoot = rssTag?.name == CHANNEL
action(isRoot,it)
}
}
}
可以用 getElementsAnnotatedWith
拿到有 @RssTag
的元素,然後判断它是不是 class 层级和它的 tag 名称,接着就可以执行 action ,这边把 action 定义成一个 lambda ,让使用这个 function 的人可以自己决定要做什麽动作。
ES6 新增了更接近传统语言写法的 Class 这个概念,基本上可以当作是一个语法糖,绝大部分的功...
本日小作品: https://codepen.io/linchinhsuan/pen/OJXVgdo...
Collection 攻击者会为了取得 ICS 环境中感兴趣的资料,进而使用许多技巧,透过监控的方式...
今天来介绍 JavaScript 的模组 esm 系统及 commonjs 系统。 什麽是模组 当我...
先来看一下题目 Given an array of positive integers (repre...