gpt4 book ai didi

java - 我如何到达 AST 表达式的底部

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:29:45 25 4
gpt4 key购买 nike

我是 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:鉴于我收到的答案,我的问题显然不清楚。我不想解决这个 特定的表达式。我希望能够在给定任何分配的情况下找出分配给它的名称,以及分配给第一个名称的名称(如果不是右值)。

因此,例如,方法调用的参数可以是字段访问或先前声明的局部变量。

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(非常简单)。我还必须检测 and 表达式的右侧何时是标记为 @Const 的字段,在这种情况下,它只能在相同类型的 @Const 变量的定义中赋值。

问题是我真的很难在表达式的右侧找到最终字段,以避免别名字段和呈现 @Const 注释无用。

最佳答案

首先引用我发布的一个答案:

You will have to work with bindings. To have bindings available, that means resolveBinding() not returning null, possibly additional steps I have posted are necessary.

以下访问者应该可以帮助您做您想做的事:

class AssignmentVisitor extends ASTVisitor {

public boolean visit(Assignment node) {
ensureConstAnnotationNotViolated(node);
return super.visit(node);
}

private void ensureConstAnnotationNotViolated(Assignment node) {
Expression leftHandSide = node.getLeftHandSide();
if (leftHandSide.getNodeType() == ASTNode.FIELD_ACCESS) {
FieldAccess fieldAccess = (FieldAccess) leftHandSide;
// access field IVariableBinding
fieldAccess.resolveFieldBinding();
// access IAnnotationBindings e.g. your @const
fieldAccess.resolveFieldBinding().getAnnotations();
// access field ITypeBinding
fieldAccess.getExpression().resolveTypeBinding();
} else {
// TODO: check possible other cases
}

}
}

关于java - 我如何到达 AST 表达式的底部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36826136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com