提取中文
本工具应用 org.eclipse.jdt.core 将 java 代码转换成 AST
-
将 java 代码转换成 AST 树
def parser = new Parser() CompilationUnit result = parser.ast(content) Document document = new Document(src.text) def ast = result.getAST()
-
应用 Vistior 模式遍历所有字符串
List<StringLiteral> visitChineseText(CompilationUnit result){var translateList = [] result.accept(new ASTVisitor(){ @Override 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>
接口,用来判断中文是否过滤
罕用的过滤器有:
- 注解过滤器
boolean isInAnnotation(StringLiteral stringLiteral){
def parent = stringLiteral.parent
// 以 StringLiteral 节点向上查找,如果找到了注解,则返回 true
while (parent != null && !(parent instanceof TypeDeclaration)) {if(parent instanceof Annotation){def memberValuePair = AstUtils.lookupUntilASTNode(stringLiteral, MemberValuePair.class)
if(memberValuePair.isPresent()){return !shouldExclude(memberValuePair.get(), parent)
}
return true
}
parent = parent.parent
}
return false
}
- 常量过滤器
- 枚举过滤器
通常 Enum 里的中文无需翻译,也无奈替换,因为不能在初始化的时候调用办法
public enum RpFlagEnum {
/**
* 应酬
*/
P("P","应酬"),
/**
* 应收
*/
R("R","应收");
}
def optMethod = AstUtils.lookupUntilASTNode(stringLiteral, EnumConstantDeclaration.class)
if (optMethod.isPresent()) {return true}
return false
- 日志过滤
过滤 log.info(“ 中文 ”)
def optMethod = AstUtils.lookupUntilASTNode(stringLiteral, MethodInvocation.class)
if(optMethod.isPresent()){def methodName = optMethod.get().getExpression()
// log.info(xxx)
if(methodName instanceof SimpleName){def simpleName = (SimpleName)methodName
if(isLogInfo(simpleName.getIdentifier())){return true}
// this.log.info(xxx)
} else if(methodName instanceof FieldAccess){def fieldAccess = (FieldAccess)methodName
def fieldName = fieldAccess.getName()
if(isLogInfo(fieldName.getIdentifier())){return true}
}
}
return false
- Main 办法过滤
- I18n 办法过滤
- 正文中增加了 kiwi-disable-method
某些状况下咱们须要过滤的中文属于业务逻辑,然而代码无奈判断,须要增加正文跳过
/**
*
* kiwi-disable-method
*/
pubic String abc(){return "中文";}
boolean hasMethodComment(StringLiteral stringLiteral) {
def parent = stringLiteral.parent
while (parent != null && !(parent instanceof TypeDeclaration)) {if(parent instanceof MethodDeclaration){def doc = parent.getJavadoc()
return doc.toString().contains(methodComment)
}
parent = parent.parent
}
return false
}
- 正则过滤器(正则匹配的中文字符(只蕴含标点))
- 参加业务逻辑的中文比方 “ 中文 ”.equsals(“ 中文 ”)
boolean hasStringEquals(StringLiteral stringLiteral){def optMethod = AstUtils.lookupUntilASTNode(stringLiteral, MethodInvocation.class)
if(optMethod.isPresent()){def method = optMethod.get()
if(method.name.identifier == "equals"){return true}
}
return false
}