All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.wicp.tams.common.annotation.complier.NameChecker Maven / Gradle / Ivy
package net.wicp.tams.common.annotation.complier;
import java.util.EnumSet;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
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;
public class NameChecker {
private final Messager messager;
NameCheckScanner nameCheckScanner = new NameCheckScanner();
NameChecker(ProcessingEnvironment processsingEnv) {
this.messager = processsingEnv.getMessager();
}
/**
* 对Java程序命名进行检查,根据《Java语言规范(第3版)》第6.8节的要求,Java程序命名应当符合下列格式:
*
* 类或接口:符合驼式命名法,首字母大写。
* 方法:符合驼式命名法,首字母小写。
* 字段:
*
* 类、实例变量:符合驼式命名法,首字母小写。
* 常量:要求全部大写。
*
*
*/
public void checkNames(Element element) {
nameCheckScanner.scan(element);
}
/**
* 名称检查器实现类,继承了JDK 1.7中新提供的ElementScanner7
* 将会以Visitor模式访问抽象语法树中的元素
*/
private class NameCheckScanner extends ElementScanner7 {
/**
* 此方法用于检查Java类
*/
@Override
public Void visitType(TypeElement e, Void p) {
scan(e.getTypeParameters(), p);
checkCamelCase(e, true);
super.visitType(e, p);
return null;
}
/**
* 检查方法命名是否合法
*/
@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(Diagnostic.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);
return null;
}
/**
* 判断一个变量是否是常量
*/
private boolean heuristicallyConstant(VariableElement e) {
if (e.getEnclosingElement().getKind() == ElementKind.INTERFACE)
return true;
else if (e.getKind() == ElementKind.FIELD
&& e.getModifiers().containsAll(EnumSet.of(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)))
return true;
else {
return false;
}
}
/**
* 检查传入的Element是否符合驼式命名法,如果不符合,则输出警告信息
*/
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(Diagnostic.Kind.WARNING, "名称'" + name + "'应当以小写字母开头", e);
return;
}
} else if (Character.isLowerCase(firstCodePoint)) {
if (initialCaps) {
messager.printMessage(Diagnostic.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(Diagnostic.Kind.WARNING, "名称'" + name + "'应当符合驼式命名法(Camel Case Names)", e);
}
/**
* 大写命名检查,要求第一个字母必须是大写的英文字母,其余部分可以是下划线或大写字母
*/
private void checkAllCaps(Element 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(Diagnostic.Kind.WARNING, "常量'" + name + "'应当全部以大写字母或下划线命名,并且以字母开头", e);
}
}
}