有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用Rascal从Eclipse项目中提取类依赖项

我正在使用Rascal分析一个Eclipse Java项目,并确定该项目中的类依赖关系。更准确地说:当且仅当类A有一个方法(1)使用类型B的参数或(2)使用类型B的局部变量时,类A依赖于类B。在这里,我只对依赖关系A感兴趣->;B、 其中A和B在我的项目中都是类,并且都是不同的类。我已经从我的Eclipse项目中创建了一个M3模型,并且能够使用以下方法确定所需的参数(类型B):

{ <e.name, f> | e <- model@declarations, e.name.scheme == "java+parameter", f <- model@typeDependency[e.name], !(/java/ := f.path), f.scheme != "java+primitiveType" }

在这里,我获取M3模型的所有声明,过滤参数,并使用@typeDependency注释检索相应的类型(我不知道如何处理使用@types时获得的信息)。最后,我使用最后两条语句过滤掉所有类型与项目中的类无关的参数,如字符串和整数参数。因为我对流氓还很陌生,所以我想不出别的办法来达到这个目的

我现在的问题是:如何为我的项目检索类型B的局部变量?与@typeDependency结合使用scheme "java+variable"是不够的,因为这还包括迭代器或字符串类型的变量,它们与我的项目中的其他类有依赖关系,我对这些类型的变量不感兴趣。此外,结果集包含以下变量:

B b = field.method(); 

其中field是该类中的全局变量。因此,从b到类本身存在一个类型依赖关系,我也希望从我的结果中排除这些依赖关系。所以,我相信@typeDependency并没有给我所需要的信息

我发现this related post似乎用Rascal处理局部变量,但它使用AST而不是M3。我不知道如何在这个环境中使用AST(就像我说的,我只是Rascal的初学者),我想知道是否可以用M3来实现。我该怎么做

编辑:为了明确我想要实现的目标,我将给出一个小例子。假设我的项目有两个类,AB,并且B包含一些方法(methodB1methodB2,…)。 此外,类A具有以下结构:

class A {

   void methodA1(){
        B importantVar;
        importantVar.methodB1();
        ...
        String someVar1 = importantVar.methodB2();
        int someVar2 = importantVar.methodB3();
   }

   void methodA2(){
        A someVar3;
        ...
   }

}

我希望能够检索的变量是importantVar,因为它是一个局部变量,属于B类型(我的项目中的一个类)。我对someVar1someVar2不感兴趣,因为它们是局部变量,其类型与我的项目无关。在我之前给出的参数代码示例中,我用最后两条语句过滤掉了这些类型。此外,我对someVar3也不感兴趣,因为它有类型A,并且出现在同一个类中

我认为我应该能够使用@types检索我想要的局部变量,但我不确定如何检索。当使用@types时,我得到了一个TypeSymbol,我已经研究了这个数据类型的定义,看看如何操作它。TypeSymbol中的大多数数据类型都有一个名为decl的位置,我知道如何操作它。然而,问题是,我还收到一些没有这个位置的类型,比如\int()\array(..)。在这些情况下,位置decl未定义


共 (2) 个答案

  1. # 1 楼答案

    可以使用M3模型中的containment关系。所有局部变量都在declarations关系中声明,但它们也出现在containment中。如果您想获取方法m中的所有变量,可以查看containment[m]并对java+variable方案进行筛选

    有趣的是,当一个方法包含一个匿名类时。如果需要过滤在containment中使用的嵌套变量,则必须进一步查看containment(如传递闭包) 匿名嵌套类也是如此

    顺便说一下,M3模型有isVariableisClass等实用谓词,还有classes(M3)

  2. # 2 楼答案

    如果你只想分析一个特定的TypeSymbol,使用模式匹配。下面是一个例子

    TypeSymbol t;
    if (class(l,_) := t) {
      println(l);
    }
    

    或者在理解中

    { l | <_,class(l,_)> <- m3@types};
    

    或者作为理解中查找的一部分:

    { <v, l> | <_,v> <- m3@containment, isVariable(v), class(l,_) <- m3@types[v]};