精准测试之ASTParser 解析含有emum 枚举方法的类文件的踩坑记

问题描述

使用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;
  }
}
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值