【发布时间】:2016-04-24 16:55:13
【问题描述】:
我是 AST 新手(我第一次编写插件)。表达式在现实生活中可能非常复杂。例如,我想知道如何解决分配的左侧和右侧。
class Visitor extends ASTVisitor
{
@Override
public boolean visit(Assignment node)
{
//here, how do I get the final name to each each side of the assignment resolves?
}
}
我还有一个疑问,如何获取用于调用方法的实例?
public boolean visit(MethodInvocation node)
{
//how do I get to know the object used to invoke this method?
//like, for example, MyClass is a class, and it has a field called myField
//the type of myField has a method called myMethod.
//how do I find myField? or for that matter some myLocalVariable used in the same way.
}
假设以下作业
SomeType.someStaticMethod(params).someInstanceMethod(moreParams).someField =
[another expression with arbitrary complexity]
如何从Assigment 节点到达someField?
另外,MethodInvocation 的什么属性为我提供了用于调用该方法的实例?
编辑 1: 鉴于我收到的答案,我的问题显然不清楚。我不想解决 this 特定的表达式。在给定任何分配的情况下,我希望能够找出分配给它的名称,以及分配给第一个的名称(如果不是右值)。
因此,例如,方法调用的参数可以是字段访问或先前声明的局部变量。
SomeType.someStaticMethod(instance.field).someInstanceMethod(type.staticField, localVariable, localField).Field.destinationField
所以,这是一个有希望的客观问题:给定任何左侧和右侧都具有任意复杂性的赋值语句,如何获得被分配到的最终字段/变量,以及最终(如果有)字段/分配给它的变量。
编辑 2: 更具体地说,我想要实现的是不变性,通过注释 @Const:
/**
* When Applied to a method, ensures the method doesn't change in any
* way the state of the object used to invoke it, i.e., all the fields
* of the object must remain the same, and no field may be returned,
* unless the field itself is marked as {@code @Const} or the field is
* a primitive non-array type. A method annotated with {@code @Const}
* can only invoke other {@code @Const} methods of its class, can only
* use the class's fields to invoke {@code @Const} methods of the fields
* classes and can only pass fields as parameters to methods that
* annotate that formal parameter as {@code @Const}.
*
* When applied to a formal parameter, ensures the method will not
* modify the value referenced by the formal parameter. A formal
* parameter annotated as {@code @Const} will not be aliased inside the
* body of the method. The method is not allowed to invoke another
* method and pass the annotated parameter, save if the other method
* also annotates the formal parameter as {@code @Const}. The method is
* not allowed to use the parameter to invoke any of its type's methods,
* unless the method being invoked is also annotated as {@code @Const}
*
* When applied to a field, ensures the field cannot be aliased and that
* no code can alter the state of that field, either from inside the
* class that owns the field or from outside it. Any constructor in any
* derived class is allowed to set the value of the field and invoke any
* methods using it. As for methods, only those annotated as
* {@code @Const} may be invoked using the field. The field may only be
* passed as a parameter to a method if the method annotates the
* corresponding formal parameter as {@code @Const}
*
* When applied to a local variable, ensures neither the block where the
* variable is declared or any nested block will alter the value of that
* local variable. The local variable may be defined only once, at any
* point where it is in scope and cannot be aliased. Only methods
* annotated as {@code @Const} may be invoked using this variable, and
* the variable may only be passed as a parameter to another method if
* said method annotates its corresponding formal parameter as
* {@code @Const}
*
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD,
ElementType.LOCAL_VARIABLE})
@Inherited
public @interface Const
{
}
要实现这一点,我要做的第一件事就是将作业左侧标记为@Const(很简单)。我还必须检测和表达式的右侧何时是标记为@Const的字段,在这种情况下,它只能在相同类型的@Const变量的定义处赋值。
问题是我很难在表达式右侧找到最终字段,以避免为字段产生别名并使 @Const 注释无用。
【问题讨论】:
-
你在这里使用什么库? (PMD 或类似的东西?)
-
eclipse jdt 用于插件开发。
-
好的,那么你想到达形成的 AST 的叶子吗?
-
我想访问作为赋值的左右解析表达式的字段(或局部变量或参数)的
Name。所以我可以解决它并获取它的注释。 -
@FinnTheHuman 看看你最近发布的一些其他问题,我觉得你可能有兴趣看看 Annotation Processors 和/或 LombokProject。两者都旨在在解析 Java 源文件时对它们的 AST 执行自定义处理。注释处理器获得对 AST 树的只读访问权限(但仍然可以向其添加警告和错误),而 LombokProject 获得对 AST 树的读写访问权限。也许这可以帮助你。
标签: java eclipse abstract-syntax-tree eclipse-jdt