提取中文
本工具使用org.eclipse.jdt.core将java代码转换成AST
将java代码转换成AST树
1
2
3
4def parser = new Parser()
CompilationUnit result = parser.ast(content)
Document document = new Document(src.text)
def ast = result.getAST()使用Vistior模式遍历所有字符串
1
2
3
4
5
6
7
8
9
10
11
12
13List<StringLiteral> visitChineseText(CompilationUnit result){
var translateList = []
result.accept(new ASTVisitor(){
boolean visit(StringLiteral node) {
if(node.toString() =~ Config.DOUBLE_BYTE_REGEX){
translateList.add(node)
}
return super.visit(node)
}
})
return translateList
}
过滤
原理:熟悉AST
以下是
logger.info("异常信息"+e)
的AST
如果我们需要过滤logger.info("异常信息"+e)
,我们需要lookup到MethodInvocation节点,然后查看MethodInvocation的expression是否为SimpleName类型,且getIdentifier() == “logger”
需要过滤的中文
kiwi中实现的过滤器支持过滤以下中文:
- 去除注释
- 过滤log中的中文
- 系统配置的中文
- 参与业务逻辑的中文比如 “中文”.equsals(“中文”)
- 正则匹配的中文字符(只包含标点)
- 存在于注解中的中文
- 存在于枚举的中文
- 注释中添加了kiwi-disable-method
过滤器实现
所有的过滤器实现了
Predicate<StringLiteral>
接口,用来判断中文是否过滤
常用的过滤器有:
- 注解过滤器
1 | boolean isInAnnotation(StringLiteral stringLiteral){ |
- 常量过滤器
- 枚举过滤器
通常Enum里的中文无需翻译,也无法替换,因为不能在初始化的时候调用方法
1 | public enum RpFlagEnum { |
1 | def optMethod = AstUtils.lookupUntilASTNode(stringLiteral, EnumConstantDeclaration.class) |
- 日志过滤
过滤 log.info(“中文”)
1 | def optMethod = AstUtils.lookupUntilASTNode(stringLiteral, MethodInvocation.class) |
- Main方法过滤
- I18n方法过滤
- 注释中添加了kiwi-disable-method
某些情况下我们需要过滤的中文属于业务逻辑,但是代码无法判断,需要添加注释跳过
1 | /** |
1 | boolean hasMethodComment(StringLiteral stringLiteral) { |
- 正则过滤器(正则匹配的中文字符(只包含标点))
- 参与业务逻辑的中文比如 “中文”.equsals(“中文”)
1 | boolean hasStringEquals(StringLiteral stringLiteral){ |