jsr269提供annotation processor,允许我们在编译器编译过程中挂钩子。http://projectlombok.org/ 的许多功能正是基于此实现。
但有时候可能需要解析语法正确,但没有语义的Java文件(比如对工程中的单个java源文件的方法等元素建索引),这个时候jsr269就不能满足需求了。此时,我们只要语法树(ast)就可以了,也就是说不需要编译通过,只需要语法解析,可选的parser我找到了3个:
— antlr parser
— eclipse jdt parser
— javac parser
下面一个例子使用javac parser来获得ast,并采用visitor模式遍历整颗语法树,提取文件中的所有方法。
注意:
需要在classpath中引入jdk的tools.jar
很多类不属于标准api,目前只在openjdk6,7上做过测试
Java代码
- package org.jilen;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.nio.channels.FileChannel;
- import java.nio.channels.FileChannel.MapMode;
- import java.nio.charset.Charset;
- import java.util.ArrayList;
- import java.util.List;
- import com.sun.source.tree.MethodTree;
- import com.sun.source.util.TreeScanner;
- import com.sun.tools.javac.file.JavacFileManager;
- import com.sun.tools.javac.parser.Parser;
- import com.sun.tools.javac.parser.ParserFactory;
- import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
- import com.sun.tools.javac.util.Context;
- public class JDKParser {
- private ParserFactory factory;
- public JDKParser() {
- factory = getParserFactory();
- }
- public List<String> parseMethodDefs(String file) throws IOException {
- JCCompilationUnit unit = parse(file);
- MethodScanner scanner = new MethodScanner();
- return scanner.visitCompilationUnit(unit, new ArrayList<String>());
- }
- JCCompilationUnit parse(String file) throws IOException {
- Parser parser = factory.newParser(readFile(file), true, false, true);
- return parser.parseCompilationUnit();
- }
- private ParserFactory getParserFactory() {
- Context context = new Context();
- JavacFileManager.preRegister(context);
- ParserFactory factory = ParserFactory.instance(context);
- return factory;
- }
- CharSequence readFile(String file) throws IOException {
- FileInputStream fin = new FileInputStream(file);
- FileChannel ch = fin.getChannel();
- ByteBuffer buffer = ch.map(MapMode.READ_ONLY, 0, ch.size());
- return Charset.defaultCharset().decode(buffer);
- }
- //扫描方法时,把方法名加入到一个list中
- static class MethodScanner extends
- TreeScanner<List<String>, List<String>> {
- @Override
- public List<String> visitMethod(MethodTree node, List<String> p) {
- p.add(node.getName().toString());
- return p;
- }
- }
- public static void main(String[] args) throws IOException {
- JDKParser parser = new JDKParser();
- for (String method : parser.parseMethodDefs(“User.java”)) {
- System.out.println(method);
- }
- }
- }
1.parser.parseCompilationUnit();获得语法树
2.MethodScanner扫描整颗语法树,整个扫面其实是fold/reduce过程
http://jilen.iteye.com/blog/1479632
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91383 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!