与局部变量不同,使用 Rascal 的流程序中缺少对集合类型 class 字段的新分配
New assignment to collection-type class field absent from flow program with Rascal, unlike to local variables
考虑以下 Java 代码:
import java.util.LinkedList;
import java.util.List;
class Library {
List<String> loans = new LinkedList<>();
public List<String> searchUser(String name) {
List<String> usersFound = new LinkedList<>();
return loans;
}
}
和以下 Rascal 模块:
module Mwe
import lang::java::flow::JavaToObjectFlow;
import lang::java::jdt::m3::AST;
import IO;
void m() {
ast = createAstFromEclipseFile(|project://test/src/test.java|, true);
fp = createOFG({ast});
print(fp);
}
生成的流程程序将是:
flowProgram({
attribute(|java+field:///Library/loans|),
method(|java+method:///Library/searchUser(java.lang.String)|,[|java+parameter:///Library/searchUser(java.lang.String)/scope(name)/scope(0)/name|]),
constructor(|java+constructor:///Library/Library()|,[])
},{
assign(|java+method:///Library/searchUser(java.lang.String)/return|,|id:///|,|java+field:///Library/loans|),
newAssign(|java+variable:///Library/searchUser(java.lang.String)/usersFound|,|java+class:///java/util/LinkedList|,|java+constructor:///java/util/LinkedList/LinkedList()|,[])
})
因此,有一个 new
分配给 LinkedList
到 usersFound
,但与 loans
没有可比性。为什么会这样?这是预期的行为吗?
刚刚检查了实现,getStatements
函数中不包含字段初始值设定项(参见第 169 行的 lang::java::flow::JavaToObjectFlow
)。类似地,class 的静态初始值设定项将被忽略。
最好的方法是将其报告为错误,或者修复它并将其变成 pull-request。 (拉取请求是将其修复为不稳定的最快方法)
作为一种可能但工作量大的解决方法,您重写 AST 以将字段初始值设定项放入所有现有的构造函数中(或者如果存在 none,则添加一个构造函数)。
考虑以下 Java 代码:
import java.util.LinkedList;
import java.util.List;
class Library {
List<String> loans = new LinkedList<>();
public List<String> searchUser(String name) {
List<String> usersFound = new LinkedList<>();
return loans;
}
}
和以下 Rascal 模块:
module Mwe
import lang::java::flow::JavaToObjectFlow;
import lang::java::jdt::m3::AST;
import IO;
void m() {
ast = createAstFromEclipseFile(|project://test/src/test.java|, true);
fp = createOFG({ast});
print(fp);
}
生成的流程程序将是:
flowProgram({
attribute(|java+field:///Library/loans|),
method(|java+method:///Library/searchUser(java.lang.String)|,[|java+parameter:///Library/searchUser(java.lang.String)/scope(name)/scope(0)/name|]),
constructor(|java+constructor:///Library/Library()|,[])
},{
assign(|java+method:///Library/searchUser(java.lang.String)/return|,|id:///|,|java+field:///Library/loans|),
newAssign(|java+variable:///Library/searchUser(java.lang.String)/usersFound|,|java+class:///java/util/LinkedList|,|java+constructor:///java/util/LinkedList/LinkedList()|,[])
})
因此,有一个 new
分配给 LinkedList
到 usersFound
,但与 loans
没有可比性。为什么会这样?这是预期的行为吗?
刚刚检查了实现,getStatements
函数中不包含字段初始值设定项(参见第 169 行的 lang::java::flow::JavaToObjectFlow
)。类似地,class 的静态初始值设定项将被忽略。
最好的方法是将其报告为错误,或者修复它并将其变成 pull-request。 (拉取请求是将其修复为不稳定的最快方法)
作为一种可能但工作量大的解决方法,您重写 AST 以将字段初始值设定项放入所有现有的构造函数中(或者如果存在 none,则添加一个构造函数)。