Wie erkenne ich Codeduplikationen während der Entwicklung? [geschlossen]

78

Wir haben eine ziemlich große Codebasis, 400 KB LOC von C ++, und die Codeduplizierung ist ein Problem. Gibt es Tools, mit denen doppelte Codeblöcke effektiv erkannt werden können?

Im Idealfall können Entwickler dies während der Entwicklung verwenden, anstatt nur gelegentlich auszuführen, um festzustellen, wo die Probleme liegen. Es wäre auch schön, wenn wir ein solches Tool in CruiseControl integrieren könnten, um nach jedem Check-in einen Bericht zu erstellen.

Ich habe mir vor einiger Zeit Duploc angesehen . Es zeigte ein schönes Diagramm, erfordert jedoch eine Smalltalk-Umgebung, um es zu verwenden, was das automatische Ausführen ziemlich schwierig macht.

Kostenlose Tools wären nett, aber wenn es einige gute kommerzielle Tools gibt, würde mich das auch interessieren.

David Dibben
quelle
3
Wann immer jemand die Einfügetaste benutzt: -}
Ira Baxter

Antworten:

36

Simian erkennt doppelten Code in C ++ - Projekten.

Update: Funktioniert auch mit Java, C #, C, COBOL, Ruby, JSP, ASP, HTML, XML, Visual Basic, Groovy-Quellcode und sogar einfachen Textdateien

Simon Steele
quelle
würde simian nahtlos .mm Dateien überprüfen, AKA ObjectiveC ++
rraallvv
1
@rraallvv Simian kann Klartextprüfungen durchführen, um Codeduplikationen in jeder Sprache zu erkennen.
Catharz
2
Beachten Sie, dass es für die kommerzielle Nutzung nicht kostenlos ist.
Zitrax
Es scheint nicht rekursiv zu funktionieren, wenn ich es nur mit den Standardeinstellungen in einem Verzeichnis unter Linux ausführe.
ZeroPhase
20

Ich habe den Copy-and-Paste-Detector von PMD verwendet und ihn mithilfe des folgenden Wrapper-Skripts in CruiseControl integriert (stellen Sie sicher, dass sich das pmd-JAR im Klassenpfad befindet).

Unser Scheck läuft jede Nacht. Wenn Sie die Ausgabe darauf beschränken möchten, nur Dateien aus dem aktuellen Änderungssatz aufzulisten, benötigen Sie möglicherweise eine benutzerdefinierte Programmierung (Idee: Alle überprüfen und nur Duplikate auflisten, wenn eine der geänderten Dateien betroffen ist. Sie müssen alle Dateien überprüfen, da eine Änderung verwendet werden könnte Code aus einer unveränderten Datei). Sollte möglich sein, indem Sie die XML-Ausgabe verwenden und das Ergebnis analysieren. Vergiss nicht, das Skript zu posten, wenn es fertig ist;)

Für den Anfang sollte die "Text" -Ausgabe in Ordnung sein, aber Sie möchten die Ergebnisse auf benutzerfreundliche Weise anzeigen, für die ich ein Perl-Skript verwende, um HTML-Dateien aus der "xml" -Ausgabe von CPD zu generieren. Sie können auf diese zugreifen, indem Sie sie an den Kater senden, in dem sich der Bericht über Kreuzfahrtberichte befindet. Die Entwickler können sie von dort aus anzeigen und die Ergebnisse ihres schmutzigen Hackings sehen :)

Es läuft ziemlich schnell, weniger als 2 Sekunden mit 150 KLoc-Code (leere Zeilen und Kommentare, die in dieser Zahl nicht enthalten sind).

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>

user39039
quelle
Verwenden Sie unbedingt die neueste Version von der Sourgeforge-Seite! Die Dokumentationsseite schlägt eine Version aus dem Jahr 2011 vor, während die Entwicklung aktiv ist. In meinem Fall funktioniert Version 5.5 viel besser als die Version 4.2, die sie auf ihrer Homepage verlinken.
FourtyTwo
Auch in der Dokumentation wird die C ++ - Unterstützung nicht mehr erwähnt.
ZeroPhase
Der neueste Link zur doppelten Codepage von PMD lautet pmd.github.io/latest/pmd_userdocs_cpd.html#supported-languages
Laurent S
6

duplo scheint eine C-Implementierung des in Duploc verwendeten Algorithmus zu sein. Es ist einfach zu kompilieren und zu installieren, und obwohl die Optionen begrenzt sind, scheint es mehr oder weniger sofort zu funktionieren.

benno
quelle
Ich habe es gerade mit einer ziemlich alten Codedatei mit vielen Tonnen von fast Dupes versucht und mit einer aktuellen Codedatei mit wenigen perfekten Dupes verglichen. Die Legacy-Datei wurde als perfekt bewertet. Die neue Datei wurde als schlecht bewertet.
Sebastian Mach
5

Diese Debian-Pakete scheinen etwas in diese Richtung zu tun :

PS: Es sollte ein Debtags- Tag für alle Tools geben, die sich auf das Auffinden von [nahezu] Duplikaten beziehen. (Aber wie würde es heißen?)

SamB
quelle
Perfekte Antwort. Das Paket similarity-testerverfügt über eine umfassende Manpage man 1 sim, ist sofort einsatzbereit und liefert überzeugende Ergebnisse.
Joachim W
4

Schauen Sie sich das PMD-Projekt an .

Ich habe es nie benutzt, wollte es aber immer.

