Java 注解处理器简单地实现,看看是什么效果

140 篇文章 0 订阅
94 篇文章 0 订阅
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
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;
import java.util.Set;


import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;

import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementScanner9;//10 is not ok
import javax.tools.Diagnostic.Kind;
import javax.annotation.processing.Messager;

@SupportedAnnotationTypes("*")//all annotations
@SupportedSourceVersion(SourceVersion.RELEASE_10)
public class NameCheckProcessor extends AbstractProcessor {

	private NameChecker nameChecker;

	@Override
	public synchronized void init(ProcessingEnvironment processingEnv) {
		super.init(processingEnv);
		this.nameChecker = new NameChecker(processingEnv);
	}

	//对语法树 每个节点进行检查
	@Override
	public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

		if(!roundEnv.processingOver()){
			for(Element e : roundEnv.getRootElements()){
				this.nameChecker.checkNames(e);
				log(e);//输出是类名
			}
		}

		return false;
	}

	public static<T> void log(T t){
		System.out.println(t);
	}
}





class NameChecker{

	
	private final Messager message;

	NameCheckScanner nameCheckScanner = new NameCheckScanner();

	public NameChecker(ProcessingEnvironment processingEnv) {
		this.message = processingEnv.getMessager();
	}

	/**
	 * class interface name : camel,first upper method : camel,first upper field
	 * variable :camel ,first lower const : all upper
	 *
	 * @param e
	 */
	public void checkNames(Element e) {
		this.nameCheckScanner.scan(e);
	}

	private class NameCheckScanner extends ElementScanner9<Void, Void> {

		@Override
		public Void scan(Element e, Void p) {
			return super.scan(e, p);
		}

		@Override
		public Void visitType(TypeElement e, Void p) {
			scan(e.getTypeParameters(), p);
			log("TypeElement: " + e.getSimpleName(), e);
			return super.visitType(e, p);
		}

		@Override
		public Void visitExecutable(ExecutableElement e, Void p) {

			if (e.getKind() == ElementKind.METHOD) {
				log("ExecutableElement: ", e);
				log("ElementKind: " + e.getKind(), e);
				log("SimpleName: " + e.getSimpleName(), e);
				log("EnclosingElement SimpleName: " + e.getEnclosingElement().getSimpleName(), e);

			}

			return super.visitExecutable(e, p);
		}

		@Override
		public Void visitVariable(VariableElement e, Void p) {

			if (e.getKind() == ElementKind.ENUM_CONSTANT || e.getConstantValue() != null
					|| e.getEnclosingElement().getKind() == ElementKind.INTERFACE || e.getKind() == ElementKind.FIELD) {
				log("VariableElement:",e);
				log("SimpleName: "+e.getSimpleName(),e);
				log("kind: "+ e.getKind(),e);
				log("EnclosingElement SimpleName: "+ e.getEnclosingElement().getSimpleName(),e);
				log("EnclosingElement kind: "+ e.getEnclosingElement().getKind(),e);
				log("Modifiers: "+e.getModifiers(),e);
			}

			return super.visitVariable(e, p);
		}

		private <T extends CharSequence> void log(T t, Element e) {
			message.printMessage(Kind.WARNING, t, e);
		}

	}

}

public class Badly_Named_Code{
	enum A{
		red,blue,green;
	}
	static final int _FORTy_TWO = 42;
	public static int NOT_A_CONSTANT = _FORTy_TWO;
	protected void Badly_Named_Code(){
		return ;
	}
	public void NOTcameCASEmethodNAME(){
		return;
	}
}

>javac -processor NameCheckProcessor Badly_Named_Code.java

