Wie oft sind Sie schon auf Code wie diesen gestoßen?

In manchen Fällen stellt solcher Code kein großes Problem dar. Wenn Entwickler diese Vorgehensweise jedoch häufig verwenden, kann sie für ein Unternehmen teuer werden. Jeder neue Entwickler, der den Code debuggen oder eine neue Funktion hinzufügen muss, wird viel Zeit darauf verwenden, die bestehende Codebasis zu verstehen.
Wie können wir solche verschleierten Namen erkennen, damit wir sie anschließend refaktorieren können?
1. clang-query und AST Matchers verwenden
Clangs LibASTMatchers ist eine leistungsfähige Bibliothek, mit der sich Knoten im AST abgleichen und Code auf Grundlage der gefundenen Knoten ausführen lässt. In Kombination mit LibTooling, erleichtert LibASTMatchers die Entwicklung von Werkzeugen zur Code-zu-Code-Transformation oder zur Abfrage von Code.
Das clang-query Tool basiert auf LibASTMatchers und bietet eine einfache Möglichkeit, die AST-Knoten einer bestimmten Quelldatei abzufragen.
Wenn wir beispielsweise Funktionen erkennen möchten, deren Namen nur aus einem einzigen Zeichen bestehen, können wir folgenden AST Matcher ausführen:
functionDecl(matchesName("^[a-zA-Z]$"))AST Matchers bieten eine leistungsfähige Möglichkeit, eine Codebasis abzufragen. Hier ist eine kurze Definition aus der Dokumentation zu AST Matchers.
AST Matcher sind Prädikate für Knoten im AST. Matcher werden durch Aufrufe von Erzeugerfunktionen erstellt, mit denen sich ein Baum aus Matchern aufbauen lässt. Innere Matcher dienen dazu, die Übereinstimmung weiter einzugrenzen.
Um beispielsweise einen Matcher zu erstellen, der alle Klassen- oder Union-Deklarationen im AST einer Übersetzungseinheit findet, können Sie recordDecl(). Um die Suche weiter einzugrenzen und beispielsweise alle Klassen- oder Union-Deklarationen mit dem Namen „Foo“ zu finden, fügen Sie einen hasName Matcher ein. Der Aufruf recordDecl(hasName("Foo")) liefert einen Matcher, der Klassen oder Unions mit dem Namen „Foo“ in jedem Namespace findet. Standardmäßig verwenden Matcher, die mehrere innere Matcher akzeptieren, implizit allOf(). Dadurch lässt sich die Übereinstimmung weiter eingrenzen, beispielsweise auf alle Klassen, die von „Bar”: recordDecl(hasName("Foo"), isDerivedFrom("Bar")).
2. CppDepend und CQLinq verwenden
CppDepend enthält CQLinq, eine Abfragesprache für die Analyse Ihrer Codebasis.
CQLinq definiert mehrere vordefinierte Bereiche, die Sie abfragen können, darunter: Typen; Methoden; Felder; Namespaces; Projekte
Diese Bereiche erfassen nicht nur sämtliche Codeelemente der abgefragten Codebasis, sondern auch alle Drittanbieter- Codeelemente, die von der Codebasis verwendet werden (beispielsweise den Typ string sowie alle Methoden und Felder des Typs string die von der Codebasis verwendet werden).
Die Syntax ist denkbar einfach:
from m in Methoden where m.NbLinesOfCode > 30 select m
Um Funktionen zu erkennen, deren Namen nur aus einem Zeichen bestehen, können wir folgende CQLinq-Abfrage ausführen:

Fazit:
Unterschätzen Sie die Bedeutung von Symbolnamen nicht: Gute Namen machen eine Codebasis leichter verständlich und wartbar. Wenn Sie die Erkennung schlecht benannter Symbole in Ihrem Build-Prozess automatisieren, können Sie die Gesamtqualität Ihrer Codebasis verbessern.