Andy Lester
quelle
Ich dachte, dass PMD nur für Java ist, aber ich sehe jetzt, dass CPD (das Teil von PMD ist) auch für C ++ verwendet werden kann.
David Dibben
2

Nun, Sie können jeden Abend einen Klondetektor auf Ihrer Quellcodebasis ausführen.

Viele Klondetektoren vergleichen Quellzeilen und können nur exakten doppelten Code finden.

CCFinder oben vergleicht Sprach-Token, sodass es nicht empfindlich auf Änderungen des Leerraums reagiert. Es kann Klone erkennen, die Varianten des ursprünglichen Codes sind, wenn sich nur einzelne Token ändern (z. B. eine Variable X in Y im Klon ändern).

Idealerweise möchten Sie das Obige, aber die Fähigkeit, Klone zu finden, bei denen die Variationen relativ willkürlich sein dürfen, z. B. eine Variable durch einen Ausdruck, eine Anweisung durch einen Block usw. zu ersetzen.

Unser CloneDR-Klondetektor erledigt dies für Java, C #, C ++, COBOL, VB.net, VB6, Fortran und eine Vielzahl anderer Sprachen. Es kann unter folgender Adresse eingesehen werden: http://www.semdesigns.com/Products/Clone/index.html

Die CloneDR-Engine kann nicht nur mehrere Sprachen verarbeiten, sondern auch eine Vielzahl von Eingabecodierungsstilen, darunter ASCII, ISO-8859-1, UTF8, UTF16, EBCDIC, eine Reihe von Microsoft-Codierungen und (japanische) Shift- JIS.

Die Site verfügt über mehrere Beispielberichte für Klonerkennungsläufe, darunter einen für C ++.

EDIT Feb 2014: Behandelt jetzt alle C ++ 14.

Ira Baxter
quelle
1

CCFinderX ist ein kostenloser (für den internen Gebrauch) geklonter Codedetektor, der mehrere Programmiersprachen (Java, C, C ++, COBOL, VB, C #) unterstützt.

bk1e
quelle
Danke für diesen Link. Ich werde es mir auf jeden Fall ansehen. Was noch besser ist, ist, dass es eine japanische Version gibt (alle anderen Entwickler im Projekt außer mir sind Japaner)
David Dibben
1

Das Auffinden "identischer" Codefragmente ist relativ einfach. Es gibt bereits Tools, die dies tun (siehe andere Antworten).

Manchmal ist es eine gute Sache, manchmal nicht; es kann die Entwicklungszeit verkürzen, wenn es auf einem zu feinen "Level" durchgeführt wird; Wenn Sie also versuchen, so viel Code umzugestalten, verlieren Sie Ihr Ziel (und verlieren wahrscheinlich Ihre Meilensteine ​​und Zeitpläne).

Was schwieriger ist, ist es, mehrere Funktionen / Methoden zu finden, die dasselbe tun, jedoch mit unterschiedlichen (aber ähnlichen) Eingaben und / oder Algorithmen ohne ordnungsgemäße Dokumentation.

Wenn Sie zwei oder verschiedene Methoden anwenden müssen, um dasselbe zu tun, und der Programmierer versucht, eine Instanz zu reparieren, aber vergisst (oder nicht weiß, dass sie existieren), um die anderen zu reparieren, erhöhen Sie das Risiko für Ihre Software.

Max
quelle
3
... und als eine praktische Sache, werden Sie in der Lage sein zu erkennen nicht , dass zwei Teile des Codes tun , die gleiche Sache , wenn sie anders umgesetzt werden. Da steht dir eine Turing-Maschine im Weg.
Ira Baxter
1
"Schwieriger ist es, mehrere Funktionen / Methoden zu finden, die dasselbe tun, jedoch unterschiedliche (aber ähnliche) Eingaben und / oder Algorithmen ohne ordnungsgemäße Dokumentation aufweisen." Recht. Und wenn sie dasselbe tun, sollten sie gleich benannt werden, da der Name beschreiben sollte, warum dieser Code überhaupt existiert. Schritt eins könnte also sein, sicherzustellen, dass alle Funktionen / Methoden korrekt benannt und dokumentiert sind. Wenn der Name wirklich beschreibt, was er tut, werden Ähnlichkeiten und Identitäten schnell offensichtlich.
MickeyfAgain_BeforeExitOfSO
Das Problem ist, dass selbst ein Orakel, das "das Gleiche tut" (von dem ich glaube, dass es wesentlich mächtiger ist als ein haltendes Orakel?), Ihnen nicht helfen würde, herauszufinden, ob zwei Namen dieselbe Idee ausdrücken (oder ausdrücken sollen). (Außerdem würde es dazu neigen, viele Fehlalarme zu geben.)
SamB
1

Same ( http://sourceforge.net/projects/same/ ) ist extrem einfach, funktioniert jedoch mit Textzeilen anstelle von Token. Dies ist nützlich, wenn Sie eine Sprache verwenden, die von keinem der schickeren Klone unterstützt wird Finder.

Sean McMillan
quelle
0

Es gibt auch Simian, das Java, C #, C ++, C, Objective-C, JavaScript ... unterstützt.

Es wird von Hudson (wie CPD) unterstützt.

Sofern Sie kein Open Source-Projekt sind, müssen Sie für Simian bezahlen .

Wernight
quelle
-3

TeamCity verfügt über eine leistungsstarke Code-Duplizierungs-Engine für .NET und Java, die mühelos als Teil Ihres Build-Systems ausgeführt werden kann.

ripper234
quelle
Weder .Net noch Java sind C ++. Die Ausführung ist zwar mühelos, aber auch erfolglos.
Tom