Badly_Named_Code
Badly_Named_Code.java:1: 警告: TypeElement: Badly_Named_Code
public class Badly_Named_Code{
       ^
Badly_Named_Code.java:2: 警告: TypeElement: A
        enum A{
        ^
警告: ExecutableElement:
警告: ElementKind: METHOD
警告: SimpleName: values
警告: EnclosingElement SimpleName: A
警告: ExecutableElement:
警告: ElementKind: METHOD
警告: SimpleName: valueOf
警告: EnclosingElement SimpleName: A
Badly_Named_Code.java:3: 警告: VariableElement:
                red,blue,green;
                ^
Badly_Named_Code.java:3: 警告: SimpleName: red
                red,blue,green;
                ^
Badly_Named_Code.java:3: 警告: kind: ENUM_CONSTANT
                red,blue,green;
                ^
Badly_Named_Code.java:3: 警告: EnclosingElement SimpleName: A
                red,blue,green;
                ^
Badly_Named_Code.java:3: 警告: EnclosingElement kind: ENUM
                red,blue,green;
                ^
Badly_Named_Code.java:3: 警告: Modifiers: [public, static, final]
                red,blue,green;
                ^
Badly_Named_Code.java:3: 警告: VariableElement:
                red,blue,green;
                    ^
Badly_Named_Code.java:3: 警告: SimpleName: blue
                red,blue,green;
                    ^
Badly_Named_Code.java:3: 警告: kind: ENUM_CONSTANT
                red,blue,green;
                    ^
Badly_Named_Code.java:3: 警告: EnclosingElement SimpleName: A
                red,blue,green;
                    ^
Badly_Named_Code.java:3: 警告: EnclosingElement kind: ENUM
                red,blue,green;
                    ^
Badly_Named_Code.java:3: 警告: Modifiers: [public, static, final]
                red,blue,green;
                    ^
Badly_Named_Code.java:3: 警告: VariableElement:
                red,blue,green;
                         ^
Badly_Named_Code.java:3: 警告: SimpleName: green
                red,blue,green;
                         ^
Badly_Named_Code.java:3: 警告: kind: ENUM_CONSTANT
                red,blue,green;
                         ^
Badly_Named_Code.java:3: 警告: EnclosingElement SimpleName: A
                red,blue,green;
                         ^
Badly_Named_Code.java:3: 警告: EnclosingElement kind: ENUM
                red,blue,green;
                         ^
Badly_Named_Code.java:3: 警告: Modifiers: [public, static, final]
                red,blue,green;
                         ^
Badly_Named_Code.java:5: 警告: VariableElement:
        static final int _FORTy_TWO = 42;
                         ^
Badly_Named_Code.java:5: 警告: SimpleName: _FORTy_TWO
        static final int _FORTy_TWO = 42;
                         ^
Badly_Named_Code.java:5: 警告: kind: FIELD
        static final int _FORTy_TWO = 42;
                         ^
Badly_Named_Code.java:5: 警告: EnclosingElement SimpleName: Badly_Named_Code
        static final int _FORTy_TWO = 42;
                         ^
Badly_Named_Code.java:5: 警告: EnclosingElement kind: CLASS
        static final int _FORTy_TWO = 42;
                         ^
Badly_Named_Code.java:5: 警告: Modifiers: [static, final]
        static final int _FORTy_TWO = 42;
                         ^
Badly_Named_Code.java:6: 警告: VariableElement:
        public static int NOT_A_CONSTANT = _FORTy_TWO;
                          ^
Badly_Named_Code.java:6: 警告: SimpleName: NOT_A_CONSTANT
        public static int NOT_A_CONSTANT = _FORTy_TWO;
                          ^
Badly_Named_Code.java:6: 警告: kind: FIELD
        public static int NOT_A_CONSTANT = _FORTy_TWO;
                          ^
Badly_Named_Code.java:6: 警告: EnclosingElement SimpleName: Badly_Named_Code
        public static int NOT_A_CONSTANT = _FORTy_TWO;
                          ^
Badly_Named_Code.java:6: 警告: EnclosingElement kind: CLASS
        public static int NOT_A_CONSTANT = _FORTy_TWO;
                          ^
Badly_Named_Code.java:6: 警告: Modifiers: [public, static]
        public static int NOT_A_CONSTANT = _FORTy_TWO;
                          ^
Badly_Named_Code.java:7: 警告: ExecutableElement:
        protected void Badly_Named_Code(){
                       ^
Badly_Named_Code.java:7: 警告: ElementKind: METHOD
        protected void Badly_Named_Code(){
                       ^
Badly_Named_Code.java:7: 警告: SimpleName: Badly_Named_Code
        protected void Badly_Named_Code(){
                       ^
Badly_Named_Code.java:7: 警告: EnclosingElement SimpleName: Badly_Named_Code
        protected void Badly_Named_Code(){
                       ^
Badly_Named_Code.java:10: 警告: ExecutableElement:
        public void NOTcameCASEmethodNAME(){
                    ^
Badly_Named_Code.java:10: 警告: ElementKind: METHOD
        public void NOTcameCASEmethodNAME(){
                    ^
Badly_Named_Code.java:10: 警告: SimpleName: NOTcameCASEmethodNAME
        public void NOTcameCASEmethodNAME(){
                    ^
Badly_Named_Code.java:10: 警告: EnclosingElement SimpleName: Badly_Named_Code
        public void NOTcameCASEmethodNAME(){
                    ^
48 个警告


涉及的类(不含包名) : 

SupportedAnnotationTypes  * 支持所有 Annotations

SupportedSourceVersion 支持版本 (唯一,与javac 版本一致,理解的)

AbstractProcessor  继承 (javac -processor 子类)

RoundEnvironment 可以查询有关注释处理的 round 的信息

Element及其子类,TypeElement,VariableElement,ExecutableElement  

ElementKind,Kind 

Messager 编译的时候可以输出

ElementScanner9 继承 实现一些操作









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值