インサートコールアウトプロセッサ
7914 ワード
Javacコマンドの-processorパラメータでコンパイルを実行するには付属の注釈プロセッサが必要で、複数の注釈プロセッサがあればカンマで区切ります.
-XprintRoundsおよび-XprintProcessorInfoパラメータを使用して、注記プロセッサの動作の詳細を表示することもできます.
NameCheckProcessorの例では、JSR-269埋め込み注釈処理APIの一部の機能のみが実証されています.このAPIのセットに基づいてサポートされている項目には、Hibernateラベルの正確性を検証するためのHibernate Validator Annotation Processor(本質的にはNameCheckProcessorとはあまり差がありません)があり、フィールドにgetterメソッドとsetterメソッドを自動的に生成するProject Lombokがあります.(既存の要素に基づいて新しい構文ツリー要素を生成する)など、
コードは次のとおりです.
テストクラスを書きます.
次にコマンドラインに入ってみましょう
javac NameCheckProcessor.java
javac -processor NameCheckProcessor FT.java
FT.java:4:警告:名称:FTはアルパカ式命名法(Camel Case Name)に適合しなければならない
public class FT {
^
1つの警告
-XprintRoundsおよび-XprintProcessorInfoパラメータを使用して、注記プロセッサの動作の詳細を表示することもできます.
NameCheckProcessorの例では、JSR-269埋め込み注釈処理APIの一部の機能のみが実証されています.このAPIのセットに基づいてサポートされている項目には、Hibernateラベルの正確性を検証するためのHibernate Validator Annotation Processor(本質的にはNameCheckProcessorとはあまり差がありません)があり、フィールドにgetterメソッドとsetterメソッドを自動的に生成するProject Lombokがあります.(既存の要素に基づいて新しい構文ツリー要素を生成する)など、
コードは次のとおりです.
import java.util.EnumSet;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
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.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementScanner7;
import javax.tools.Diagnostic.Kind;
/**
* javac NameCheckProcessor.java
* javac -processor NameCheckProcessor FT.java
* @author kevin
*
*/
// * Annotations
@SupportedAnnotationTypes(value = "*")
@SupportedSourceVersion(value = SourceVersion.RELEASE_7)
public class NameCheckProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
this.nameCheck = new NameCheck(processingEnv);
}
private NameCheck nameCheck;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (!roundEnv.processingOver()) {
for (Element element : roundEnv.getRootElements()) {
nameCheck.check(element);
}
}
return false;
}
/**
* , Warning
*
* @author kevin
*
*/
public static class NameCheck {
Messager messager = null;
public NameCheckScanner nameCheckScanner;
private NameCheck(ProcessingEnvironment processingEnv) {
messager = processingEnv.getMessager();
nameCheckScanner = new NameCheckScanner(processingEnv);
}
/**
* Java , 《Java ( 3 )》6.8 ,Java :
* <ul>
* <li> : , 。
* <li> : , 。
* <li> :
* <ul>
* <li> , : , 。
* <li> :
* </ul>
* </ul>
*
* @param element
*/
public void check(Element element) {
nameCheckScanner.scan(element);
}
/**
* , 1.6 ElementScanner6<br>
* Visitor
*
* @author kevin
*
*/
public static class NameCheckScanner extends ElementScanner7<Void, Void> {
Messager messager = null;
public NameCheckScanner(ProcessingEnvironment processingEnv) {
this.messager = processingEnv.getMessager();
}
/**
* Java
*/
@Override
public Void visitType(TypeElement e, Void p) {
scan(e.getTypeParameters(), p);
checkCamelCase(e, true);
super.visitType(e, p);
return null;
}
/**
* Element , ,
*
* @param e
* @param b
*/
private void checkCamelCase(Element e, boolean initialCaps) {
String name = e.getSimpleName().toString();
boolean previousUpper = false;
boolean conventional = true;
int firstCodePoint = name.codePointAt(0);
if (Character.isUpperCase(firstCodePoint)) {
previousUpper = true;
if (!initialCaps) {
messager.printMessage(Kind.WARNING, " :" + name + " ", e);
return;
}
} else if (Character.isLowerCase(firstCodePoint)) {
if (initialCaps) {
messager.printMessage(Kind.WARNING, " :" + name + " ", e);
return;
}
} else {
conventional = false;
}
if (conventional) {
int cp = firstCodePoint;
for (int i = Character.charCount(cp); i < name.length(); i += Character.charCount(cp)) {
cp = name.codePointAt(i);
if (Character.isUpperCase(cp)) {
if (previousUpper) {
conventional = false;
break;
}
previousUpper = true;
} else {
previousUpper = false;
}
}
}
if (!conventional) {
messager.printMessage(Kind.WARNING, " :" + name + " (Camel Case Names)", e);
}
}
/**
*
*/
@Override
public Void visitExecutable(ExecutableElement e, Void p) {
if (e.getKind() == ElementKind.METHOD) {
Name name = e.getSimpleName();
if (name.contentEquals(e.getEnclosingElement().getSimpleName())) {
messager.printMessage(Kind.WARNING, " :" + name + " , ", e);
checkCamelCase(e, false);
}
}
super.visitExecutable(e, p);
return null;
}
/**
*
*/
@Override
public Void visitVariable(VariableElement e, Void p) {
/* Variable , , */
if (e.getKind() == ElementKind.ENUM_CONSTANT || e.getConstantValue() != null || heuristicallyConstant(e)) {
checkAllCaps(e);
} else {
checkCamelCase(e, false);
}
super.visitVariable(e, p);
return null;
}
/**
* , ,
*
* @param e
*/
private void checkAllCaps(VariableElement e) {
String name = e.getSimpleName().toString();
boolean conventional = true;
int firstCodePoint = name.codePointAt(0);
if (!Character.isUpperCase(firstCodePoint)) {
conventional = false;
} else {
boolean previousUnderscore = false;
int cp = firstCodePoint;
for (int i = Character.charCount(cp); i < name.length(); i += Character.charCount(cp)) {
cp = name.codePointAt(i);
if (cp == (int) '_') {
if (previousUnderscore) {
conventional = false;
break;
}
previousUnderscore = true;
} else {
previousUnderscore = false;
if (!Character.isUpperCase(cp) && !Character.isDigit(cp)) {
conventional = false;
break;
}
}
}
}
if (!conventional) {
messager.printMessage(Kind.WARNING, " :" + name + " " + " , ", e);
}
}
/**
*
*
* @param e
* @return
*/
private boolean heuristicallyConstant(VariableElement e) {
if (e.getEnclosingElement().getKind() == ElementKind.INTERFACE) {
return true;
} else if (e.getKind() == ElementKind.FIELD && e.getModifiers().containsAll(EnumSet.of(javax.lang.model.element.Modifier.FINAL, javax.lang.model.element.Modifier.STATIC, javax.lang.model.element.Modifier.PUBLIC))) {
return true;
}
return false;
}
}
}
}
テストクラスを書きます.
import java.util.ArrayList;
import java.util.List;
public class FT {
public static class A_B_C {
}
public static String ab_sd="";
public static int method(List<Integer> list) {
System.out.println("method(List<Integer>list)");
return 1;
}
public static void main(String[] args) {
method(new ArrayList<Integer>());
Long aLong = 2l;
Integer aInteger = 1;
Integer bInteger = 1;
System.out.println(aLong.equals(aInteger + bInteger));
System.out.println(aInteger.equals(1L));
System.out.println("true");
}
}
次にコマンドラインに入ってみましょう
javac NameCheckProcessor.java
javac -processor NameCheckProcessor FT.java
FT.java:4:警告:名称:FTはアルパカ式命名法(Camel Case Name)に適合しなければならない
public class FT {
^
1つの警告