【问题标题】:Tool to analyze and compare logic of similar functions?分析和比较类似功能逻辑的工具?
【发布时间】:2012-02-14 16:21:02
【问题描述】:

我最近选择了一个包含大量重复代码库的项目。问题是重复的功能不是由同一个人编写的,也不是在他们之间复制的。

那么,有没有工具可以用来比较两个函数的实际逻辑?以下是一些有用的限制条件。

  • 忽略顺序不重要的顺序(例如设置属性)
  • 应分析变量名称的相似性,但如果出于相同原因使用,则不需要匹配
  • 深入研究被比较的函数调用的其他方法,并扁平化比较逻辑

理想情况下,该工具将生成单个函数输出。实际的逻辑差异将以某种方式突出显示。它甚至可以是为逻辑上的差异定义单独的函数的形式,将它们传递给包含相同逻辑的主函数。

这听起来确实是一项艰巨的任务,但有没有人遇到过试图做这些事情的工具?

编辑

虽然提到了一些很酷的工具,但在比较两种方法的逻辑时,它们似乎都不会考虑被调用函数的内容。如果我不正确,请告诉我!

【问题讨论】:

  • 我认为这样的“工具”是存在的,它是一个人类程序员:)
  • @vulkanino:这是否意味着你会来为我分析代码?我只需要花 50-200 美元一次,就可以在需要时随时使用这个“工具”?
  • :) 我的成本更高,但你肯定会在 VWorker 上找到更便宜的“工具”;)
  • 如果你用谷歌搜索,那里有很多工具。我看到 Simian 在结果列表中高居榜首。尝试其中一些,看看它们是否满足您的需求。不过,我怀疑它们中的任何一个都达到了你想要的程度。
  • @DBM:这正是我的问题。所有工具似乎都停留在它们开始的功能级别。我真正需要的是能够深入研究子函数的东西。

标签: c# static-analysis


【解决方案1】:

如果您下载 Visual Studio vNext Ultimate 的开发者预览版,它包含一个新的代码克隆检测功能: http://msdn.microsoft.com/en-us/library/hh205279(v=vs.110).aspx

http://blogs.msdn.com/b/zainnab/archive/2011/12/13/visual-studio-11-developer-preview-code-clone-detection-aka-code-clone-analysis.aspx

开发者预览版 Visual Studio 的下载链接: http://www.microsoft.com/download/en/details.aspx?id=27543

【讨论】:

  • 这看起来很接近。希望我有机会尝试一下。
  • 除非我遗漏了什么,否则这与其他工具具有相同的困难——它不会检查被调用函数中的代码。 (所以如果函数 A 调用 B、C 和 D,那么 B、C 和 D 中的代码与函数 A 和 Z 的比较无关。)
  • 我不知道为什么这个答案被赞成,更不用说标有赏金了。 Visual Studio 克隆检测器匹配标记序列。它不能可靠地找到函数边界,更不用说解析代码、找出名称和类型,或者确定函数是否相似。它会找到复制和粘贴的代码; OP 明确表示他想要匹配的代码没有被复制和粘贴。
【解决方案2】:

如果您有 ReSharper,则有一个 ReSharper 插件 Agent Ralf

特工Ralf主页引述:

在某些情况下,两个给定的方法在功能上可能是等效的(相同的输入产生相同的输出和副作用),但在文本上不等效。例如,两种方法可能仅在局部变量的命名上有所不同,而在其他方面则相同。特工 Ralph 可以检测到这种情况以及其他类似情况,并确定这些方法在功能上是等效的

【讨论】:

    【解决方案3】:

    CodeRush 上有重复检测和合并功能。 (http://devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/duplicate_code.xml)

    此功能检测到重复代码。我不确定它是否能够检测/比较类似功能的逻辑。

    希望对您有所帮助。

    【讨论】:

      【解决方案4】:

      您始终可以编写自己的代码。这属于适当的单元测试。

      如果你的类似函数修改了一些状态实例/类,那么使用反射来测试结果类的属性值是否相等。

      如果您的类似函数修改了数据库,则制作数据库副本并在副本上运行每个函数并进行比较。

      但这可能一切都始于适当的单元测试。如果您知道所有可能的“用例”,那么当您发现所有这些“用例”的两个(或更多)函数的输出都相同时,您可以安全地保留一个函数并丢弃不必要的重复。

      另一种选择是获取代码/函数正在执行的实际需求。了解您的系统实际尝试完成的任务可以更轻松地重构旧代码或重复代码。


      检查逻辑重复的工具只会带您到您愿意工作的范围内。如果您说当前的工具没有考虑嵌套函数或调用其他函数的函数,那么为什么不重构代码以内联那些被调用的函数,以便您的工具可以工作呢?如果您甚至不想将方法 A(调用方法 B、C、D)重构为方法 AA,该方法内联 B、C、D 中的代码,那么您只是在寻找灵丹妙药。

      简短通过一些“工作”,您可以获得适合您的当前工​​具。您可能希望为开源工具做出贡献,以弥补您提到的失败。

      【讨论】:

      • 您的答案的主旨是假设函数是相同的。但是,我知道功能不同,正在寻找相似之处。
      • 当然,我可以重构代码,使工具能够轻松完成其所能做的事情。但是到那时我已经完成了大部分工作——这不就是找一个工具来做这件事的意义吗?
      • “有一些工作”?你真的这样做了吗?我完全认为你错了。
      • @Ira Baxter - 我是否已经重构了旧的/遗留的函数,这些函数是数千行 BOOLshit 外包代码,它们似乎都在执行类似的任务,但完全是迂回的方式?是的,是的,我有,虽然这有点费时,但一点也不难。成为一名程序员意味着能够在开发生命周期的任何时候介入。所以,为了保持主观毫无根据的意见(当然只是开玩笑),我完全认为你很懒。
      • @LastCoder:是的,我相信你已经手工完成了;这让你就像我们其他大多数人一样,以该计划为生。那是无关紧要的。讨论的是您是否可以构建工具来执行此操作。在你认为我很懒,或者在这方面没有构建工具的丰富经验之前,你可以查看我的简历。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多