【问题标题】:Detecting code duplicate between files and making semiautomatic refactoring检测文件之间的代码重复并进行半自动重构
【发布时间】:2015-11-08 11:16:09
【问题描述】:

解决方案是由框架、工具还是其他任何东西表示都没有关系。这个问题很难解决,多年来我一直在与它作斗争。

我将举一个例子来更好地说明我在说什么。

文件1

<head>
<title>Fotografia Elenco Completo Filtri Professionali</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<META name="Language" content="it">
<META http-equiv="Revisit-After" content="2 days">
<style>
<!--
 table.MsoNormalTable
    {mso-style-parent:"";
    font-size:10.0pt;
    font-family:"Times New Roman"}
-->
</style>
</head>

文件2

<head>
<title>Militari</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="keywords" content="militari, ....">
<meta name="robots" content="INDEX, FOLLOW">
<meta name="Language" content="it">
<meta http-equiv="Revisit-After" content="2 days">
<meta name="Rating" content="General">
<link rel="stylesheet" type="text/css" href="./file/stile.css">
<script language="JavaScript">

文件 3

<head>
<title>Cinema - Recensioni e Trame di Film</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="keywords" content="recensioni film">
<meta name="description" content="Ottimo sito di recensioni di film, trame di film cinematografice, di Videogame e Romanzi. ">
<meta name="robots" content="INDEX, FOLLOW">
<meta name="Language" content="it">
<meta http-equiv="Revisit-After" content="2 days">
<meta name="Rating" content="General">
<link rel="stylesheet" type="text/css" href="file/stile.css">
<style type="text/css">
body {
    background-color:#F0F0F0;
    text-align: center;
}
</style>

对于人类来说,避免这种代码重复的任务是显而易见的。他能认出“”、“”是定界符。行的顺序无关紧要,哪些部分可以放入变量中(或作为值存储在数据库中)以及哪些文件足够相似可以重构。

整个过程似乎没有那么难自动化。但是..直到现在我找不到任何解决方案。甚至自动识别分隔符也很困难..

我发现最好的方法是玩正则表达式工具并变得疯狂:D


重构后

文件1

header -> PrintHeader();

文件2

header -> PrintHeader();

文件3

header -> PrintHeader();

全局文件

class header
{
 function PrintHeader
 {
  SELECT title, content-type, language, revisit-after, rating, robots, extra_text_unparsed
  into myArray
  FROM header_table
  WHERE filename = $filename

 foreach(v in myArray)
 {
  echo ....
 }
 }
}

有什么建议吗?

【问题讨论】:

  • 对于这个人来说,很难理解你的意思。您能否提供一个如何重构这三个文件的示例?
  • @venerik:已编辑。这并不容易。如果您愿意,我将使用 powergrep 发布最终解决方案,但它不是最聪明的工具...

标签: c# php regex code-duplication


【解决方案1】:

您需要的是克隆检测器。

https://en.wikipedia.org/wiki/Duplicate_code。那里有一个克隆检测器列表。

关键问题是:

  • 克隆检测器支持什么语言?
  • 它如何检测克隆?
  • 如何删除此类克隆?
  • 该工具是否提供删除克隆的自动化功能?

纯“字符串克隆检测”可以独立于语言,但通常 找不到可移动克隆,因为它们不了解代码片段之间的边界。

我构建AST-based clone detectors。它们根据目标语言的结构检测克隆,如 AST 所示。克隆 以这种方式检测到的语言边界比其他检测器更自然。一个缺点:这些必然是依赖于语言的。您需要为每种语言使用不同的检测器。回报是您可以在大量代码中检测到高质量的克隆。

自动删除个克隆很难;每种语言都提供了自己的抽象代码方法(例如,创建子例程、宏、包含文件……),并且工具必须了解它们中的每一个。您发明了一种 HTML 抽象,它超出了 HTML 可以编码的范围(将片段放入数据库:不在 HMTL 的词汇表中)。

实际上,基本上没有自动克隆删除器。您要做的几乎就是识别克隆(这就是克隆检测器很好的原因),然后手动删除它们,尤其是要获得像您展示的那样的自定义效果。

如果你想实现一个自动克隆删除工具,你需要 相当于program transformation system。 (参见我的简历,恰好也支持克隆检测)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多