java如何获取tree_如何从javac插件获取memberselecttree中的表达式类型?

本文探讨了在Java中使用JSR 269和编译器树API进行源代码分析时,如何获取成员选择表达式(如方法调用)的类型。作者遇到的问题是Trees.getTypeMirror返回null,期望找到一个更直接的方式来获取表达式的静态类型,而不需要手动分析整个树结构。目前的解决方案是在AbstractProcessor中使用TreePathScanner遍历树结构,并在visitMethodInvocation和visitMemberSelect方法中尝试获取类型信息。
摘要由CSDN通过智能技术生成

我试图用jsr 269格式编写一个注释处理器,它使用javac的编译器树api来做一些源代码分析。我对成员选择表达式感兴趣,比如方法调用。

我可以很容易地得到所选方法(或字段等)的名称。但我想知道成员是从哪种类型中选择的,我似乎找不到一个简单的方法来完成这项工作。

Trees.getTypeMirror

收益率

null

对于我尝试调用的所有内容(javadoc没有给出任何提示)。

我想我可以详尽地分析成员select左侧的各种表达式,并通过递归分析确定表达式的静态类型:

NewClassTree

,

TypeCastTree

,

MethodInvocationTree

,

ArrayAccessTree

,以及许多其他。但是这看起来像是很多容易出错的工作,而且很明显javac已经知道表达式的静态类型,因为它需要这些信息用于很多目的。但是我怎样才能获得这种类型的信息呢?

到目前为止我所拥有的:

import com.sun.source.tree.MemberSelectTree;

import com.sun.source.tree.MethodInvocationTree;

import com.sun.source.util.TreePath;

import com.sun.source.util.TreePathScanner;

import com.sun.source.util.Trees;

import java.util.Set;

import javax.annotation.processing.AbstractProcessor;

import javax.annotation.processing.RoundEnvironment;

import javax.annotation.processing.SupportedAnnotationTypes;

import javax.annotation.processing.SupportedSourceVersion;

import javax.lang.model.SourceVersion;

import javax.lang.model.element.Element;

import javax.lang.model.element.TypeElement;

@SupportedAnnotationTypes("*")

@SupportedSourceVersion(SourceVersion.RELEASE_6)

public class PublicProcessor extends AbstractProcessor {

public @Override boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {

for (Element e : roundEnv.getRootElements()) {

final Trees trees = Trees.instance(processingEnv);

final TreePath root = trees.getPath(e);

new TreePathScanner() {

public @Override Void visitMethodInvocation(MethodInvocationTree node, Void p) {

System.err.println("visiting method invocation: " + node + " of kind: " + node.getMethodSelect().getKind());

TreePath expr = TreePath.getPath(root, node);

System.err.println(" of type: " + trees.getTypeMirror(expr));

return super.visitMethodInvocation(node, p);

}

public @Override Void visitMemberSelect(MemberSelectTree node, Void p) {

System.err.println("accessing member: " + node.getIdentifier());

System.err.println(" from: " + getCurrentPath().getCompilationUnit().getSourceFile().toUri());

TreePath expr = TreePath.getPath(root, node.getExpression());

System.err.println(" in expr: " + expr.getLeaf());

System.err.println(" of type: " + trees.getTypeMirror(expr));

return super.visitMemberSelect(node, p);

}

}.scan(root, null);

}

return true;

}

}

当运行在一些简单的代码上进行方法调用时,它会打印出什么:

visiting method invocation: new Class().method() of kind: MEMBER_SELECT

of type: null

accessing member: method

from: .../Whatever.java

in expr: new Class()

of type: null

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值