Erzyb

怕什么真理无穷,进一步有进一步的欢喜


  • 首页

  • 归档

插入式直接处理器

发表于 2018-07-31

插入式注解处理器

Sub:CheckStyle,FindBugs,Klocwork实现原理

一.API基础知识

AbstractProcessor

ElementKind

ProcessingEnvironment

SupportedAnnotationTypes

SupportedSourceVersion

二.eg代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.util.Set;

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;

//可以用"*"标识支持所有Annotations
@SupportedAnnotationTypes("*")
//只支持JDK1.6的java代码
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class NameCheckProcessor extends AbstractProcessor {

private NameChecker mNameChecker;

/**
* 初始换名称检查插件
* @param processingEnvironment
*/
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
mNameChecker = new NameChecker(processingEnvironment);
}

/**
* 对输入的语法树的各个节点进行名称检查
* @param set
* @param roundEnvironment
* @return
*/
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
if (!roundEnvironment.processingOver()) {
for (Element element : roundEnvironment.getRootElements()) {
mNameChecker.checkNames(element);
}
}
return false;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
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.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementScanner6;
import javax.tools.Diagnostic;

import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;

/**
* 程序名称规范的编译器插件
* 如果名称不符合规范,将会报出一个编译器的警告信息
* Created by zhouyibo on 2018/7/30.
*/

public class NameChecker {
private final Messager mMessager;
private NameCheckScanner mNameCheckScanner = new NameCheckScanner();

public NameChecker(ProcessingEnvironment processingEnvironment) {
mMessager = processingEnvironment.getMessager();
}

/**
* 对Java程序命名进行检查
* @param element
*/
public void checkNames(Element element) {
mNameCheckScanner.scan(element);
}

/**
* 名称检查实现类 继承ElementScanner6
* 将会以Visitor模式访问抽象语法树中的元素
*/
private class NameCheckScanner extends ElementScanner6<Void, Void> {
/**
* 检查Java类
* @param typeElement
* @param aVoid
* @return
*/
@Override
public Void visitType(TypeElement typeElement, Void aVoid) {
scan(typeElement.getTypeParameters(), aVoid);
checkCamelCase(typeElement, true);
super.visitType(typeElement, aVoid);
return null;
}

/**
* 检查方法名
* @param executableElement
* @param aVoid
* @return
*/
@Override
public Void visitExecutable(ExecutableElement executableElement, Void aVoid) {
if (executableElement.getKind() == ElementKind.METHOD) {
Name name = executableElement.getSimpleName();
if (name.contentEquals(executableElement.getEnclosingElement().getSimpleName())) {
mMessager.printMessage(Diagnostic.Kind.WARNING, "一个普通方法" + name + "不应当与类名重复,避免与构造函数产生混淆", executableElement);
checkCamelCase(executableElement, false);
}
}
super.visitExecutable(executableElement, aVoid);
return null;
}

/**
* 检查变量命名
* @param variableElement
* @param aVoid
* @return
*/
@Override
public Void visitVariable(VariableElement variableElement, Void aVoid) {
if (variableElement.getKind() == ElementKind.ENUM_CONSTANT || variableElement.getConstantValue() != null || heuristicallyConstant(variableElement)) {
checkAllCaps(variableElement);
} else {
checkCamelCase(variableElement, false);
}
return null;
}

/**
* 大写命名检查
* @param e
*/
private void checkAllCaps(Element e) {
String name = e.getSimpleName().toString();
boolean convertional = true;
int firstCodePoint = name.codePointAt(0);
if (!Character.isUpperCase(firstCodePoint)) {
convertional = 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) {
convertional = false;
break;
}
previousUnderscore = true;
} else {
previousUnderscore = false;
if (!Character.isUpperCase(cp) && !Character.isDigit(cp)) {
convertional = false;
break;
}
}
}
}
if (!convertional) {
mMessager.printMessage(Diagnostic.Kind.WARNING, "常量" + name + "应当全部以大写字母或者下划线命名,并且以字母开头", e);
}
}

