Як виявити дублювання коду під час розробки? [зачинено]


79

У нас досить велика база коду, 400 тис. LOC C ++, і дублювання коду є проблемою. Чи існують інструменти, які можуть ефективно виявляти дубльовані блоки коду?

В ідеалі це було б те, що розробники могли б використовувати під час розробки, а не просто періодично запускати, щоб побачити, де проблеми. Також було б непогано, якби ми могли інтегрувати такий інструмент із CruiseControl, щоб подавати звіт після кожної реєстрації.

Я дивився на Duploc деякий час тому, він показав гарний графік, але для його використання потрібне середовище smalltalk, що робить його автоматичний запуск досить складним.

Безкоштовні інструменти були б непоганими, але якщо є якісні комерційні інструменти, я б також зацікавився.


3
Кожного разу, коли хтось використовує кнопку вставлення: -}
Ira Baxter

Пов’язане запитання - stackoverflow.com/questions/2490884/…
Оновлено

Відповіді:


36

Simian виявляє повторюваний код у проектах на C ++.

Оновлення: Також працює з Java, C #, C, COBOL, Ruby, JSP, ASP, HTML, XML, Visual Basic, Groovy і з текстовими файлами


Симіан безперешкодно перевіряв би файли .mm, AKA ObjectiveC ++
rraallvv,

1
@rraallvv Simian може виконувати перевірку звичайного тексту, тому може виявляти дублювання коду будь-якою мовою.
Catharz

2
Зверніть увагу, що це не безкоштовно для комерційного використання.
Zitrax

Здається, це не працює рекурсивно, якщо я просто запускаю його із налаштуваннями за замовчуванням у каталозі в Linux.
ZeroPhase

20

Я використовував детектор копіювання та вставлення PMD та інтегрував його у CruiseControl, використовуючи наступний сценарій обгортки (обов’язково майте банку pmd у шляху до класу).

Наш чек працює щоночі. Якщо ви хочете обмежити вихідні дані лише переліком файлів із поточного набору змін, вам може знадобитися спеціальне програмування (ідея: перевірити всі та перерахувати лише дублікати, де задіяний один із змінених файлів. Вам доведеться перевірити всі файли, оскільки зміна може використовувати деякий код із незміненого файлу). Це має бути здійснено за допомогою виводу XML та аналізу результату. Не забудьте опублікувати цей сценарій, коли це буде зроблено;)

Для початку вихід "Тексту" повинен бути нормальним, але ви хочете відобразити результати зручним способом, для чого я використовую скрипт perl для створення HTML-файлів з "xml" виводу CPD. До них можна отримати доступ, розмістивши їх у tomcat, де знаходиться jsp, що звітує про круїз. Розробники можуть переглянути їх звідти та побачити результати їхнього брудного злому :)

Він працює досить швидко, менше 2 секунд на коді 150 KLoc (порожні рядки та коментарі не враховуються в цій кількості).

duplicatecheck.xml :

<project name="duplicatecheck" default="cpd">

<property name="files.dir" value="dir containing your sources"/>
<property name="output.dir" value="dir containing results for publishing"/>

<target name="cpd">
    <taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask"/>
    <cpd minimumTokenCount="100" 
         language="cpp" 
         outputFile="${output.dir}/duplicates.txt"
         ignoreLiterals="false"
         ignoreIdentifiers="false"
         format="text">
        <fileset dir="${files.dir}/">
            <include name="**/*.h"/>
            <include name="**/*.cpp"/>
                <!-- exclude third-party stuff -->
            <exclude name="boost/"/>
            <exclude name="cppunit/"/>
        </fileset>
    </cpd>
</target>


Обов’язково використовуйте останню версію зі сторінки sourgeforge! На їх сторінці документації пропонується версія з 2011 року, поки активна розробка. У моєму випадку версія 5.5 працює набагато краще, ніж версія 4.2, яку вони посилають на свою домашню сторінку.
FourtyTwo,

У їхній документації також більше не згадується про підтримку C ++.
ZeroPhase

Останнє посилання на повторювану кодову сторінку PMD
Лоран С,

6

duplo, здається, є реалізацією алгоритму, що використовується в Duploc. Це просто для компіляції та встановлення, і хоча параметри обмежені, здається, більш-менш працюють нестандартно.


Я просто спробував його на досить застарілому кодовому файлі з великою кількістю тонн майже дурнів і порівняв із недавнім файлом коду з декількома ідеальними дурнями. Спадковий файл оцінено як досконалий. Новий файл оцінено як поганий.
Себастьян Мах

5

Ці пакети Debian, здається, роблять щось подібне :

PS Повинен бути тег debtags для всіх інструментів, пов’язаних з пошуком [біля] дублювання. (Але як би це називатись?)


Ідеальна відповідь. Пакет similarity-testerмає вичерпну сторінку з інформацією man 1 sim, працює нестандартно і дає переконливі результати.
Joachim W

4

Подивіться на проект PMD .

Я ніколи цим не користувався, але завжди хотів.


