Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 23x 23x 39x 39x 29x 29x 29x 45x 45x 45x 45x 45x 45x 23x | import type { DependencyGraph, CoUsageData } from '../types';
/**
* Build co-usage matrix: track which files are imported together frequently.
*
* @param graph - The dependency graph to analyze.
* @returns Map of file path to nested map of related files and their co-occurrence counts.
*/
export function buildCoUsageMatrix(
graph: DependencyGraph
): Map<string, Map<string, number>> {
const coUsageMatrix = new Map<string, Map<string, number>>();
for (const [, node] of graph.nodes) {
const imports = node.imports;
for (let i = 0; i < imports.length; i++) {
const fileA = imports[i];
if (!coUsageMatrix.has(fileA)) coUsageMatrix.set(fileA, new Map());
for (let j = i + 1; j < imports.length; j++) {
const fileB = imports[j];
const fileAUsage = coUsageMatrix.get(fileA)!;
fileAUsage.set(fileB, (fileAUsage.get(fileB) || 0) + 1);
Iif (!coUsageMatrix.has(fileB)) coUsageMatrix.set(fileB, new Map());
const fileBUsage = coUsageMatrix.get(fileB)!;
fileBUsage.set(fileA, (fileBUsage.get(fileA) || 0) + 1);
}
}
}
return coUsageMatrix;
}
/**
* Find semantic clusters using frequently occurring co-usage patterns.
*
* @param coUsageMatrix - The co-usage matrix from buildCoUsageMatrix.
* @param minCoUsage - Minimum co-usage count to consider a strong relationship (default: 3).
* @returns Map of cluster representative files to their associated cluster members.
*/
export function findSemanticClusters(
coUsageMatrix: Map<string, Map<string, number>>,
minCoUsage: number = 3
): Map<string, string[]> {
const clusters = new Map<string, string[]>();
const visited = new Set<string>();
for (const [file, coUsages] of coUsageMatrix) {
if (visited.has(file)) continue;
const cluster: string[] = [file];
visited.add(file);
for (const [relatedFile, count] of coUsages) {
if (count >= minCoUsage && !visited.has(relatedFile)) {
cluster.push(relatedFile);
visited.add(relatedFile);
}
}
if (cluster.length > 1) clusters.set(file, cluster);
}
return clusters;
}
/**
* Retrieve co-usage data for a specific file.
*
* @param file - The file path to look up.
* @param coUsageMatrix - The global co-usage matrix.
* @returns Formatted co-usage data object.
*/
export function getCoUsageData(
file: string,
coUsageMatrix: Map<string, Map<string, number>>
): CoUsageData {
return {
file,
coImportedWith: coUsageMatrix.get(file) || new Map(),
sharedImporters: [],
};
}
|