资讯专栏INFORMATION COLUMN

Java代码分析器(一): JDT入门

binaryTree / 3668人阅读

摘要:另载于这是一个关于抽象语法树的故事。抽象语法树是对程序代码的结构化表示,是对代码进行词法分析语法分析后得到的产物。

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

这是一个关于抽象语法树(Abstract Syntax Tree, AST)的故事。

抽象语法树是对程序代码的结构化表示,是对代码进行词法分析、语法分析后得到的产物。编译器要用到它,很多生产力工具也要用它,例如:

IDE可以自动重构、自动生成一些代码、自动对不规范代码发出警告。这是很强很实惠的功能。

一个大型软件项目常常有几百人合作,几百万行代码。很多代码规范难以百分百落实,很多编程错误潜藏在项目中。这时候我们会考虑Sonar, FindBug, Checkstyle之类的代码分析工具来帮助我们扫描出巨量代码中存在的问题。

国内有位老兄就做了个自动生成测试代码的工具。(但不要生成功能代码,我们要构建良好的抽象和简洁的代码)

我司的系统要进行架构迁移,其中有百万行代码需要修改,用人力来做是很可怕的。我做了个工具来自动完成这件事。

它们利用AST来对大量程序代码做自动化处理,给了我们莫大的帮助。甚至自动写代码也不是不可能。那么我们自己能玩一玩AST这种高大上的东西吗?

能。Eclipse这个开源的Java IDE就提供了一个库来帮助我们达到目的,它的名字是JDT(Java Development Tools)。我们使用它的核心模块JDT Core。

这个项目历史悠久,功能强力,早期开发者有《设计模式》GoF的作者。

它提供了一套关于AST的API,能解析Java代码,生成、分析和操作AST结构。有了它,我们就不用自己实现高难度的词法分析和语法分析了。

动手搞起

(嫌麻烦可以看这个小框架 https://github.com/sorra/exia)
首先准备好库文件——打开你的Eclipse安装目录,在搜索框中搜索以下jar文件(*是通配符):
org.eclipse.jdt.core_*
org.eclipse.core.contenttype_*
org.eclipse.core.jobs_*
org.eclipse.core.resources_*
org.eclipse.core.runtime_*
org.eclipse.equinox.common_*
org.eclipse.equinox.preferences_*
org.eclipse.equinox.registry_*
org.eclipse.osgi_*
org.eclipse.text_*
如果有多个版本,取最新版本。统统copy出来,添加到你的项目中。
源代码包是org.eclipse.jdt.core.source_* 用Eclipse的Attach source功能把它连到第一个jar上,可以阅读源代码。

先来溜一段起步代码,把一段Java代码解析成AST。

import java.util.Map;
import org.eclipse.jdt.core.dom.*;
import org.eclipse.jdt.JavaCore;
......
public static void main(String[] args) {
    ASTParser parser = ASTParser.newParser(AST.JLS4); //设置Java语言规范版本
    parser.setKind(ASTParser.K_COMPILATION_UNIT);

    Map compilerOptions = JavaCore.getOptions();
    compilerOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7); //设置Java语言版本
    compilerOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
    compilerOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
    parser.setCompilerOptions(compilerOptions); //设置编译选项

    char[] src = "class A { void method1(int b){;} }".toCharArray();
    parser.setSource(src);

    CompilationUnit cu = (CompilationUnit) parser.createAST(null); //这个参数是IProgessMonitor,用于GUI的进度显示,我们不需要,填个null. 返回值是AST的根结点

    System.out.println(cu); //把AST直接输出看看啥样
}

AST作为抽象语法树,它就是一棵树,有点像XML的DOM树。
例子中的树大概长这样:

CompilationUnit
       |
     class
    |     |
    A   method1
       |   |   |
     void []   {}
           |   |
          arg  ;
         |  |
        int b

延伸阅读:http://help.eclipse.org/ 点击JDT Plug-in User Guide -> Programmer"s Guide -> JDT Core。

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

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

相关文章

  • Java代码析器(二): 使用DOM API操作抽象语法树

    摘要:请下载一份源代码,这里有个对应的源码包元素的组合需要遵守基本的语法规则不是全部。名字也是表达式的一种,是指变量名类名包名等元素,它们在中都属于抽象类,分为和两种具体类。 另载于 http://www.qingjingjie.com/blogs/3 上篇博客末尾提到了一棵抽象语法树长什么样子。JDT提供了一套DOM API来让我们顺利地控制这样一棵树。 读完本篇后请继续完成上篇的延伸阅读...

    pf_miles 评论0 收藏0
  • logback管理日志入门

    摘要:是由创始人设计的又一个开源日志组件。此外完整实现使你可以很方便地更换成其它日志系统如或。访问模块与容器集成提供通过来访问日志的功能。依赖配置的核心,包建议使用来管理日志,方便替换底层实现,要用,就在依赖中加入包和包。 Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-classic和logback-ac...

    bluesky 评论0 收藏0
  • Java代码析器(三): 以强大的属性描述符写出通用代码

    摘要:最后提供一段我用写的代码供参考行就能把任意代码结构转换成输出使用了库利用强大的属性描述符,写出通用的转换代码,避免了给每个结点类写对应的转换代码几十种结点类,要死啊。 另载于 http://www.qingjingjie.com/blogs/4 上篇介绍的形形色色的语法元素大概让人眼花缭乱了,而且每种元素都对应一个Java类。知道是一回事,使用就是另一回事了,这么多个类,要给每个类写对...

    andot 评论0 收藏0
  • 分享代码片段:如何对自动生成的java代码做自动格式化,以达到接近手写的效果

    摘要:原文链接如题,有的时候,我们会采用自动生成代码的方式来完成一些任务,比如根据业务数据自动生成调用的供用户下载使用这样自动生成的代码,如果未经格式化处理,基本上是不可读的正好,我们常用的,快捷键就能自动格式化代码那么,下面这段代码,就是将的这 原文链接:https://gist.github.com/pfmiles/653c8b59e795698c867d 如题,有的时候,我们会采用自...

    lykops 评论0 收藏0
  • 使用JDK自带的VisualVM进行Java程序的性能分析

    摘要:是什么是自带的一个用于程序性能分析的工具,安装完毕后就有啦,在安装目录的文件夹下能找到名称为。假设我自己实现了一个快速排序算法,我想测一测它的性能。首先我在下图代码第行执行我的快速排序算法之处设置一个断点。回到,按结束应用程序的执行。 VisualVM是什么? showImg(https://segmentfault.com/img/remote/1460000016730111); ...

    piapia 评论0 收藏0

发表评论

0条评论

binaryTree

|高级讲师

TA的文章

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