/**
* 检查是都是常量
* @param variableElement
* @return
*/
private boolean heuristicallyConstant(VariableElement variableElement) {
if (variableElement.getEnclosingElement().getKind() == ElementKind.INTERFACE) {
return true;
} else if (variableElement.getKind() == ElementKind.FIELD && variableElement.getModifiers().containsAll(EnumSet.of(PUBLIC, STATIC, FINAL))) {
return true;
} else {
return false;
}
}

/**
* 检查是否符合驼式命名
* @param e
* @param b
*/
private void checkCamelCase(Element e, boolean b) {
String name = e.getSimpleName().toString();
boolean previousUpper = false;
boolean conventional = true;
int firstCodePoint = name.codePointAt(0);
if (Character.isUpperCase(firstCodePoint)) {
previousUpper = true;
if (!b) {
mMessager.printMessage(Diagnostic.Kind.WARNING, "名称" + name + "应当以小写字母开头", e);
return;
}
} else if (Character.isLowerCase(firstCodePoint)) {
if (b) {
mMessager.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) {
mMessager.printMessage(Diagnostic.Kind.WARNING, "名称" + name + "应当符合驼式命名法", e);
}
}
}
}

webview缓存

发表于 2018-06-20

webview漏洞

发表于 2018-06-19
  1. 任意代码执行漏洞
  2. 密码明文存储漏洞
  3. 域控制不严格漏洞

阅读全文 »

夜间模式实现整理

发表于 2018-03-22

产品:我们要加一个夜间模式。

:我们不是有夜间模式?

产品:我们的在阅读器里,我们再外边也要加。

:换肤?

产品:不换肤,跟竞品学。你看看他们怎么做的。

(mmp):好的,我看看。

:看完了,貌似就是改变了亮度,不难。

产品:嗯,做去吧。

阅读全文 »

正则表达式学习

发表于 2018-03-06

来源:http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html

元字符

代码 说明
. 匹配除换行符以外的所有字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
\$ 匹配字符串的结束
阅读全文 »

java 位操作

发表于 2018-02-28

LeetCode 371.两整数之和

不使用运算符 + 和-,计算两整数a 、b之和。

阅读全文 »

Resource Drawable 详解

发表于 2018-02-23

位图

编译的资源数据类型:BitmapDrawable

位图文件

Android支持以下三种格式的位图文件:.png .jpg .gif(不建议)

在构建过程中可以通过appt工具自动优化位图文件,对图像进行无损压缩。如果计划将图像解读为比特流以转化为位图,可以放在res/raw/文件夹中,在那里不会优化

阅读全文 »

2018目标

发表于 2018-02-22

阅读全文 »

checkstyle

发表于 2018-02-09

CheckStyle配置

Checkstyle使用

Checkstyle是检查java程序代码样式的工具。ide中可以通过checkstyle插件检查代码。

Checkstyle配置是通过指定modules来应用到java文件的。modules是树状结构,以一个名为Checker的module作为root节点,一般的checker都会包括TreeWalker子module。

阅读全文 »

git版本控制总结

发表于 2018-02-07

关于git

关于版本控制

  版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。版本控制分为集中式和分布式两种。

  1. 集中式版本控制

    在一个集中管理的服务器中保存所有文件的修改版本,而协同工作的人都通过客户端连接到这台服务器,取出最新的文件或提交修改。中央库保证版本的唯一性。集中式版本控制存在的问题是,在使用过程中需要不断和服务器进行通信,一旦网络出现故障,就很难继续工作,并且对中央服务器依赖大。

  2. 分布式版本控制

    客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份。

    git属于分布式版本控制,核心主要在于以下几个方面:分布式、快照、状态区、分支。

阅读全文 »
12
Erzyb

Erzyb

怕什么真理无穷,进一步有进一步的欢喜

13 日志
7 标签
GitHub E-Mail
© 2018 Erzyb
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.4