问题描述
使用ASTParser 解析含有emum 枚举方法的类文件时,解析的结果时错误的。比如下面的文件解析后method 数据含有以下四个,其中FULL_AMOUNT不是一个method,对应的行范围也是不准的,结果导致我们在影响面评估中,评估该方法有变动但却找不到的问题,使得调用链路分析评估不准确。
STATUS
FULL_AMOUNT
TYPE
getNameByCode
被解析java代码
import lombok.Getter;
@Getter
public class DicTaskEnum {
/**
* 状态
*/
@Getter
public enum STATUS {
/**
* 未执行
*/
NO_EXECUTION(1, "未执行"),
/**
* 执行中
*/
EXECUTING(0, "执行中"),
;
private final Integer code;
private final String name;
STATUS(Integer code, String name) {
this.code = code;
this.name = name;
}
public static String getNameByCode(Integer code) {
for (STATUS typeEnum : STATUS.values()) {
if (typeEnum.getCode().equals(code)) {
return typeEnum.getName();
}
}
return null;
}
}
/**
* 状态
*/
@Getter
public enum TYPE {
/**
* 全量
*/
FULL_AMOUNT("全量"),
/**
* 增量
*/
INCREMENTAL("增量"),
/**
* 指定范围
*/
SPECIFIED_RANGE("指定范围"),
;
private final String name;
TYPE(String name) {
this.name = name;
}
}
}
AST解析代码(未改进)
ASTParser parser = ASTParser.newParser(AST.JLS8);
Map<String, String> options = JavaCore.getOptions(); // 加上options 可以解决enum等生成树解析出错的问题
parser.setSource(javaSource.toCharArray());
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
解析后的错误cu数据,可以看到FULL_AMOUNT变成一个void方法
import lombok.Getter;
@Getter public class DicTaskEnum {
/**
* 状态
*/
@Getter public enum STATUS;
{
}
private final Integer code;
private final String name;
void STATUS( Integer code, String name){
this.code=code;
this.name=name;
}
public static String getNameByCode( Integer code){
for ( STATUS typeEnum : STATUS.values()) {
if (typeEnum.getCode().equals(code)) {
return typeEnum.getName();
}
}
return null;
}
/**
* 状态
*/
@Getter public enum TYPE;
/**
* 全量
*/
void FULL_AMOUNT(){
}
private final String name;
void TYPE( String name){
this.name=name;
}
}
AST解析代码(改进后,多了options)
ASTParser parser = ASTParser.newParser(AST.JLS8);
Map<String, String> options = JavaCore.getOptions(); // 解析的时候加上java1.8的特性options
options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
parser.setCompilerOptions(options);
parser.setKind(ASTParser.K_COMPILATION_UNIT); // 申明传入的是java文件
parser.setSource(javaSource.toCharArray());
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
解析后的cu数据,这个结果就是正确的。方法、行范围都是准确的
STATUS
TYPE
getNameByCode
import lombok.Getter;
@Getter public class DicTaskEnum {
/**
* 状态
*/
@Getter public enum STATUS { /**
* 未执行
*/
NO_EXECUTION(1,"未执行"), /**
* 执行中
*/
EXECUTING(0,"执行中"); private final Integer code;
private final String name;
STATUS( Integer code, String name){
this.code=code;
this.name=name;
}
public static String getNameByCode( Integer code){
for ( STATUS typeEnum : STATUS.values()) {
if (typeEnum.getCode().equals(code)) {
return typeEnum.getName();
}
}
return null;
}
}
/**
* 状态
*/
@Getter public enum TYPE { /**
* 全量
*/
FULL_AMOUNT("全量"), /**
* 增量
*/
INCREMENTAL("增量"), /**
* 指定范围
*/
SPECIFIED_RANGE("指定范围"); private final String name;
TYPE( String name){
this.name=name;
}
}
}