我正在尝试使用 Java Compiler API 分析 .java 文件。我当前的问题是找出给定变量、方法或类是否在程序的特定范围内已知(范围是指在 Java Compiler API 本身中定义的范围,请参见此处:http:// docs.oracle.com/javase/6/docs/jdk/api/javac/tree/com/sun/source/tree/Scope.html)。
Java 编译器 API ( http://docs.oracle.com/javase/6/docs/jdk/api/javac/tree/com/sun/source/util/Trees.html )的 Trees 类有一个实用方法来这样做:是可访问的。如果目标节点在给定范围内已知,则此方法获取 Scope 和目标节点及其声明的类型并返回 true。
不幸的是,我不知道如何创建这个 DeclaredType 对象(从现在开始,我只能编写类名并且不再发布超链接,因为 stackoverflows 垃圾邮件预防:javax.lang.model.type.DeclaredType)。我可以询问目标节点的类型(javax.lang.model.element.Element [asType()-method]),但它返回的是 TypeMirror 实例,而不是 DeclaredType。
目前我使用这两行代码:
final DeclaredType nodeType = (DeclaredType) nodeTypeMirror;
isAccessible = referenceCompTree.isAccessible(referenceScope, nodeElement, nodeType);
其中“referenceCompTree”是当前程序的树实例,referenceScope 是有问题的 Scope,nodeElement 是有问题的节点和 nodeType ...嗯,应该是有问题的节点的 DeclaredType。
这种直接类型转换方法适用于一种情况,即类的节点(我认为这是有效的,因为节点声明了自己的类型,因此它的 typeMirror 等效于它自己的类型)。但它绝对不适用于原始类型的变量(如标题中所述),我不确定它是否适用于变量。
有没有人知道
- 如何将 Trees 的 isAccessible 方法用于原始类型,或者更具体地说:如何将 TypeMirror 实例转换为 DeclaredType 实例?或者
- 如何在不使用 isAccessible 的情况下获取我想要的信息(如果变量、类或方法在给定范围内已知)?
附录:
我确实对这两个问题进行了进一步的研究,并想向您介绍我发现的一些事情:
- 有一个名为 Types (javax.lang.model.util.Types) 的实用程序类。可以使用标准 Java Compiler API 类(在本例中为:com.sun.source.util.JavaTask)获取类型的实例。此对象有一个方法 (getDeclaredType),它返回给定 TypeElement 和一些 TypeMirror 的 DeclaredType 实例。但是这个方法对我也不起作用,因为它会抛出一个错误,指出我以前很少输入参数。我想这个方法的唯一目的是为给定的原始类和一些类型参数返回一个 DeclaredType 实例(例如,要为 HashMap 创建 DeclaredType 实例,您可以将此方法与用于 HashMap 的 typeElement 和用于 String 的两个 typeMirror 一起使用)。显然这不是我打算做的。
- 我试图通过查找变量、类或方法在给定范围内是否已知变量、类或方法来编写解决方法,方法是查找其各自的修饰符并搜索范围树,但我不相信这种方法,主要原因有两个:不确定我是否在我的搜索算法中正确地获得了 Java 范围构造的所有特殊情况,其次这似乎非常不必要,因为我试图重新实现一些(似乎)已经存在并且 Java 编译器一直在执行的东西。天啊,即使是我的 NetBeans 也一直告诉我给定的变量、方法或类是否在我当前的范围内是已知的。所以必须有办法。