假设我定义了一个名为的自定义注释@Unsafe.
我想提供一个注释处理器,它将检测对注释方法的引用@Unsafe并打印警告.
例如,鉴于此代码......
public class Foo {
@Unsafe
public void doSomething() { ... }
}
public class Bar {
public static void main(String[] args) {
new Foo().doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
...我希望编译器打印如下:
WARN > Bar.java, line 3 : Call to Unsafe API - Foo.doSomething()
Run Code Online (Sandbox Code Playgroud)
它在精神上非常相似@Deprecated,但我的注释是在传达不同的东西,所以我不能@Deprecated直接使用.有没有办法用注释处理器实现这一目标?注释处理器API似乎更关注应用注释的实体(Foo.java在我的示例中),而不是引用注释成员的实体.
此问题提供了一种使用ASM作为单独构建步骤实现它的技术.但我想知道我是否可以通过javac和注释处理以更自然的方式做到这一点?
我试图用JSR 269格式编写一个注释处理器,它使用javac的Compiler Tree API来做一些源代码分析.我对成员选择表达式感兴趣,例如方法调用.
我可以很容易地获得所选方法(或字段等)的名称.但我想知道该成员的选择类型,我似乎无法找到一种直接的方法来做到这一点.Trees.getTypeMirror返回null我尝试调用的所有内容(而Javadoc没有提示).
我想我可以详尽地分析每一种表达对成员的左侧选择,并通过回归分析确定的静态类型的表达式:NewClassTree,TypeCastTree,MethodInvocationTree,ArrayAccessTree,和其他许多人.但这似乎是很容易出错的工作,显然javac已经知道表达式的静态类型,因为它需要这些信息用于许多目的.但是如何访问此类型信息?
到目前为止我所拥有的:
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.util.TreePath;
import com.sun.source.util.TreePathScanner;
import com.sun.source.util.Trees;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class PublicProcessor extends AbstractProcessor {
public @Override boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element e : roundEnv.getRootElements()) {
final Trees trees = Trees.instance(processingEnv);
final TreePath root = trees.getPath(e);
new …Run Code Online (Sandbox Code Playgroud) 对于 Java7 和 Java8,如果调用了某些方法,我想生成警告。如果用户编译时存在特定的 jar,则将打印警告。
我编写了一个注释处理器并捕获了visitMethodInvocation()。现在,我想提取将调用的类和方法名称。
有可能这样做吗?或者如何解决这个问题?