Я думав, що PMD призначений лише для Java, але тепер я бачу, що CPD (який є частиною PMD) можна використовувати і для C ++.
Девід Діббен,

2

Що ж, ви можете запускати детектор клонів на базі вихідного коду щовечора.

Багато клонових детекторів працюють, порівнюючи вихідні рядки, і можуть знайти лише точний повторюваний код.

CCFinder, вище, працює, порівнюючи мовні лексеми, тому він не чутливий до пробілів. Він може виявляти клони, які є варіантами вихідного коду, якщо змінюються лише окремі маркери (наприклад, зміна змінної X на Y у клоні).

В ідеалі те, що ви хочете, - це вище, але можливість знаходити клони, де варіації можуть бути відносно довільними, наприклад, замінити змінну виразом, вираз блоком тощо.

Наш детектор клонів CloneDR робить це для Java, C #, C ++, COBOL, VB.net, VB6, Fortran та багатьох інших мов. Це можна побачити за адресою: http://www.semdesigns.com/Products/Clone/index.html

Окрім того, що здатний обробляти кілька мов, движок CloneDR здатний обробляти різноманітні стилі кодування введення, включаючи ASCII, ISO-8859-1, UTF8, UTF16, EBCDIC, ряд кодувань Microsoft та (японський) Shift- JIS.

На сайті є кілька прикладів звітів про запуск виявлення клонів, включаючи один для C ++.

EDIT лютого 2014: Тепер обробляє всі C ++ 14.


1

CCFinderX - це безкоштовний (для власного використання) клонований детектор коду, який підтримує кілька мов програмування (Java, C, C ++, COBOL, VB, C #).


Дякую за це посилання. Я обов’язково подивлюсь на це. Ще краще, що існує японська версія (усі інші розробники проекту, крім мене, - японці)
Девід Діббен,

1

Знайти "однакові" фрагменти коду відносно просто, існує вже існуючий інструмент, який це вже робить (див. Інші відповіді).

Іноді це добре, іноді ні; це може загрожувати часом розробки, якщо це зробити на занадто тонкому "рівні"; тобто намагаючись реструктурувати стільки коду, ви втрачаєте свою мету (і, можливо, розбиваєте свої етапи та графіки).

Складніше знайти декілька функцій / методів, які виконують одне і те ж, але з різними (але схожими) входами та / або алгоритмом без належної документації.

Якщо вам потрібно два або різні методи, щоб зробити одне і те ж, і програміст спробує виправити один екземпляр, але забуде (або не знає, що вони існують), щоб виправити інші, ви збільшите ризик для свого програмного забезпечення.


3
... і з практичної точки зору ви не зможете виявити, що дві частини коду виконують одне і те ж, якщо вони реалізовані по-різному. На вашому шляху стоїть машина Тьюрінга.
Айра Бакстер,

1
"Важче знайти кілька функцій / методів, які виконують одне і те ж, але з різними (але подібними) входами та / або алгоритмом без належної документації" Правильно. І якщо вони роблять те саме, їх слід НАЗВАТИ однаково, оскільки назва повинна описувати, чому цей код існує насамперед. Тож першим кроком може бути переконання, що всі функції / методи точно названі та задокументовані. Якщо назва справді описує те, що вона робить, схожість та ідентичність швидко стануть очевидними.
MickeyfAgain_BeforeExitOfSO

Проблема полягає в тому, що навіть оракул "робить те саме" (який, на мою думку, є значно потужнішим, ніж зупиняючий оракул?), Не допоможе вам зрозуміти, якщо два імена висловлюють (або призначені для вираження) одну і ту ж ідею. (Окрім цього, могло б бути багато помилкових спрацьовувань.)
SamB

1

Те саме ( http://sourceforge.net/projects/same/ ) надзвичайно просто, але воно працює на текстових рядках замість лексем, що корисно, якщо ви використовуєте мову, яка не підтримується одним із прихильників клону шукачі.


1

ConQAT - чудовий інструмент, який підтримує аналіз коду на C ++. Можна знайти копії, ігноруючи пробіли. Має надзвичайно зручний інтерфейс інтерфейсу користувача та консолі. Завдяки своїй гнучкості його непросто налаштувати. Я знайшов цю публікацію в блозі дуже корисною для налаштування проекту c ++ .


1

Ви можете використовувати наш інструмент SourceMeter для виявлення дублювання коду. Це інструмент командного рядка (дуже схожий на компілятори), тому ви можете легко інтегрувати його в інструменти безперервної інтеграції, такі як CruiseControl, про який ви згадали, або Jenkins .


0

Існує також Simian, який підтримує Java, C #, C ++, C, Objective-C, JavaScript ...

Це підтримується Хадсоном (як CPD).

Якщо ви не проект з відкритим кодом, ви повинні заплатити за Сіміана.


-3

TeamCity має потужний механізм дублювання коду для .NET та Java, який без особливих зусиль може працювати як частина вашої системи збірки.


Ні .Net, ні Java не є C ++, тому, хоча це не важко запустити, воно також безрезультатне.
Том
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.