From 27a74af0cc2b6d3a3ab54c80069591b0bcc55675 Mon Sep 17 00:00:00 2001 From: Jim Bethancourt Date: Sat, 5 Sep 2026 13:25:05 -0500 Subject: [PATCH 1/4] Fixing JavaDocs --- .../hjug/graphbuilder/CodebaseGraphDTO.java | 27 +++++++++++ .../graphbuilder/CompositeGraphBuilder.java | 9 ++++ .../graphbuilder/DependencyCollector.java | 6 +++ .../KotlinSourceFileGraphBuilder.java | 2 +- .../graphbuilder/metrics/ClassMetrics.java | 2 + .../metrics/ComplexityCalculator.java | 15 +++++++ .../metrics/DisharmonyDetector.java | 15 +++++++ .../metrics/GraphMetricsCollector.java | 6 +++ .../visitor/AbstractDependencyVisitor.java | 11 +++++ .../visitor/BaseTypeProcessor.java | 37 +++++++++++++++ .../visitor/DependencyVisitorLogic.java | 45 +++++++++++++++++++ .../visitor/DependencyVisitorState.java | 7 +++ 12 files changed, 181 insertions(+), 1 deletion(-) diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CodebaseGraphDTO.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CodebaseGraphDTO.java index 9455ccb2..c236d464 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CodebaseGraphDTO.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CodebaseGraphDTO.java @@ -12,6 +12,11 @@ import org.jgrapht.Graph; import org.jgrapht.graph.DefaultWeightedEdge; +/** + * Data transfer object containing the complete codebase graph analysis results. + * Includes class and package reference graphs, class-to-package relationships, + * source file mappings, and detected disharmonies (antipatterns). + */ @Getter @EqualsAndHashCode @ToString @@ -26,6 +31,16 @@ public class CodebaseGraphDTO { private final List classDisharmonies; private final List methodDisharmonies; + /** + * Creates a new CodebaseGraphDTO. + * + * @param classReferencesGraph the class reference graph + * @param packageReferencesGraph the package reference graph + * @param classRelationshipsInPackageRelationship the class-to-package relationships + * @param classToSourceFilePathMapping the class to source file path mapping + * @param classDisharmonies the list of class disharmonies + * @param methodDisharmonies the list of method disharmonies + */ public CodebaseGraphDTO( Graph classReferencesGraph, Graph packageReferencesGraph, @@ -41,12 +56,24 @@ public CodebaseGraphDTO( this.methodDisharmonies = methodDisharmonies; } + /** + * Returns class disharmonies filtered by type. + * + * @param disharmonyType the disharmony type to filter by + * @return list of matching class disharmonies + */ public List getClassDisharmoniesOfType(String disharmonyType) { return classDisharmonies.stream() .filter(d -> disharmonyType.equals(d.getDisharmonyType())) .collect(Collectors.toList()); } + /** + * Returns method disharmonies filtered by type. + * + * @param disharmonyType the disharmony type to filter by + * @return list of matching method disharmonies + */ public List getMethodDisharmoniesOfType(String disharmonyType) { return methodDisharmonies.stream() .filter(d -> disharmonyType.equals(d.getDisharmonyType())) diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java index 92f414a2..206d004f 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java @@ -49,6 +49,15 @@ public CodebaseGraphDTO getCodebaseGraphDTO(String repositoryPath, boolean exclu return getCodebaseGraphDTO(repositoryPath, config); } + /** + * Build a unified {@link CodebaseGraphDTO} from a directory that may contain + * both Java and Kotlin source files. + * + * @param repositoryPath path to the source directory + * @param config graph-builder configuration + * @return a merged CodebaseGraphDTO + * @throws IOException if parsing fails + */ public CodebaseGraphDTO getCodebaseGraphDTO(String repositoryPath, GraphBuilderConfig config) throws IOException { String repositoryRoot = config.getRepositoryRoot() != null ? config.getRepositoryRoot() : ""; return getCodebaseGraphDTO(repositoryPath, repositoryRoot, config); diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java index b755eb84..c5c55736 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java @@ -2,6 +2,11 @@ import org.jgrapht.graph.DefaultWeightedEdge; +/** + * Interface for collecting dependencies between classes and packages during + * source file analysis. Implementations build the class and package reference + * graphs used by the graph builder. + */ // TODO: Revisit - I don't think this is really needed public interface DependencyCollector { @@ -18,6 +23,7 @@ public interface DependencyCollector { * * @param fromPackageName The package that depends on another * @param toPackageName The package being depended upon + * @return the edge representing the package dependency */ DefaultWeightedEdge addPackageDependency(String fromPackageName, String toPackageName); diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/KotlinSourceFileGraphBuilder.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/KotlinSourceFileGraphBuilder.java index ffa6a2af..ee3826ae 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/KotlinSourceFileGraphBuilder.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/graphbuilder/KotlinSourceFileGraphBuilder.java @@ -27,7 +27,7 @@ /** * Kotlin-language source-file graph builder. Invoked unconditionally by - * {@link CompositeGraphBuilder} (Kotlin analysis is always on). This + * {@link org.hjug.graphbuilder.CompositeGraphBuilder} (Kotlin analysis is always on). This * module declares a compile dependency on * {@code org.openrewrite:rewrite-kotlin}, so the Kotlin parser is always * on the classpath of any consumer of this builder. diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ClassMetrics.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ClassMetrics.java index aae6044e..94be61d5 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ClassMetrics.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ClassMetrics.java @@ -371,6 +371,8 @@ public void addMethod(MethodMetrics methodMetrics) { * ({@code Klass::method}) across all declared methods. Returns the sum * of {@link MethodMetrics#getNumberOfCallableReferences()} across every * method on this class. + * + * @return the total number of callable references */ public int getNumberOfCallableReferences() { return methods.values().stream() diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java index 57e179a6..ad8d787e 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java @@ -4,16 +4,31 @@ import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.tree.J; +/** + * Calculates cyclomatic complexity and maximum nesting depth for a method + * by visiting its AST nodes. Extends {@link JavaIsoVisitor} to traverse + * the OpenRewrite Java AST. + */ public class ComplexityCalculator extends JavaIsoVisitor { private int cyclomaticComplexity = 1; private int nestingLevel = 0; private int maxNestingDepth = 0; + /** + * Returns the calculated cyclomatic complexity. + * + * @return the cyclomatic complexity + */ public int getCyclomaticComplexity() { return cyclomaticComplexity; } + /** + * Returns the calculated maximum nesting depth. + * + * @return the maximum nesting depth + */ public int getMaxNestingDepth() { return maxNestingDepth; } diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java index dbe1520a..40ee51f5 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java @@ -4,6 +4,18 @@ import lombok.Data; import org.hjug.graphbuilder.metrics.DisharmonyMetric.Direction; +/** + * Detects disharmonies (code smells / antipatterns) in the collected class and + * method metrics. Based on the HIDOOP / DECOR / Lanza-Marinescu catalog. + * + *

This class is a pure function of the {@link ClassMetrics} and {@link + * MethodMetrics} populations produced by {@link GraphMetricsCollector}. It has + * no side effects and no external dependencies. + * + *

Threshold constants (FEW, HALF, ONE_THIRD, etc.) are defined at the top + * of the class and tuned to the literature values cited in the Lanza-Marinescu + * book. They can be adjusted for specific codebase characteristics if needed. + */ public class DisharmonyDetector { // Linguistic quantifiers (Lanza & Marinescu, Table 2.4) @@ -373,6 +385,9 @@ public boolean isBrainMethod(MethodMetrics metrics) { /** * Feature Envy (Fig. 5.4): method accesses more foreign data than local data. * ATFD > FEW AND LAA < ONE_THIRD AND FDP <= FEW + * + * @param metrics the method metrics to check + * @return if the method method has feature envy */ public boolean hasFeatureEnvy(MethodMetrics metrics) { return metrics.getAccessToForeignData() > FEW diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java index 596eb0a5..82b53648 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java @@ -204,6 +204,9 @@ public boolean hasKotlinMetrics() { * {@link #getOrCreateClassMetrics(String)} from visitor logic that * intends to mutate the returned instance and have the mutation * reflected by {@link #getAllClassMetrics()}. + * + * @param className the class name + * @return the class metrics, or {@code null} if not found */ public ClassMetrics getClassMetrics(String className) { return classMetrics.get(className); @@ -329,6 +332,9 @@ private int computeSealedDepth(ClassMetrics metrics) { * {@link #getAllClassMetrics()}. Any get-or-create path that builds an * instance without storing it would silently discard every class's * metrics. + * + * @param className the class name + * @return the class metrics (existing or newly created) */ public ClassMetrics getOrCreateClassMetrics(String className) { return classMetrics.computeIfAbsent(className, ClassMetrics::new); diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java index 0c599724..28cea868 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java @@ -30,6 +30,13 @@ public abstract class AbstractDependencyVisitor

extends JavaIsoVisitor

{ @Getter private final DependencyVisitorState state; + /** + * Creates a new AbstractDependencyVisitor. + * + * @param repositoryPath path to the source directory + * @param repositoryRoot path to the repository root + * @param dependencyCollector the dependency collector to use + */ protected AbstractDependencyVisitor( String repositoryPath, String repositoryRoot, DependencyCollector dependencyCollector) { BaseTypeProcessor typeProcessor = new BaseTypeProcessor() { @@ -61,6 +68,8 @@ public Javadoc visitDocComment(Javadoc.DocComment docComment, P p) { * Source-file extension used when synthetic source paths are produced for junit-based * tests (where the parser's URI is not usable as a repo path). Java returns {@code ".java"}, * Kotlin returns {@code ".kt"}. + * + * @return the source file extension */ protected String sourceFileExtension() { return ".java"; @@ -191,6 +200,8 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, P /** * Returns the class-to-source-file-path mapping collected during the visit. * Delegates to the internal state. + * + * @return the class-to-source-file-path mapping */ public Map getClassToSourceFilePathMapping() { return state.getClassToSourceFilePathMapping(); diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java index b33c7bed..497b1369 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java @@ -9,13 +9,29 @@ import org.openrewrite.java.tree.JavaType; import org.openrewrite.java.tree.TypeTree; +/** + * Base type processor that provides common type-processing logic for + * dependency extraction. Subclasses implement {@link #getDependencyCollector()} + * to provide the dependency collector instance. + */ @Slf4j public abstract class BaseTypeProcessor { private final TypeDependencyExtractor typeDependencyExtractor = new TypeDependencyExtractor(); + /** + * Returns the dependency collector to use for recording class dependencies. + * + * @return the dependency collector + */ protected abstract DependencyCollector getDependencyCollector(); + /** + * Processes a Java type and extracts class dependencies. + * + * @param ownerFqn the fully qualified name of the type owner + * @param javaType the Java type to process + */ protected void processType(String ownerFqn, JavaType javaType) { if (javaType == null || javaType instanceof JavaType.Unknown) { return; @@ -26,6 +42,13 @@ protected void processType(String ownerFqn, JavaType javaType) { } } + /** + * Processes an annotation and extracts class dependencies. + * + * @param ownerFqn the fully qualified name of the type owner + * @param annotation the annotation to process + * @param cursor the cursor for context + */ protected void processAnnotation(String ownerFqn, J.Annotation annotation, Cursor cursor) { if (annotation.getType() instanceof JavaType.Unknown) { return; @@ -45,6 +68,14 @@ protected void processAnnotation(String ownerFqn, J.Annotation annotation, Curso } } + /** + * Processes a type parameter and extracts class dependencies from its bounds + * and annotations. + * + * @param ownerFqn the fully qualified name of the type owner + * @param typeParameter the type parameter to process + * @param cursor the cursor for context + */ protected void processTypeParameter(String ownerFqn, J.TypeParameter typeParameter, Cursor cursor) { if (null != typeParameter.getBounds()) { for (TypeTree bound : typeParameter.getBounds()) { @@ -59,6 +90,12 @@ protected void processTypeParameter(String ownerFqn, J.TypeParameter typeParamet } } + /** + * Processes all annotations at the given cursor position. + * + * @param ownerFqn the fully qualified name of the type owner + * @param cursor the cursor for context + */ protected void processAnnotations(String ownerFqn, Cursor cursor) { AnnotationService annotationService = new AnnotationService(); for (J.Annotation annotation : annotationService.getAllAnnotations(cursor)) { diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java index 84cb96ee..957f4d52 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java @@ -32,6 +32,10 @@ private DependencyVisitorLogic() {} /** * Called on entering a compilation unit. Records the package name and source path. + * + * @param state the visitor state + * @param packageName the package name + * @param sourcePath the source path */ public static void enterCompilationUnit(DependencyVisitorState state, String packageName, String sourcePath) { state.setOwningPackageName(packageName); @@ -40,6 +44,9 @@ public static void enterCompilationUnit(DependencyVisitorState state, String pac /** * Registers a package with the dependency collector. + * + * @param state the visitor state + * @param packageName the package name */ public static void registerPackage(DependencyVisitorState state, String packageName) { state.getTypeProcessor().getDependencyCollector().registerPackage(packageName); @@ -149,6 +156,9 @@ public static ClassSnapshot enterClassDeclaration( /** * Called when leaving a class declaration. Restores the previous owner FQN. + * + * @param state the visitor state + * @param snapshot the class snapshot */ public static void leaveClassDeclaration(DependencyVisitorState state, ClassSnapshot snapshot) { if (snapshot == null) { @@ -162,6 +172,9 @@ public static void leaveClassDeclaration(DependencyVisitorState state, ClassSnap /** * Called when visiting a method declaration. Processes return type, annotations, * type parameters, throws clauses. + * + * @param state the visitor state + * @param method the method declaration */ public static void handleMethodDeclaration(DependencyVisitorState state, J.MethodDeclaration method) { J.MethodDeclaration methodDeclaration = method; @@ -210,6 +223,9 @@ public static void handleMethodDeclaration(DependencyVisitorState state, J.Metho /** * Called when visiting variable declarations. Processes the type and annotations. * Falls back to UnattributedTypeFqnResolver when the type is not attributed. + * + * @param state the visitor state + * @param multiVariable the variable declarations */ public static void handleVariableDeclarations(DependencyVisitorState state, J.VariableDeclarations multiVariable) { if (state.getCurrentOwnerFqn() == null) { @@ -252,6 +268,9 @@ public static void handleVariableDeclarations(DependencyVisitorState state, J.Va /** * Called when visiting a method invocation. Records the declaring type and type parameters. + * + * @param state the visitor state + * @param method the method invocation */ public static void handleMethodInvocation(DependencyVisitorState state, J.MethodInvocation method) { if (state.getCurrentOwnerFqn() == null) { @@ -274,6 +293,9 @@ public static void handleMethodInvocation(DependencyVisitorState state, J.Method /** * Called when visiting a new class instantiation. Records the instantiated type. + * + * @param state the visitor state + * @param newClass the new class expression */ public static void handleNewClass(DependencyVisitorState state, J.NewClass newClass) { if (state.getCurrentOwnerFqn() != null) { @@ -285,6 +307,9 @@ public static void handleNewClass(DependencyVisitorState state, J.NewClass newCl /** * Called when visiting a lambda expression. Records the lambda's type. + * + * @param state the visitor state + * @param lambda the lambda expression */ public static void handleLambda(DependencyVisitorState state, J.Lambda lambda) { if (state.getCurrentOwnerFqn() != null && lambda.getType() != null) { @@ -296,6 +321,9 @@ public static void handleLambda(DependencyVisitorState state, J.Lambda lambda) { /** * Called when visiting an instanceof expression. Records the checked type. + * + * @param state the visitor state + * @param instanceOf the instanceof expression */ public static void handleInstanceOf(DependencyVisitorState state, J.InstanceOf instanceOf) { if (state.getCurrentOwnerFqn() != null && instanceOf.getClazz() instanceof TypeTree) { @@ -308,6 +336,9 @@ public static void handleInstanceOf(DependencyVisitorState state, J.InstanceOf i /** * Called when visiting a type cast. Records the cast type. + * + * @param state the visitor state + * @param typeCast the type cast */ public static void handleTypeCast(DependencyVisitorState state, J.TypeCast typeCast) { if (state.getCurrentOwnerFqn() != null && typeCast.getClazz() != null) { @@ -322,6 +353,9 @@ public static void handleTypeCast(DependencyVisitorState state, J.TypeCast typeC /** * Called when visiting a new array expression. Records the array element type. + * + * @param state the visitor state + * @param newArray the new array expression */ public static void handleNewArray(DependencyVisitorState state, J.NewArray newArray) { if (state.getCurrentOwnerFqn() != null && newArray.getType() != null) { @@ -333,6 +367,9 @@ public static void handleNewArray(DependencyVisitorState state, J.NewArray newAr /** * Called when visiting a method/field reference. Records the declaring type. + * + * @param state the visitor state + * @param memberRef the member reference */ public static void handleMemberReference(DependencyVisitorState state, J.MemberReference memberRef) { if (state.getCurrentOwnerFqn() == null) { @@ -360,6 +397,10 @@ public static void handleMemberReference(DependencyVisitorState state, J.MemberR * file name from the sourcePathUri rather than deriving a synthetic path from the * class FQN. This ensures that classes in files with different names (e.g., * {@code GameSettings} in {@code Settings.kt}) map correctly. + * + * @param state the visitor state + * @param classFqn the fully qualified class name + * @param sourcePathUri the source path URI */ public static void recordClassLocation(DependencyVisitorState state, String classFqn, String sourcePathUri) { boolean isAnonymous = isAnonymousFqn(classFqn); @@ -443,6 +484,10 @@ private static String extractPackagePathFromFqn(String classFqn) { /** * Canonicalises a file:// URI against the repository path. + * + * @param repositoryPath the repository path + * @param uriString the URI string + * @return the canonicalised path */ public static String canonicaliseUriStringForRepoLookup(String repositoryPath, String uriString) { if (repositoryPath.startsWith("/") || repositoryPath.startsWith("\\")) { diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorState.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorState.java index bf8c816b..5ea6b291 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorState.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorState.java @@ -54,6 +54,13 @@ public class DependencyVisitorState { @Setter private Cursor cursor; + /** + * Creates a new DependencyVisitorState. + * + * @param repositoryPath path to the source directory + * @param repositoryRoot path to the Git repository root + * @param typeProcessor the type processor for dependency collection + */ public DependencyVisitorState(String repositoryPath, String repositoryRoot, BaseTypeProcessor typeProcessor) { this.repositoryPath = repositoryPath; this.repositoryRoot = repositoryRoot; From 0537eb44bfa0123475d723e85fbff7b85c513104 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Sat, 5 Sep 2026 18:39:03 +0000 Subject: [PATCH 2/4] Correct graph builder Javadocs for edge nullability and visitor behavior --- .../main/java/org/hjug/graphbuilder/DependencyCollector.java | 2 +- .../org/hjug/graphbuilder/metrics/DisharmonyDetector.java | 2 +- .../org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java index c5c55736..78938bcc 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/DependencyCollector.java @@ -23,7 +23,7 @@ public interface DependencyCollector { * * @param fromPackageName The package that depends on another * @param toPackageName The package being depended upon - * @return the edge representing the package dependency + * @return the package dependency edge, or {@code null} when no package edge is created */ DefaultWeightedEdge addPackageDependency(String fromPackageName, String toPackageName); diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java index 40ee51f5..52935da1 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java @@ -387,7 +387,7 @@ public boolean isBrainMethod(MethodMetrics metrics) { * ATFD > FEW AND LAA < ONE_THIRD AND FDP <= FEW * * @param metrics the method metrics to check - * @return if the method method has feature envy + * @return if the method has feature envy */ public boolean hasFeatureEnvy(MethodMetrics metrics) { return metrics.getAccessToForeignData() > FEW diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java index 957f4d52..666f2a1b 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java @@ -31,11 +31,11 @@ private DependencyVisitorLogic() {} // ===================== Compilation Unit ===================== /** - * Called on entering a compilation unit. Records the package name and source path. + * Called on entering a compilation unit. Stores the package name in the visitor state. * * @param state the visitor state * @param packageName the package name - * @param sourcePath the source path + * @param sourcePath the source path (currently unused) */ public static void enterCompilationUnit(DependencyVisitorState state, String packageName, String sourcePath) { state.setOwningPackageName(packageName); From 368679bcee0eb4dc9b062930f76a2bce5b182f3d Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Sat, 5 Sep 2026 18:41:55 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9D=20Add=20docstrings=20to=20`fix?= =?UTF-8?q?-javadocs-for-release-0.10.0`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Docstrings generation was requested by @jimbethancourt. * https://github.com/refactorfirst/RefactorFirst/pull/210#issuecomment-5553971362 The following files were modified: * `codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java` * `codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java` * `codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java` * `codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java` * `codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java` * `codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java` * `codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java` --- .../graphbuilder/CompositeGraphBuilder.java | 12 +++--- .../metrics/ComplexityCalculator.java | 2 +- .../metrics/DisharmonyDetector.java | 7 ++- .../metrics/GraphMetricsCollector.java | 26 ++--------- .../visitor/AbstractDependencyVisitor.java | 3 +- .../visitor/BaseTypeProcessor.java | 6 +-- .../visitor/DependencyVisitorLogic.java | 43 ++++++++----------- 7 files changed, 35 insertions(+), 64 deletions(-) diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java index 206d004f..eda73a53 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/CompositeGraphBuilder.java @@ -26,14 +26,14 @@ public class CompositeGraphBuilder { /** - * Build a unified {@link CodebaseGraphDTO} from a directory that may contain - * both Java and Kotlin source files. + * Builds a unified graph for Java and Kotlin source files in a repository. * - * @param repositoryPath path to the source directory - * @param excludeTests whether to exclude test files + * @param repositoryPath path to the source directory + * @param excludeTests whether to exclude test files * @param testSourceDirectory test source directory pattern - * @return a merged CodebaseGraphDTO - * @throws IOException if parsing fails + * @return the combined Java and Kotlin codebase graph + * @throws IllegalArgumentException if {@code repositoryPath} is null or empty + * @throws IOException if source analysis fails */ public CodebaseGraphDTO getCodebaseGraphDTO(String repositoryPath, boolean excludeTests, String testSourceDirectory) throws IOException { diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java index ad8d787e..f9c5829d 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ComplexityCalculator.java @@ -16,7 +16,7 @@ public class ComplexityCalculator extends JavaIsoVisitor { private int maxNestingDepth = 0; /** - * Returns the calculated cyclomatic complexity. + * Provides the calculated cyclomatic complexity. * * @return the cyclomatic complexity */ diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java index 52935da1..93b7e929 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/DisharmonyDetector.java @@ -383,11 +383,10 @@ public boolean isBrainMethod(MethodMetrics metrics) { } /** - * Feature Envy (Fig. 5.4): method accesses more foreign data than local data. - * ATFD > FEW AND LAA < ONE_THIRD AND FDP <= FEW + * Identifies methods that access substantially more foreign data than local data. * - * @param metrics the method metrics to check - * @return if the method has feature envy + * @param metrics the method metrics to evaluate + * @return {@code true} if the method has feature envy, {@code false} otherwise */ public boolean hasFeatureEnvy(MethodMetrics metrics) { return metrics.getAccessToForeignData() > FEW diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java index 82b53648..8e63a12c 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java @@ -199,14 +199,9 @@ public boolean hasKotlinMetrics() { } /** - * Read-only lookup of a class's metrics. Returns {@code null} when the - * class has never been registered with this collector. Prefer - * {@link #getOrCreateClassMetrics(String)} from visitor logic that - * intends to mutate the returned instance and have the mutation - * reflected by {@link #getAllClassMetrics()}. + * Looks up the metrics recorded for a class. * - * @param className the class name - * @return the class metrics, or {@code null} if not found + * @return the class metrics, or {@code null} if no metrics are recorded */ public ClassMetrics getClassMetrics(String className) { return classMetrics.get(className); @@ -318,23 +313,10 @@ private int computeSealedDepth(ClassMetrics metrics) { } /** - * Canonical get-or-create entry point used by {@link MetricsVisitorLogic} - * and the metrics-collecting visitors. Returns the existing - * {@link ClassMetrics} for {@code className} if present, otherwise - * creates one, stores it in {@link #getAllClassMetrics()}, and returns - * it. - *

The returned instance is the same object later returned by - * {@link #getAllClassMetrics()}. This is the invariant the historical - * {@code instanceof GraphMetricsCollector} branch in - * {@link MetricsVisitorLogic#enterClass} emulated: the - * {@link ClassMetrics} the visitor mutates during the walk is the - * instance the downstream disharmony detectors read from - * {@link #getAllClassMetrics()}. Any get-or-create path that builds an - * instance without storing it would silently discard every class's - * metrics. + * Retrieves or creates metrics for a class. * * @param className the class name - * @return the class metrics (existing or newly created) + * @return the existing or newly created class metrics */ public ClassMetrics getOrCreateClassMetrics(String className) { return classMetrics.computeIfAbsent(className, ClassMetrics::new); diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java index 28cea868..e8dbd94e 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/AbstractDependencyVisitor.java @@ -198,8 +198,7 @@ public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, P } /** - * Returns the class-to-source-file-path mapping collected during the visit. - * Delegates to the internal state. + * Provides the source file path associated with each visited class. * * @return the class-to-source-file-path mapping */ diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java index 497b1369..be0717ba 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/BaseTypeProcessor.java @@ -43,11 +43,11 @@ protected void processType(String ownerFqn, JavaType javaType) { } /** - * Processes an annotation and extracts class dependencies. + * Processes an annotation and records its class and argument type dependencies. * - * @param ownerFqn the fully qualified name of the type owner + * @param ownerFqn the fully qualified name of the owning type * @param annotation the annotation to process - * @param cursor the cursor for context + * @param cursor the cursor providing processing context */ protected void processAnnotation(String ownerFqn, J.Annotation annotation, Cursor cursor) { if (annotation.getType() instanceof JavaType.Unknown) { diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java index 666f2a1b..ca039c2a 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/visitor/DependencyVisitorLogic.java @@ -170,8 +170,7 @@ public static void leaveClassDeclaration(DependencyVisitorState state, ClassSnap // ===================== Method Declaration ===================== /** - * Called when visiting a method declaration. Processes return type, annotations, - * type parameters, throws clauses. + * Processes a method declaration's return type, annotations, type parameters, and declared exceptions. * * @param state the visitor state * @param method the method declaration @@ -221,11 +220,11 @@ public static void handleMethodDeclaration(DependencyVisitorState state, J.Metho // ===================== Variable Declarations ===================== /** - * Called when visiting variable declarations. Processes the type and annotations. - * Falls back to UnattributedTypeFqnResolver when the type is not attributed. + * Processes the annotations and declared type of variable declarations for the current class. + * Resolves unattributed types using the surrounding package and import context. * * @param state the visitor state - * @param multiVariable the variable declarations + * @param multiVariable the variable declarations to process */ public static void handleVariableDeclarations(DependencyVisitorState state, J.VariableDeclarations multiVariable) { if (state.getCurrentOwnerFqn() == null) { @@ -267,10 +266,10 @@ public static void handleVariableDeclarations(DependencyVisitorState state, J.Va // ===================== Method Invocation ===================== /** - * Called when visiting a method invocation. Records the declaring type and type parameters. + * Records the declaring type and explicit type parameters referenced by a method invocation. * * @param state the visitor state - * @param method the method invocation + * @param method the method invocation to process */ public static void handleMethodInvocation(DependencyVisitorState state, J.MethodInvocation method) { if (state.getCurrentOwnerFqn() == null) { @@ -335,10 +334,10 @@ public static void handleInstanceOf(DependencyVisitorState state, J.InstanceOf i // ===================== Type Cast ===================== /** - * Called when visiting a type cast. Records the cast type. + * Records the type used by a cast expression. * * @param state the visitor state - * @param typeCast the type cast + * @param typeCast the cast expression */ public static void handleTypeCast(DependencyVisitorState state, J.TypeCast typeCast) { if (state.getCurrentOwnerFqn() != null && typeCast.getClazz() != null) { @@ -352,7 +351,7 @@ public static void handleTypeCast(DependencyVisitorState state, J.TypeCast typeC // ===================== New Array ===================== /** - * Called when visiting a new array expression. Records the array element type. + * Records the type associated with a new array expression. * * @param state the visitor state * @param newArray the new array expression @@ -366,10 +365,10 @@ public static void handleNewArray(DependencyVisitorState state, J.NewArray newAr // ===================== Member Reference ===================== /** - * Called when visiting a method/field reference. Records the declaring type. + * Records the referenced member type and its declaring type when available. * * @param state the visitor state - * @param memberRef the member reference + * @param memberRef the member reference to process */ public static void handleMemberReference(DependencyVisitorState state, J.MemberReference memberRef) { if (state.getCurrentOwnerFqn() == null) { @@ -388,19 +387,11 @@ public static void handleMemberReference(DependencyVisitorState state, J.MemberR // ===================== Class Location Recording ===================== /** - * Records a class's source file location. Handles the junit synthetic path branch. - * For anonymous classes (FQN containing {@code }), the actual source file - * path is used even in the junit branch, since synthetic paths derived from the - * anonymous FQN are not meaningful. - *

- * For non-anonymous classes in the junit branch, we now also use the actual source - * file name from the sourcePathUri rather than deriving a synthetic path from the - * class FQN. This ensures that classes in files with different names (e.g., - * {@code GameSettings} in {@code Settings.kt}) map correctly. + * Records the source file location associated with a class. * * @param state the visitor state * @param classFqn the fully qualified class name - * @param sourcePathUri the source path URI + * @param sourcePathUri the source file URI */ public static void recordClassLocation(DependencyVisitorState state, String classFqn, String sourcePathUri) { boolean isAnonymous = isAnonymousFqn(classFqn); @@ -483,11 +474,11 @@ private static String extractPackagePathFromFqn(String classFqn) { } /** - * Canonicalises a file:// URI against the repository path. + * Converts a file URI into a repository-relative path. * - * @param repositoryPath the repository path - * @param uriString the URI string - * @return the canonicalised path + * @param repositoryPath the repository path to remove from the URI + * @param uriString the file URI to canonicalise + * @return the repository-relative path */ public static String canonicaliseUriStringForRepoLookup(String repositoryPath, String uriString) { if (repositoryPath.startsWith("/") || repositoryPath.startsWith("\\")) { From 91e0e9fa2cbd1e273dd6ec19d6e8af0044293478 Mon Sep 17 00:00:00 2001 From: Jim Bethancourt Date: Sat, 5 Sep 2026 14:50:17 -0500 Subject: [PATCH 4/4] Fixing JavaDocs --- .../java/org/hjug/graphbuilder/metrics/ClassMetrics.java | 2 +- .../hjug/graphbuilder/metrics/GraphMetricsCollector.java | 6 +++--- .../src/main/java/org/hjug/cbc/CycleRanker.java | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ClassMetrics.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ClassMetrics.java index 94be61d5..34da1947 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ClassMetrics.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/ClassMetrics.java @@ -369,7 +369,7 @@ public void addMethod(MethodMetrics methodMetrics) { /** * Aggregated class-level count of Kotlin/Java callable references * ({@code Klass::method}) across all declared methods. Returns the sum - * of {@link MethodMetrics#getNumberOfCallableReferences()} across every + * of {@code MethodMetrics#getNumberOfCallableReferences()} across every * method on this class. * * @return the total number of callable references diff --git a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java index 8e63a12c..eabbc038 100644 --- a/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java +++ b/codebase-graph-builder/src/main/java/org/hjug/graphbuilder/metrics/GraphMetricsCollector.java @@ -153,8 +153,8 @@ public void recordMethodMetric(String className, String methodSignature, String /** * Returns {@code true} iff at least one collected {@link ClassMetrics} - * carries a Kotlin-specific signal — i.e. {@link ClassMetrics#isDataClass()}, - * {@link ClassMetrics#isSealed()}, {@link ClassMetrics#getNumberOfExtensionFunctions()} + * carries a Kotlin-specific signal — i.e. {@code ClassMetrics#isDataClass()}, + * {@code ClassMetrics#isSealed()}, {@code ClassMetrics#getNumberOfExtensionFunctions()} * > 0, a non-empty {@link ClassMetrics#getExtensionReceiverTypes()}, or a * non-empty {@link ClassMetrics#getSealedHierarchyAncestors()}. * @@ -174,7 +174,7 @@ public void recordMethodMetric(String className, String methodSignature, String * only after {@link #finalizeMetrics()} has run (detection always runs * post-finalization); before finalization the cached value is still * computed on demand but may not reflect {@link #computeKotlinDerivedMetrics()} - * derived flags such as {@link ClassMetrics#isHasExplicitLogic()}. + * derived flags such as {@code ClassMetrics#isHasExplicitLogic()}. * * @return {@code true} if any class carries a Kotlin-specific metric signal, * {@code false} for an empty or Java-only collector diff --git a/cost-benefit-calculator/src/main/java/org/hjug/cbc/CycleRanker.java b/cost-benefit-calculator/src/main/java/org/hjug/cbc/CycleRanker.java index d23cd56d..65157d16 100644 --- a/cost-benefit-calculator/src/main/java/org/hjug/cbc/CycleRanker.java +++ b/cost-benefit-calculator/src/main/java/org/hjug/cbc/CycleRanker.java @@ -38,7 +38,6 @@ public CycleRanker(String repositoryPath) { * @param excludeTests whether to exclude test files * @param testSourceDirectory test source directory pattern * @return a merged CodebaseGraphDTO - * @throws IOException if parsing fails */ // TODO: should this method belong in this class? public CodebaseGraphDTO generateClassReferencesGraph(boolean excludeTests, String testSourceDirectory) {