资讯专栏INFORMATION COLUMN

Java代码分析器(四): 代码改写技术

沈建明 / 3411人阅读

摘要:另载于一般的工具只能分析代码,不能改变代码,除了的重构功能。这个小框架让你看文章前就能上手,快速对代码库做分析改写,性能很高下面介绍经过验证的具体技术,能局部修改代码,调就行了感谢。由于以上原因,这套便利的在不再保证支持。

另载于 http://www.qingjingjie.com/blogs/5

一般的工具只能分析代码,不能改变代码,除了IDE的重构功能。但我们还是有办法实现的。

不想让黑科技失传,趁着Java 7还在广泛使用,赶紧写下来(可能无法支持Java 8)。

这个小框架让你看文章前就能上手,快速对代码库做分析/改写,性能很高: https://github.com/sorra/exia

下面介绍经过验证的具体技术,能局部修改代码,调API就行了(感谢Eclipse)。文档里很难查到这些,痛的回忆…… (有句名言说: 画一条线值1美元,知道在哪画线值9999美元。)

核心代码如下:

import org.eclipse.jface.text.Document;
import org.eclipse.text.edits.TextEdit;

CompilationUnit cu = parseAST(...); //parse方法参见系列文章
cu.recordModifications(); //开始记录AST变化事件
doChangesOnAST(...); //直接在树上改变结点,参见系列文章
Document document = new Document(content);
TextEdit edits = cu.rewrite(document, formatterOptions); //树上的变化生成了像diff一样的东西
edits.apply(document); //应用diff
return document.get(); //得到新的代码,未改动的部分几乎都保持原样

我用的formatterOptions:

    private static final Map formatterOptions = DefaultCodeFormatterConstants.getEclipseDefaultSettings();
    static {
        formatterOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
        formatterOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
        formatterOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
        formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
        formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "2");
        formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, "100");
        formatterOptions.put(DefaultCodeFormatterConstants.FORMATTER_JOIN_LINES_IN_COMMENTS, DefaultCodeFormatterConstants.FALSE);
        // change the option to wrap each enum constant on a new line
        formatterOptions.put(
            DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS,
            DefaultCodeFormatterConstants.createAlignmentValue(
            true,
            DefaultCodeFormatterConstants.WRAP_ONE_PER_LINE,
            DefaultCodeFormatterConstants.INDENT_ON_COLUMN));
    }

如果改动幅度很大,被改的代码可能会缩进混乱。忍一忍吧,这套API原本会把代码改错,我定位到bug,提给Eclipse,他们发现问题很深,最后没什么办法,只能牺牲缩进换来代码正确性。

由于以上原因,这套便利的API在Java 8不再保证支持。据说只能用原始的ListRewrite来改代码…… 珍惜着用吧。

最后再介绍两个便利方法:

ASTNode#delete()
结点能把自身从树上移除。调这个方法不需要知道parent结点的类型,用起来就知道方便了。

replaceNode
我仿写的方法,能任意替换一个结点,不需要知道parent结点的类型。

    public static void replaceNode(ASTNode old, ASTNode neo) {
      StructuralPropertyDescriptor p = old.getLocationInParent();
      if (p == null) {
          // node is unparented
          return;
      }
      if (p.isChildProperty()) {
          old.getParent().setStructuralProperty(p, neo);
          return;
      }
      if (p.isChildListProperty()) {
          List l = (List) old.getParent().getStructuralProperty(p);
          l.set(l.indexOf(old), neo);
      }
    }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64352.html

相关文章

  • UAVStack的慢SQL数据库监控功能及其实现

    摘要:页面展示的统计追踪等信息则通过的接口获取四功能展示数据库监控目前已实现的功能有分类统计数据库连接池监控慢耗时分布统计慢统计慢追踪以及调用链日志关联功能。 作者: 王林林 出处:UAVStack智能运维 来源:宜信技术学院技术沙龙001期|AI中台:一种敏捷的智能业务支持方案|宜信技术沙龙 3月28日晚8点线上直播,点击报名 UAVStack是一个全维监控与应用运维平台。UAV.Mon...

    luodongseu 评论0 收藏0
  • 深入解析阿里Android热修复技术原理

    摘要:不过它确实各方面都做了大量的优化,本文中的很多知识点也来源于阿里的热修复技术原理一书,本书值得一读,里面就是基于框架来编排的。 前言;本文框架什么是热修复?热修复框架分类技术原理及特点Tinker框架解析各框架对比图总结通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单描述一下Tinker的框架结构。 一、什么是热修复?1.正常开发流程showI...

    番茄西红柿 评论0 收藏0

发表评论

0条评论

沈建明

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<