确定在Java中传递给方法的所有字符串(动态构建和文本)

确定在Java中传递给方法的所有字符串(动态构建和文本),java,eclipse-jdt,static-code-analysis,Java,Eclipse Jdt,Static Code Analysis,我试图构建一个静态代码分析,它允许收集传递给函数的所有字符串,而无需运行代码。我正在使用EclipseJDT3.10.0来解析代码 假设/预补偿: 每个传递的参数都可以解析为字符串文字 该值不会保存到任何非静态字段,然后在另一个调用中传递 解析器可以识别和访问所有调用者 已标识所检查方法的MethodInvocation 我所拥有的: 目前,我能够识别该特定方法上的所有MethodInvocation,因此能够收集作为StringLiteral传递的所有参数。 我可以看到所有参数类型,但当然,无

我试图构建一个静态代码分析,它允许收集传递给函数的所有字符串,而无需运行代码。我正在使用EclipseJDT3.10.0来解析代码

假设/预补偿:

每个传递的参数都可以解析为字符串文字 该值不会保存到任何非静态字段,然后在另一个调用中传递 解析器可以识别和访问所有调用者 已标识所检查方法的MethodInvocation 我所拥有的:

目前,我能够识别该特定方法上的所有MethodInvocation,因此能够收集作为StringLiteral传递的所有参数。 我可以看到所有参数类型,但当然,无法确定参数、字段、对象等的值,因为值绑定只能在运行时使用

问题

假设每个传递的参数,无论类型如何,在某个时候都可以解析为StringLiteral或StringLiteral的串联,我应该能够确定程序传递给此方法的所有值的不同集合。 有没有一种方法可以递归地确定所有方法调用的字符串值,而无需跟踪每个stacktrace并手动实现每次发生的逻辑

想象一下下面的例子:

我能想到的使用EclipseJDT的唯一方法是将每个非StringLiteral的参数添加到一个工作集,并使用ASTParser再开始一次迭代,以确定传递的值的设置位置或来源。然后我将这个位置添加到工作集中,并再次迭代。最后,这将引导我找到所有可能的论点。
不幸的是,使用这种方法,我必须为每一种可能的传递方法实现逻辑。想象一下,在上述两种方法旁边的所有其他可能性。通过静态分析,检查所有可能的数据流到给定方法中通常是不可行的。你所概述的方法可以适用于一小部分程序,直到你遇到递归,事情会在什么时候爆发


也许一个全面的测试套件会给出比静态分析更好的结果。

这不是一个通用的解决方案。函数的被调用方都是可解析的,实际上不会超过特定堆栈。递归是不可能的。基本上,我们希望验证用于调用函数的字符串资源是否存在于数据库的初始数据集中。因此,有一组有限的输入数据,以及如何形成这些数据的特定规则集。通过测试套件进行测试是可能的,但即使在开发过程中也要花费更多的时间。一般解决方案和一个示例只是长期的两个极端。如果您确信不会遇到复杂的程序结构,请继续。但是,正如问题已经指出的那样,Java的每一种语言特性都会增加工具的复杂性。如果还有其他问题,你应该处理吗?转换各种各样的循环?试着接球?StringBuilder操作?等等。这对你来说可能会爆炸,也可能不会爆炸。如果您继续:您是否考虑过使用搜索引擎来查找给定方法的所有调用方,而不是每次迭代都遍历完整的AST?我假设SearchEngine指的是IDE中的用法搜索?问题是,是否有更聪明的方法来做这件事,而不是冒着爆炸的风险。另一种方法是手动评估每个可能的调用者,或者对系统进行完全重构。两者都需要很多时间,在不久的将来都不可能实现。该工具基本上应该是手动搜索所有调用方的替代品。org.eclipse.jdt.core.search.SearchEngine是jdt/core中的一个类,您可以使用它来自动搜索调用方,类似于IDE中的搜索或调用层次结构。您有如何使用它的实际示例吗?我发现这是他们说你必须打开工作区上下文的地方。在我看来,就我所发现的例子而言,这似乎是相当多的工作
public class IAmAnalysed{
    public void analysedMethod(String argument){
        //do something useful
    }
}

//Values in a map
hashMap.put("test", "TestString");
hashMap.put("test2", "TestString2");
for (Map.Entry<String, String> e : hashMap.entrySet()) {
    iAmAnalysed.analysedMethod(e.getValue);
}

//util method
public void util(String argument){
    iAmAnalysed.analysedMethod(argument + "utilCalled");  
}
util("TestString3")
TestString
TestString2
TestString3utilCalled