【问题标题】:Locating method/variable declaration in Java with Rascal使用 Rascal 在 Java 中定位方法/变量声明
【发布时间】:2017-10-03 10:39:11
【问题描述】:

我正在寻找一个库或工具,它们提供构建数据结构的功能,我可以使用它来查找在另一个范围内的类中使用的变量或方法声明。

示例代码:

class A
{
    public void methodA()
    {
         B external = new B();
         external.methodB();    // I would like to know the name/location where this method is declared. something like: classB.java ... line 3
    }
}

class B
{
    public void methodB()
    {

    }
}`

Rascal 会是检索此类信息的好人选吗?我以前一直在使用该工具。据我所知,我可以创建一个 AST,但这没有足够的信息来确定某些变量/方法的声明范围。 如果这不是合适的候选人,对替代方案有什么想法吗?我目前正在研究的候选人名单是:Antlr/symtab; JavaParser/JavaSymbolSolver;勺子;流氓; JDT

【问题讨论】:

    标签: rascal


    【解决方案1】:

    是的,肯定有几个选项可以找出声明的位置。

    第一个答案是从 AST 中的任何节点检索decl 信息,如下所示,例如:

     rascal>myTree.decl
     loc: |java+parameter:///myClass/fac(int)/n|
    

    从位置值可以看出这是myClass类中名为fac的方法中名为n的参数。

    现在您可以使用位置的访问字段和功能(例如myTree.decl.path 等)剖析位置以查找父级,或者您可以在 AST 构建器也可以构建的 M3 模型中进一步查找您的信息:

     model = createM3FromEclipseProject(|project://myProject);
    

    此模型包含如下关系:rel[loc, loc] containment,均在此处定义:

    要找到包含关系中的父母,您可以尝试以下操作:

    model.containment[myTree.decl]
    

    或者这个用于反向查找:

    invert(model.containment)[myTree.decl]
    

    对于您的特定问题,rel[loc src, loc name] uses 关系也很有趣,它将完全限定的声明名称映射到源位置使用,rel[loc name, loc src] declarations 将限定名称映射到它们被声明的位置。

    【讨论】:

    • 我在自己的示例中尝试了您的答案,但有些事情对我来说不是很清楚。您将什么放入 myTree 以及 myTree.decl 是如何工作的。我与您的示例最接近的是 unit@decl.path,其中 unit 是来自 createAstsFromEclipseProject 的 compilerUnit 有了这个我可以做 model@containment[unit@decl] 这似乎会导致您在上面描述的内容。你能解释一下为什么你可以使用字段 operator(.) i.s.o.我正在使用的注释。
    • 我认为我使用的是最新的持续构建,而您可能使用的是较旧的稳定版本。我们最近将 M3 模型从使用注释切换到“关键字字段”,因此从 @ 移动到 .
    猜你喜欢
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    相关资源
    最近更新 更多