CK calcule les mesures de code au niveau de la classe et au niveau de la méthode dans les projets Java au moyen d'une analyse statique (c'est-à-dire pas besoin de code compilé). Actuellement, il contient un large ensemble de mesures, y compris le célèbre CK:
CBO (couplage entre objets) : compte le nombre de dépendances d'une classe. Les outils vérifient tout type utilisé dans toute la classe (Déclaration de champ, types de retour de méthode, déclarations variables, etc.). Il ignore les dépendances à Java elle-même (par exemple java.lang.string).
CBO modifié (couplage entre objets) : compte le nombre de dépendances d'une classe. Il est très similaire au CBO d'origine du CKTool. Cependant, cette métrique considère une dépendance d'une classe comme étant à la fois les références que le type fait aux autres et les références qu'elle reçoit d'autres types.
Fan-in : compte le nombre de dépendances d'entrée d'une classe, c'est-à-dire le nombre de classes qui font référence à une classe particulière. Par exemple, étant donné une classe X, le fan-in de X serait le nombre de classes qui appellent X en le faisant référence comme un attribut, accédant à certains de ses attributs, invoquant certaines de ses méthodes, etc.
Fan-out : compte le nombre de dépendances de sortie d'une classe, c'est-à-dire le nombre d'autres classes référencées par une classe particulière. En d'autres termes, étant donné une classe X, le fan-out de x est le nombre de classes appelées par x via la référence des attributs, les invocations de la méthode, les instances d'objet, etc.
DIT (Tree d'héritage en profondeur) : il compte le nombre de "pères" qu'une classe a. Toutes les classes ont au moins 1 (tout le monde hérite de java.lang.object). Pour y arriver, les classes doivent exister dans le projet (c'est-à-dire que si une classe dépend de X qui s'appuie dans un fichier de pot / dépendance, et X dépend d'autres classes, le DIT est compté comme 2).
NOC (nombre d'enfants) : il compte le nombre de sous-classes immédiates d'une classe particulière.
Nombre de champs : compte le nombre de champs. Nombres spécifiques pour le nombre total de champs, statiques, publics, privés, protégés, par défaut, finaux et synchronisés.
Nombre de méthodes : compte le nombre de méthodes. Nombres spécifiques pour le nombre total de méthodes, statiques, publiques, abstraites, privées, protégées, par défaut, finales et synchronisées. Les méthodes du constructeur comptent également ici.
Nombre de méthodes visibles : compte le nombre de méthodes visibles. Une méthode est visible si elle n'est pas privée.
NOSI (nombre d'invocations statiques) : compte le nombre d'invocations aux méthodes statiques. Il ne peut compter que ceux qui peuvent être résolus par le JDT.
RFC (réponse pour une classe) : compte le nombre d'invocations de méthode uniques dans une classe. Comme les invocations sont résolues via une analyse statique, cette implémentation échoue lorsqu'une méthode a des surcharges avec le même nombre de paramètres, mais différents types.
WMC (classe de méthode de poids) ou complexité de McCabe . Il compte le nombre d'instructions de branche dans une classe.
Loc (lignes de code) : il compte les lignes de décompte, ignorant les lignes et les commentaires vides (c'est-à-dire, ses lignes de code source ou Sloc). Le nombre de lignes ici peut être un peu différent du fichier d'origine, car nous utilisons la représentation interne de JDT du code source pour le calculer.
LCOM (manque de cohésion des méthodes) : calcule la métrique LCOM. Il s'agit de la toute première version de Metric, qui n'est pas fiable. LCOM-HS peut être meilleur (j'espère que vous nous enverrez une demande de traction).
LCOM * (manque de cohésion des méthodes) : Cette métrique est une version modifiée de la version actuelle de LCOM implémentée dans CK Tool. LCOM * est une métrique normalisée qui calcule le manque de cohésion de la classe dans une plage de 0 à 1. Ensuite, plus, plus la valeur de LCOM * dans une classe, moins le degré de cohésion de cette classe respective. Plus la valeur de LCOM * dans une classe, la plus la cohésion de cette classe respective. Cette implémentation suit la troisième version de LCOM * définie dans [1].
TCC (cohésion de classe serrée) : mesure la cohésion d'une classe avec une plage de valeur de 0 à 1. TCC mesure la cohésion d'une classe via des connexions directes entre les méthodes visibles, deux méthodes ou leurs arbres d'invocation accèdent à la même variable de classe.
LCC (cohésion de classe lâche) : similaire au TCC, mais il comprend en outre le nombre de connexions indirectes entre les classes visibles pour le calcul de cohésion. Ainsi, la contrainte LCC> = TCC détient toujours.
Quantité de rendements : le nombre d'instructions return .
Quantité de boucles : le nombre de boucles (c'est-à-dire, pour, tandis que, améliorez-vous).
Quantité de comparaisons : le nombre de comparaisons (c'est-à-dire, == et! =). Remarque :! = est disponible uniquement en 0.4.2+.
Quantité d'essai / captures : le nombre d'essais / captures
Quantité d'expressions entre parenthèses : le nombre d'expressions à l'intérieur des parenthèses.
Literales de cordes : le nombre de littéraux de cordes (par exemple, "John Doe" ). Les cordes répétées comptent autant de fois qu'elles apparaissent.
Quantité de nombre : le nombre de nombres (c'est-à-dire, int, long, double, flottant) littéraux.
Quantité d'opérations mathématiques : le nombre d'opérations mathématiques (temps, diviser, reste, plus, moins, merde gauche, changement de droite).
Quantité de variables : nombre de variables déclarées.
Blocs imbriqués max : le plus grand nombre de blocs imbriqués ensemble.
Quantité de classes anonymes, de classes intérieures et d'expressions de lambda : le nom dit tout. Notez que chaque fois qu'une classe anonyme ou une classe intérieure est déclarée, elle devient une "nouvelle classe entière", par exemple, CK génère AB et AB $ C, C étant une classe intérieure à l'intérieur d'AB cependant, les expressions de lambda ne sont pas considérées comme des classes, et donc, font partie de la classe / méthode dans laquelle ils sont intégrés. A class or a method only has the number of inner classes that are declared at its level, eg, an inner class that is declared inside a method M2, that is inside an anonymous class A, that is declared inside a method M, that finally is declared inside a class C, will not count in class C, but only in method M2 (first-level method it is embodied), and anonymous class A (first-level class it is embodied).
Nombre de mots uniques : Nombre de mots uniques dans le code source. Au niveau de la méthode, il utilise uniquement le corps de la méthode comme entrée. Au niveau de la classe, il utilise tout le corps de la classe comme mesures. L'algorithme compte essentiellement le nombre de mots dans une méthode / classe, après avoir supprimé les mots clés Java. Les noms sont divisés en fonction du cas de chameau et de la soulignement (par exemple, LongName_Likethis devient quatre mots). Voir la classe WordCounter pour plus de détails sur l'implémentation.
Nombre d'instructions de journal : Nombre d'instructions de journal dans le code source. Le comptage utilise Regex compatible avec les appels API SLF4J et log4j. Voir NumberOfLogStatements.java et les exemples de test ( NumberOfLogStatementsTest et fixtures/logs ) pour plus d'informations.
A Javadoc : Boolean indiquant si une méthode a Javadoc. (Seulement au niveau de la méthode pour l'instant)
Modificateurs : modificateurs publics / abstraits / privés / protégées / natifs des classes / méthodes. Peut être décodé à l'aide d' org.eclipse.jdt.core.dom.Modifier .
Utilisation de chaque variable : à quelle fréquence chaque variable a été utilisée à l'intérieur de chaque méthode.
Utilisation de chaque champ : À quelle fréquence chaque champ local a été utilisé à l'intérieur de chaque méthode, le champ local est des champs dans une classe (les sous-classes ne sont pas incluses). Des usages de champs locaux indirects sont également détectés, les usages de champs locaux indirects incluent tous les usages des champs dans l'arbre d'invocation local d'une classe, par exemple, les invoquer B et B utilisent le champ A, alors a est indirectement utilisé par A.
Invocations de méthode : toutes les méthodes directement invoquées, les variations sont des invocations locales et des invocations locales indirectes.
Remarque: CK sépare les classes, les classes intérieures et les classes anonymes. LOC est la seule métrique qui n'est pas complètement isolée des autres, par exemple, si A a une déclaration d'une classe intérieure B, alors loc (a) = loc (classe A) + LOC (classe b).
CK est un outil de collecte de métriques de code Java, rationalisé dans une structure simple qui tourne autour de trois packages principaux:
Pour Brevity, dans cette documentation, les préfixes de package tels que com.github.mauricioaniche.ck sont omis.
CK gère l'orchestration de l'ensemble du processus de collecte de métriques. Il initialise les chercheurs métriques, gère le partitionnement de fichiers en fonction de la mémoire disponible, configure les analyseurs AST avec des paramètres d'environnement appropriés et gère le flux d'exécution entre différents répertoires et dépendances en pot. Il ajuste dynamiquement son comportement en fonction des entrées utilisateur comme useJars , maxAtOnce et variablesAndFields pour optimiser le traitement des fichiers Java pour la collecte de métriques.ck . Cette classe traite des arguments en ligne de commande pour configurer et lancer le processus de collecte de métriques. Il gère la saisie de l'utilisateur pour le chemin du projet, l'inclusion de JAR, le partitionnement de fichiers, les détails des métriques et la configuration du répertoire de sortie. Runner orchestre l'exécution globale en initialisant et en utilisant la classe CK et en gérant la sortie des résultats via ResultWriter .FileASTRequestor , un composant du noyau Eclipse JDT (Java Development Tools). Il joue un rôle central dans le cadre CK en orchestrant le processus de collecte de métriques. La MetricsExecutor coordonne la création de l'arborescence de syntaxe abstraite (AST) pour les fichiers source Java, qui est essentiel pour analyser et extraire les métriques de code. Metricsfinder: cette classe d'utilité, située dans ck.utils , joue un rôle crucial dans l'identification dynamique et l'instanciation des classes de collection de métriques dans le cadre CK. Il cible des classes qui implémentent les interfaces ClassLevelMetric et MethodLevelMetric à partir du package metrics .
Le MetricsFinder utilise la bibliothèque Reflections pour scanner et charger les classes de collecteur de métriques à l'exécution, ce qui permet au système CK d'être extensible et adaptable à de nouvelles métriques sans nécessiter de modifications à l'architecture de base. Cette fonctionnalité est particulièrement utile pour intégrer les mesures personnalisées dans le processus d'analyse de manière transparente.
CKVisitor: composant intégral du framework CK, CKVisitor étend la classe ASTVisitor fournie par la bibliothèque Eclipse JDT (Java Development Tools), permettant une analyse détaillée et une collection métrique directement à partir de l'arborescence de syntaxe abstraite du code source Java (AST).
Le visiteur est conçu pour traverser divers nœuds de l'AST, tels que les types et les méthodes, et appliquer des actions spécifiques à chaque nœud. Il gère efficacement une hiérarchie basée sur la pile de classes et de méthodes, permettant de calculer et de collecter des mesures dans le contexte de la portée du nœud actuel.
CKastVisitor: implémenté par des classes métriques dans ck.metrics , permettant à chaque métrique de gérer des nœuds AST spécifiques d'intérêt, tels que les invocations de méthode et les créations d'instance de classe.
ClassLevelMetric et MethodLevelMetric: Interfaces Définition des méthodes pour collecter les métriques au niveau de la classe et au niveau de la méthode, respectivement.
CKNotifier .CKClassResult et CKMethodResult avec les données collectées.CK Framework intègre un certain nombre de modèles de conception bien établis pour améliorer la modularité, l'extensibilité et la maintenabilité de sa base de code. Ces modèles permettent au cadre de gérer efficacement les opérations complexes telles que la traversée des arbres de syntaxe abstraites (AST), la collecte de mesures et la notification des résultats. Vous trouverez ci-dessous les modèles de conception clés utilisés:
Modèle des visiteurs: les interfaces CKVisitor et CKASTVisitor implémentent le modèle de visiteur, qui est essentiel dans la gestion des opérations sur divers nœuds AST sans modifier les classes des éléments sur lesquels il fonctionne. Ce modèle est particulièrement bénéfique dans les scénarios où un composant doit effectuer des opérations distinctes et sans rapport sur une hiérarchie de classe de nœuds AST. Il simplifie le code en externalisant la logique opérationnelle dans les objets du visiteur, facilitant l'ajout facile de nouvelles opérations sans modifier les classes de nœuds existantes. Cette séparation des préoccupations conduit à une base de code plus maintenable et plus extensible, où les structures et les opérations des nœuds AST sont découplés.
Modèle de notificateur: CK adopte le modèle de notificateur grâce à l'utilisation de CKNotifier , qui agit comme un mécanisme central pour diffuser les résultats de la collection de métriques à tous les observateurs enregistrés. Ce modèle est crucial pour créer une architecture à couplage vaguement où le sujet (Metric Computation Process) est indépendant de ses observateurs (processeurs de résultats ou générateurs de rapports). Cela permet à CK de notifier plusieurs composants de l'achèvement des calculs métriques sans couplage à des composants spécifiques, ce qui améliore la flexibilité et l'évolutivité du système.
Modèle d'usine: l'instanciation des collectionneurs métriques est gérée par MetricsFinder , qui incarne le modèle d'usine. Ce modèle est utilisé pour encapsuler la logique des classes de collection de métriques spécifiques en fonction des décisions d'exécution. Le modèle d'usine simplifie le processus d'ajout de nouveaux types de collectionneurs métriques sans perturber le code existant, fournissant une architecture plug-and-play où de nouvelles métriques peuvent être introduites de manière transparente. Il aide également à maintenir la séparation des préoccupations, car le processus de création d'objets métriques est isolé de la logique centrale de la collecte métrique.
En tirant parti de ces modèles de conception, CK gère efficacement la complexité et garantit que le cadre reste robuste, adaptable et facile à étendre à mesure que de nouvelles exigences et de types métriques émergent.
Vous avez besoin d'au moins Java 8 pour pouvoir compiler et exécuter cet outil.
Pour utiliser la dernière version (que vous devriez), clonez le projet et générez un pot. Un simple mvn clean compile package génère le fichier JAR unique pour vous (voir votre dossier cible ).
Ensuite, il suffit de courir:
java -jar ck-x.x.x-SNAPSHOT-jar-with-dependencies.jar
<project dir>
<use jars:true|false>
<max files per partition:0=automatic selection>
<variables and fields metrics?:true|false>
<output dir>
[ignored directories...]
Project dir fait référence au répertoire où CK peut trouver tout le code source à analyser. CK recherchera récursivement les fichiers .java. CK peut utiliser les dépendances du projet pour améliorer sa précision. Les paramètres use jars indiquent à CK de rechercher des fichiers .jar dans le répertoire et de les utiliser pour mieux résoudre les types. Max files per partition indiquent à JDT la taille du lot à traiter. Laissez-nous décider pour vous et commencer par 0; Si des problèmes se produisent (c'est-à-dire hors de la mémoire), vous pensez à le régler. Variables and field metrics indiquent que vous voulez également des métriques au niveau des variables et des champs. Ils sont très fins et produisent beaucoup de production; Vous devez le sauter si vous n'avez besoin que de mesures au niveau de la classe ou de la méthode. Enfin, output dir se réfère au répertoire où CK exportera le fichier CSV avec des mesures du projet analysé. Facultativement, vous pouvez spécifier n'importe quel nombre répertoires ignorés, séparés par des espaces (par exemple, build/ ). Par défaut, .git et tous les autres dossiers cachés sont ignorés.
L'outil générera trois fichiers CSV: classe, méthode et niveaux variables.
Apprenez par l'exemple. Voir Classe Runner.java .
Voir la version la plus récente de la bibliothèque dans le badge au début de cette lecture, ou sur https://mvnrepository.com/artifact/com.github.mauricioaniche/ck.
Utilisez l'extrait suivant dans votre pom.xml. Mettez à jour XYZ avec la version la plus récente de l'outil (vérifiez mvnRepository.com ou l'insigne au début de ce fichier ReadMe):
<!-- https://mvnrepository.com/artifact/com.github.mauricioaniche/ck -->
<dependency>
<groupId>com.github.mauricioaniche</groupId>
<artifactId>ck</artifactId>
<version>X.Y.Z</version>
</dependency>
Vous pouvez également utiliser le plugin CK Maven, développé par @JazzMuesli, qui exécute automatiquement CK dans votre projet. Très utile aux développeurs: https://github.com/jazzmuesli/ck-mvn-plugin.
Cet outil utilise la bibliothèque JDT Core d'Eclipse sous le capot pour AST Construction. Actuellement, la version de conformité est définie sur Java 11.
Besoin de prise en charge d'une version linguistique plus récente? Le processus de l'ajout est très simple, en considérant la contribution d'un RP:
pom.xml . Vous pouvez utiliser un navigateur de référentiel comme le référentiel MVN pour faciliter ce processus.pom.xml , mettez à jour les propriétés source et target du plugin de compilateur Maven en conséquence.CK.java : [...]
ASTParser parser = ASTParser.newParser(AST.JLS11);
[...]
JavaCore.setComplianceOptions(JavaCore.VERSION_11, options);
[...]
Parce que l'outil est né pour calculer simplement le CK ClassLevelMetrics, mais il a augmenté au-delà de mes attentes ... La vie est drôle!
S'il vous plaît, utilisez l'entrée Bibtex suivante:
@manual{aniche-ck,
title={Java code metrics calculator (CK)},
author={Maurício Aniche},
year={2015},
note={Available in https://github.com/mauricioaniche/ck/}
}
Soumettez simplement un PR! :)
Ce logiciel est concédé sous licence Apache 2.0.