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..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 { @@ -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..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 @@ -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 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/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..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,8 +369,10 @@ 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 */ 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..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 @@ -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; + /** + * Provides 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..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 @@ -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) @@ -371,8 +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 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 596eb0a5..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 @@ -199,11 +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. + * + * @return the class metrics, or {@code null} if no metrics are recorded */ public ClassMetrics getClassMetrics(String className) { return classMetrics.get(className); @@ -315,20 +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 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 0c599724..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 @@ -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"; @@ -189,8 +198,9 @@ 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 */ 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..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 @@ -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 records its class and argument type dependencies. + * + * @param ownerFqn the fully qualified name of the owning type + * @param annotation the annotation to process + * @param cursor the cursor providing processing 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..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 @@ -31,7 +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 (currently unused) */ 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) { @@ -160,8 +170,10 @@ 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 */ public static void handleMethodDeclaration(DependencyVisitorState state, J.MethodDeclaration method) { J.MethodDeclaration methodDeclaration = method; @@ -208,8 +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 to process */ public static void handleVariableDeclarations(DependencyVisitorState state, J.VariableDeclarations multiVariable) { if (state.getCurrentOwnerFqn() == null) { @@ -251,7 +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 to process */ public static void handleMethodInvocation(DependencyVisitorState state, J.MethodInvocation method) { if (state.getCurrentOwnerFqn() == null) { @@ -274,6 +292,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 +306,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 +320,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) { @@ -307,7 +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 cast expression */ public static void handleTypeCast(DependencyVisitorState state, J.TypeCast typeCast) { if (state.getCurrentOwnerFqn() != null && typeCast.getClazz() != null) { @@ -321,7 +351,10 @@ 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 */ public static void handleNewArray(DependencyVisitorState state, J.NewArray newArray) { if (state.getCurrentOwnerFqn() != null && newArray.getType() != null) { @@ -332,7 +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 to process */ public static void handleMemberReference(DependencyVisitorState state, J.MemberReference memberRef) { if (state.getCurrentOwnerFqn() == null) { @@ -351,15 +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 file URI */ public static void recordClassLocation(DependencyVisitorState state, String classFqn, String sourcePathUri) { boolean isAnonymous = isAnonymousFqn(classFqn); @@ -442,7 +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 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("\\")) { 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; 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) {