driftdetect-core 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/boundaries/boundary-scanner.d.ts +76 -0
- package/dist/boundaries/boundary-scanner.d.ts.map +1 -0
- package/dist/boundaries/boundary-scanner.js +801 -0
- package/dist/boundaries/boundary-scanner.js.map +1 -0
- package/dist/boundaries/data-access-learner.d.ts +126 -0
- package/dist/boundaries/data-access-learner.d.ts.map +1 -0
- package/dist/boundaries/data-access-learner.js +486 -0
- package/dist/boundaries/data-access-learner.js.map +1 -0
- package/dist/boundaries/index.d.ts +6 -0
- package/dist/boundaries/index.d.ts.map +1 -1
- package/dist/boundaries/index.js +6 -0
- package/dist/boundaries/index.js.map +1 -1
- package/dist/boundaries/security-prioritizer.d.ts +118 -0
- package/dist/boundaries/security-prioritizer.d.ts.map +1 -0
- package/dist/boundaries/security-prioritizer.js +316 -0
- package/dist/boundaries/security-prioritizer.js.map +1 -0
- package/dist/call-graph/analysis/coverage-analyzer.d.ts +201 -0
- package/dist/call-graph/analysis/coverage-analyzer.d.ts.map +1 -0
- package/dist/call-graph/analysis/coverage-analyzer.js +553 -0
- package/dist/call-graph/analysis/coverage-analyzer.js.map +1 -0
- package/dist/call-graph/analysis/dead-code-detector.d.ts +145 -0
- package/dist/call-graph/analysis/dead-code-detector.d.ts.map +1 -0
- package/dist/call-graph/analysis/dead-code-detector.js +391 -0
- package/dist/call-graph/analysis/dead-code-detector.js.map +1 -0
- package/dist/call-graph/analysis/graph-builder.d.ts +142 -0
- package/dist/call-graph/analysis/graph-builder.d.ts.map +1 -0
- package/dist/call-graph/analysis/graph-builder.js +624 -0
- package/dist/call-graph/analysis/graph-builder.js.map +1 -0
- package/dist/call-graph/analysis/impact-analyzer.d.ts +150 -0
- package/dist/call-graph/analysis/impact-analyzer.d.ts.map +1 -0
- package/dist/call-graph/analysis/impact-analyzer.js +329 -0
- package/dist/call-graph/analysis/impact-analyzer.js.map +1 -0
- package/dist/call-graph/analysis/index.d.ts +11 -0
- package/dist/call-graph/analysis/index.d.ts.map +1 -0
- package/dist/call-graph/analysis/index.js +9 -0
- package/dist/call-graph/analysis/index.js.map +1 -0
- package/dist/call-graph/analysis/path-finder.d.ts +117 -0
- package/dist/call-graph/analysis/path-finder.d.ts.map +1 -0
- package/dist/call-graph/analysis/path-finder.js +360 -0
- package/dist/call-graph/analysis/path-finder.js.map +1 -0
- package/dist/call-graph/analysis/reachability.d.ts +56 -0
- package/dist/call-graph/analysis/reachability.d.ts.map +1 -0
- package/dist/call-graph/analysis/reachability.js +357 -0
- package/dist/call-graph/analysis/reachability.js.map +1 -0
- package/dist/call-graph/demo.d.ts +11 -0
- package/dist/call-graph/demo.d.ts.map +1 -0
- package/dist/call-graph/demo.js +339 -0
- package/dist/call-graph/demo.js.map +1 -0
- package/dist/call-graph/enrichment/enrichment-engine.d.ts +126 -0
- package/dist/call-graph/enrichment/enrichment-engine.d.ts.map +1 -0
- package/dist/call-graph/enrichment/enrichment-engine.js +760 -0
- package/dist/call-graph/enrichment/enrichment-engine.js.map +1 -0
- package/dist/call-graph/enrichment/impact-scorer.d.ts +59 -0
- package/dist/call-graph/enrichment/impact-scorer.d.ts.map +1 -0
- package/dist/call-graph/enrichment/impact-scorer.js +328 -0
- package/dist/call-graph/enrichment/impact-scorer.js.map +1 -0
- package/dist/call-graph/enrichment/index.d.ts +12 -0
- package/dist/call-graph/enrichment/index.d.ts.map +1 -0
- package/dist/call-graph/enrichment/index.js +15 -0
- package/dist/call-graph/enrichment/index.js.map +1 -0
- package/dist/call-graph/enrichment/remediation-generator.d.ts +41 -0
- package/dist/call-graph/enrichment/remediation-generator.d.ts.map +1 -0
- package/dist/call-graph/enrichment/remediation-generator.js +609 -0
- package/dist/call-graph/enrichment/remediation-generator.js.map +1 -0
- package/dist/call-graph/enrichment/sensitivity-classifier.d.ts +71 -0
- package/dist/call-graph/enrichment/sensitivity-classifier.d.ts.map +1 -0
- package/dist/call-graph/enrichment/sensitivity-classifier.js +454 -0
- package/dist/call-graph/enrichment/sensitivity-classifier.js.map +1 -0
- package/dist/call-graph/enrichment/types.d.ts +402 -0
- package/dist/call-graph/enrichment/types.d.ts.map +1 -0
- package/dist/call-graph/enrichment/types.js +9 -0
- package/dist/call-graph/enrichment/types.js.map +1 -0
- package/dist/call-graph/extractors/base-extractor.d.ts +112 -0
- package/dist/call-graph/extractors/base-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/base-extractor.js +140 -0
- package/dist/call-graph/extractors/base-extractor.js.map +1 -0
- package/dist/call-graph/extractors/csharp-data-access-extractor.d.ts +76 -0
- package/dist/call-graph/extractors/csharp-data-access-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/csharp-data-access-extractor.js +387 -0
- package/dist/call-graph/extractors/csharp-data-access-extractor.js.map +1 -0
- package/dist/call-graph/extractors/csharp-extractor.d.ts +87 -0
- package/dist/call-graph/extractors/csharp-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/csharp-extractor.js +470 -0
- package/dist/call-graph/extractors/csharp-extractor.js.map +1 -0
- package/dist/call-graph/extractors/data-access-extractor.d.ts +76 -0
- package/dist/call-graph/extractors/data-access-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/data-access-extractor.js +234 -0
- package/dist/call-graph/extractors/data-access-extractor.js.map +1 -0
- package/dist/call-graph/extractors/index.d.ts +26 -0
- package/dist/call-graph/extractors/index.d.ts.map +1 -0
- package/dist/call-graph/extractors/index.js +36 -0
- package/dist/call-graph/extractors/index.js.map +1 -0
- package/dist/call-graph/extractors/java-data-access-extractor.d.ts +101 -0
- package/dist/call-graph/extractors/java-data-access-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/java-data-access-extractor.js +611 -0
- package/dist/call-graph/extractors/java-data-access-extractor.js.map +1 -0
- package/dist/call-graph/extractors/java-extractor.d.ts +87 -0
- package/dist/call-graph/extractors/java-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/java-extractor.js +510 -0
- package/dist/call-graph/extractors/java-extractor.js.map +1 -0
- package/dist/call-graph/extractors/php-data-access-extractor.d.ts +93 -0
- package/dist/call-graph/extractors/php-data-access-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/php-data-access-extractor.js +589 -0
- package/dist/call-graph/extractors/php-data-access-extractor.js.map +1 -0
- package/dist/call-graph/extractors/php-extractor.d.ts +104 -0
- package/dist/call-graph/extractors/php-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/php-extractor.js +619 -0
- package/dist/call-graph/extractors/php-extractor.js.map +1 -0
- package/dist/call-graph/extractors/python-data-access-extractor.d.ts +90 -0
- package/dist/call-graph/extractors/python-data-access-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/python-data-access-extractor.js +537 -0
- package/dist/call-graph/extractors/python-data-access-extractor.js.map +1 -0
- package/dist/call-graph/extractors/python-extractor.d.ts +98 -0
- package/dist/call-graph/extractors/python-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/python-extractor.js +681 -0
- package/dist/call-graph/extractors/python-extractor.js.map +1 -0
- package/dist/call-graph/extractors/semantic-data-access-scanner.d.ts +91 -0
- package/dist/call-graph/extractors/semantic-data-access-scanner.d.ts.map +1 -0
- package/dist/call-graph/extractors/semantic-data-access-scanner.js +498 -0
- package/dist/call-graph/extractors/semantic-data-access-scanner.js.map +1 -0
- package/dist/call-graph/extractors/typescript-data-access-extractor.d.ts +122 -0
- package/dist/call-graph/extractors/typescript-data-access-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/typescript-data-access-extractor.js +788 -0
- package/dist/call-graph/extractors/typescript-data-access-extractor.js.map +1 -0
- package/dist/call-graph/extractors/typescript-extractor.d.ts +145 -0
- package/dist/call-graph/extractors/typescript-extractor.d.ts.map +1 -0
- package/dist/call-graph/extractors/typescript-extractor.js +904 -0
- package/dist/call-graph/extractors/typescript-extractor.js.map +1 -0
- package/dist/call-graph/index.d.ts +127 -0
- package/dist/call-graph/index.d.ts.map +1 -0
- package/dist/call-graph/index.js +247 -0
- package/dist/call-graph/index.js.map +1 -0
- package/dist/call-graph/store/call-graph-store.d.ts +70 -0
- package/dist/call-graph/store/call-graph-store.d.ts.map +1 -0
- package/dist/call-graph/store/call-graph-store.js +210 -0
- package/dist/call-graph/store/call-graph-store.js.map +1 -0
- package/dist/call-graph/store/index.d.ts +7 -0
- package/dist/call-graph/store/index.d.ts.map +1 -0
- package/dist/call-graph/store/index.js +7 -0
- package/dist/call-graph/store/index.js.map +1 -0
- package/dist/call-graph/types.d.ts +376 -0
- package/dist/call-graph/types.d.ts.map +1 -0
- package/dist/call-graph/types.js +8 -0
- package/dist/call-graph/types.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/lake/callgraph-shard-store.d.ts +168 -0
- package/dist/lake/callgraph-shard-store.d.ts.map +1 -0
- package/dist/lake/callgraph-shard-store.js +466 -0
- package/dist/lake/callgraph-shard-store.js.map +1 -0
- package/dist/lake/examples-store.d.ts +127 -0
- package/dist/lake/examples-store.d.ts.map +1 -0
- package/dist/lake/examples-store.js +389 -0
- package/dist/lake/examples-store.js.map +1 -0
- package/dist/lake/index-store.d.ts +82 -0
- package/dist/lake/index-store.d.ts.map +1 -0
- package/dist/lake/index-store.js +359 -0
- package/dist/lake/index-store.js.map +1 -0
- package/dist/lake/index.d.ts +93 -0
- package/dist/lake/index.d.ts.map +1 -0
- package/dist/lake/index.js +138 -0
- package/dist/lake/index.js.map +1 -0
- package/dist/lake/lake.bak/index-store.d.ts +82 -0
- package/dist/lake/lake.bak/index-store.d.ts.map +1 -0
- package/dist/lake/lake.bak/index-store.js +357 -0
- package/dist/lake/lake.bak/index-store.js.map +1 -0
- package/dist/lake/lake.bak/index.d.ts +81 -0
- package/dist/lake/lake.bak/index.d.ts.map +1 -0
- package/dist/lake/lake.bak/index.js +114 -0
- package/dist/lake/lake.bak/index.js.map +1 -0
- package/dist/lake/lake.bak/manifest-store.d.ts +51 -0
- package/dist/lake/lake.bak/manifest-store.d.ts.map +1 -0
- package/dist/lake/lake.bak/manifest-store.js +347 -0
- package/dist/lake/lake.bak/manifest-store.js.map +1 -0
- package/dist/lake/lake.bak/query-engine.d.ts +112 -0
- package/dist/lake/lake.bak/query-engine.d.ts.map +1 -0
- package/dist/lake/lake.bak/query-engine.js +370 -0
- package/dist/lake/lake.bak/query-engine.js.map +1 -0
- package/dist/lake/lake.bak/types.d.ts +428 -0
- package/dist/lake/lake.bak/types.d.ts.map +1 -0
- package/dist/lake/lake.bak/types.js +46 -0
- package/dist/lake/lake.bak/types.js.map +1 -0
- package/dist/lake/lake.bak/view-materializer.d.ts +70 -0
- package/dist/lake/lake.bak/view-materializer.d.ts.map +1 -0
- package/dist/lake/lake.bak/view-materializer.js +314 -0
- package/dist/lake/lake.bak/view-materializer.js.map +1 -0
- package/dist/lake/lake.bak/view-store.d.ts +57 -0
- package/dist/lake/lake.bak/view-store.d.ts.map +1 -0
- package/dist/lake/lake.bak/view-store.js +348 -0
- package/dist/lake/lake.bak/view-store.js.map +1 -0
- package/dist/lake/manifest-store.d.ts +51 -0
- package/dist/lake/manifest-store.d.ts.map +1 -0
- package/dist/lake/manifest-store.js +348 -0
- package/dist/lake/manifest-store.js.map +1 -0
- package/dist/lake/pattern-shard-store.d.ts +87 -0
- package/dist/lake/pattern-shard-store.d.ts.map +1 -0
- package/dist/lake/pattern-shard-store.js +347 -0
- package/dist/lake/pattern-shard-store.js.map +1 -0
- package/dist/lake/query-engine.d.ts +124 -0
- package/dist/lake/query-engine.d.ts.map +1 -0
- package/dist/lake/query-engine.js +453 -0
- package/dist/lake/query-engine.js.map +1 -0
- package/dist/lake/security-shard-store.d.ts +156 -0
- package/dist/lake/security-shard-store.d.ts.map +1 -0
- package/dist/lake/security-shard-store.js +498 -0
- package/dist/lake/security-shard-store.js.map +1 -0
- package/dist/lake/types.d.ts +428 -0
- package/dist/lake/types.d.ts.map +1 -0
- package/dist/lake/types.js +46 -0
- package/dist/lake/types.js.map +1 -0
- package/dist/lake/view-materializer.d.ts +70 -0
- package/dist/lake/view-materializer.d.ts.map +1 -0
- package/dist/lake/view-materializer.js +314 -0
- package/dist/lake/view-materializer.js.map +1 -0
- package/dist/lake/view-store.d.ts +57 -0
- package/dist/lake/view-store.d.ts.map +1 -0
- package/dist/lake/view-store.js +348 -0
- package/dist/lake/view-store.js.map +1 -0
- package/dist/parsers/tree-sitter/index.d.ts +1 -0
- package/dist/parsers/tree-sitter/index.d.ts.map +1 -1
- package/dist/parsers/tree-sitter/index.js +4 -0
- package/dist/parsers/tree-sitter/index.js.map +1 -1
- package/dist/parsers/tree-sitter/typescript-loader.d.ts +58 -0
- package/dist/parsers/tree-sitter/typescript-loader.d.ts.map +1 -0
- package/dist/parsers/tree-sitter/typescript-loader.js +250 -0
- package/dist/parsers/tree-sitter/typescript-loader.js.map +1 -0
- package/dist/store/project-config.d.ts +154 -0
- package/dist/store/project-config.d.ts.map +1 -0
- package/dist/store/project-config.js +235 -0
- package/dist/store/project-config.js.map +1 -0
- package/dist/store/project-registry.d.ts +241 -0
- package/dist/store/project-registry.d.ts.map +1 -0
- package/dist/store/project-registry.js +557 -0
- package/dist/store/project-registry.js.map +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dead Code Detector
|
|
3
|
+
*
|
|
4
|
+
* Finds functions that are never called and aren't entry points.
|
|
5
|
+
* These are candidates for removal.
|
|
6
|
+
*/
|
|
7
|
+
import type { CallGraph } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Confidence level for dead code detection
|
|
10
|
+
*/
|
|
11
|
+
export type DeadCodeConfidence = 'high' | 'medium' | 'low';
|
|
12
|
+
/**
|
|
13
|
+
* Reason why code might appear dead but isn't
|
|
14
|
+
*/
|
|
15
|
+
export type FalsePositiveReason = 'dynamic-call' | 'framework-hook' | 'test-only' | 'api-endpoint' | 'event-handler' | 'serialization' | 'magic-method' | 'interface-impl' | 'callback' | 'export' | 'cli-command' | 'scheduled-task' | 'dependency-injection';
|
|
16
|
+
/**
|
|
17
|
+
* A potentially dead function
|
|
18
|
+
*/
|
|
19
|
+
export interface DeadCodeCandidate {
|
|
20
|
+
/** Function ID */
|
|
21
|
+
id: string;
|
|
22
|
+
/** Function name */
|
|
23
|
+
name: string;
|
|
24
|
+
/** Qualified name */
|
|
25
|
+
qualifiedName: string;
|
|
26
|
+
/** File path */
|
|
27
|
+
file: string;
|
|
28
|
+
/** Line number */
|
|
29
|
+
line: number;
|
|
30
|
+
/** Language */
|
|
31
|
+
language: string;
|
|
32
|
+
/** Class name if method */
|
|
33
|
+
className?: string;
|
|
34
|
+
/** Confidence this is actually dead */
|
|
35
|
+
confidence: DeadCodeConfidence;
|
|
36
|
+
/** Possible reasons this might be a false positive */
|
|
37
|
+
possibleFalsePositives: FalsePositiveReason[];
|
|
38
|
+
/** Lines of code (rough estimate) */
|
|
39
|
+
linesOfCode: number;
|
|
40
|
+
/** Does this function access data? */
|
|
41
|
+
hasDataAccess: boolean;
|
|
42
|
+
/** Is this exported? */
|
|
43
|
+
isExported: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Dead code analysis result
|
|
47
|
+
*/
|
|
48
|
+
export interface DeadCodeResult {
|
|
49
|
+
/** All dead code candidates */
|
|
50
|
+
candidates: DeadCodeCandidate[];
|
|
51
|
+
/** Summary statistics */
|
|
52
|
+
summary: {
|
|
53
|
+
totalFunctions: number;
|
|
54
|
+
deadCandidates: number;
|
|
55
|
+
highConfidence: number;
|
|
56
|
+
mediumConfidence: number;
|
|
57
|
+
lowConfidence: number;
|
|
58
|
+
estimatedDeadLines: number;
|
|
59
|
+
byLanguage: Record<string, number>;
|
|
60
|
+
byFile: Array<{
|
|
61
|
+
file: string;
|
|
62
|
+
count: number;
|
|
63
|
+
lines: number;
|
|
64
|
+
}>;
|
|
65
|
+
};
|
|
66
|
+
/** Functions excluded from analysis (entry points, etc.) */
|
|
67
|
+
excluded: {
|
|
68
|
+
entryPoints: number;
|
|
69
|
+
withCallers: number;
|
|
70
|
+
frameworkHooks: number;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Options for dead code detection
|
|
75
|
+
*/
|
|
76
|
+
export interface DeadCodeOptions {
|
|
77
|
+
/** Include exported functions (default: false - they might be used externally) */
|
|
78
|
+
includeExported?: boolean;
|
|
79
|
+
/** Include test files (default: false) */
|
|
80
|
+
includeTests?: boolean;
|
|
81
|
+
/** Minimum confidence level to report (default: low) */
|
|
82
|
+
minConfidence?: DeadCodeConfidence;
|
|
83
|
+
/** File patterns to exclude */
|
|
84
|
+
excludePatterns?: string[];
|
|
85
|
+
}
|
|
86
|
+
export declare class DeadCodeDetector {
|
|
87
|
+
private graph;
|
|
88
|
+
private entryPointSet;
|
|
89
|
+
constructor(graph: CallGraph);
|
|
90
|
+
/**
|
|
91
|
+
* Detect dead code in the codebase
|
|
92
|
+
*/
|
|
93
|
+
detect(options?: DeadCodeOptions): DeadCodeResult;
|
|
94
|
+
/**
|
|
95
|
+
* Analyze a function to determine if it's dead code
|
|
96
|
+
*/
|
|
97
|
+
private analyzeCandidate;
|
|
98
|
+
/**
|
|
99
|
+
* Check if function is a framework hook
|
|
100
|
+
*/
|
|
101
|
+
private isFrameworkHook;
|
|
102
|
+
/**
|
|
103
|
+
* Check if function has a decorator indicating it's used
|
|
104
|
+
*/
|
|
105
|
+
private hasUsedDecorator;
|
|
106
|
+
/**
|
|
107
|
+
* Check if function looks like a callback
|
|
108
|
+
*/
|
|
109
|
+
private looksLikeCallback;
|
|
110
|
+
/**
|
|
111
|
+
* Check if function looks like a decorator wrapper (nested function in decorator factory)
|
|
112
|
+
* Common patterns: decorator, wrapper, inner, wrapped
|
|
113
|
+
*/
|
|
114
|
+
private looksLikeDecoratorWrapper;
|
|
115
|
+
/**
|
|
116
|
+
* Check if function might be called dynamically
|
|
117
|
+
*/
|
|
118
|
+
private looksLikeDynamicCall;
|
|
119
|
+
/**
|
|
120
|
+
* Check if function looks like an event handler
|
|
121
|
+
*/
|
|
122
|
+
private looksLikeEventHandler;
|
|
123
|
+
/**
|
|
124
|
+
* Check if function looks like it's managed by DI
|
|
125
|
+
*/
|
|
126
|
+
private looksLikeDI;
|
|
127
|
+
/**
|
|
128
|
+
* Check if function is a serializer method
|
|
129
|
+
*/
|
|
130
|
+
private looksLikeSerializer;
|
|
131
|
+
/**
|
|
132
|
+
* Check if file is a test file
|
|
133
|
+
*/
|
|
134
|
+
private isTestFile;
|
|
135
|
+
/**
|
|
136
|
+
* Check if confidence meets threshold
|
|
137
|
+
*/
|
|
138
|
+
private meetsConfidenceThreshold;
|
|
139
|
+
/**
|
|
140
|
+
* Build summary statistics
|
|
141
|
+
*/
|
|
142
|
+
private buildSummary;
|
|
143
|
+
}
|
|
144
|
+
export declare function createDeadCodeDetector(graph: CallGraph): DeadCodeDetector;
|
|
145
|
+
//# sourceMappingURL=dead-code-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dead-code-detector.d.ts","sourceRoot":"","sources":["../../../src/call-graph/analysis/dead-code-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dead Code Detector
|
|
3
|
+
*
|
|
4
|
+
* Finds functions that are never called and aren't entry points.
|
|
5
|
+
* These are candidates for removal.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Framework Hook Patterns
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Patterns that indicate framework lifecycle methods (not dead)
|
|
12
|
+
*/
|
|
13
|
+
const FRAMEWORK_HOOKS = [
|
|
14
|
+
// Python
|
|
15
|
+
/^__init__$/, /^__new__$/, /^__del__$/,
|
|
16
|
+
/^__str__$/, /^__repr__$/, /^__hash__$/, /^__eq__$/,
|
|
17
|
+
/^__lt__$/, /^__le__$/, /^__gt__$/, /^__ge__$/,
|
|
18
|
+
/^__len__$/, /^__iter__$/, /^__next__$/, /^__getitem__$/,
|
|
19
|
+
/^__setitem__$/, /^__delitem__$/, /^__contains__$/,
|
|
20
|
+
/^__call__$/, /^__enter__$/, /^__exit__$/,
|
|
21
|
+
/^__getattr__$/, /^__setattr__$/, /^__delattr__$/,
|
|
22
|
+
/^setUp$/, /^tearDown$/, /^setUpClass$/, /^tearDownClass$/,
|
|
23
|
+
/^test_/, /^_test/,
|
|
24
|
+
// JavaScript/TypeScript
|
|
25
|
+
/^constructor$/, /^render$/, /^componentDidMount$/,
|
|
26
|
+
/^componentWillUnmount$/, /^componentDidUpdate$/,
|
|
27
|
+
/^shouldComponentUpdate$/, /^getDerivedStateFromProps$/,
|
|
28
|
+
/^getSnapshotBeforeUpdate$/, /^componentDidCatch$/,
|
|
29
|
+
/^useEffect$/, /^useState$/, /^useMemo$/, /^useCallback$/,
|
|
30
|
+
/^ngOnInit$/, /^ngOnDestroy$/, /^ngOnChanges$/, // Angular
|
|
31
|
+
/^mounted$/, /^created$/, /^destroyed$/, /^updated$/, // Vue
|
|
32
|
+
/^beforeEach$/, /^afterEach$/, /^beforeAll$/, /^afterAll$/, // Jest
|
|
33
|
+
/^describe$/, /^it$/, /^test$/,
|
|
34
|
+
// Java/C#
|
|
35
|
+
/^main$/, /^Main$/,
|
|
36
|
+
/^toString$/, /^hashCode$/, /^equals$/,
|
|
37
|
+
/^compareTo$/, /^clone$/,
|
|
38
|
+
/^Dispose$/, /^Finalize$/,
|
|
39
|
+
/^OnGet$/, /^OnPost$/, /^OnPut$/, /^OnDelete$/, // ASP.NET
|
|
40
|
+
// General
|
|
41
|
+
/^setup$/, /^teardown$/, /^init$/, /^initialize$/,
|
|
42
|
+
/^dispose$/, /^cleanup$/, /^close$/, /^shutdown$/,
|
|
43
|
+
/^handle$/, /^process$/, /^execute$/, /^run$/,
|
|
44
|
+
/^on[A-Z]/, /^handle[A-Z]/, // Event handlers
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Decorator patterns that indicate the function is used
|
|
48
|
+
*/
|
|
49
|
+
const USED_DECORATOR_PATTERNS = [
|
|
50
|
+
// Python web frameworks
|
|
51
|
+
/@app\.route/, /@router\./, /@blueprint\./,
|
|
52
|
+
/@get/, /@post/, /@put/, /@delete/, /@patch/,
|
|
53
|
+
/@api_view/, /@action/,
|
|
54
|
+
/@celery\.task/, /@shared_task/, // Celery
|
|
55
|
+
/@receiver/, /@signal/, // Django signals
|
|
56
|
+
/@property/, /@staticmethod/, /@classmethod/,
|
|
57
|
+
/@pytest\.fixture/, /@fixture/,
|
|
58
|
+
/@click\.command/, /@command/, // CLI
|
|
59
|
+
/@scheduled/, /@cron/,
|
|
60
|
+
// JavaScript/TypeScript
|
|
61
|
+
/@Get/, /@Post/, /@Put/, /@Delete/, /@Patch/, // NestJS
|
|
62
|
+
/@Controller/, /@Injectable/, /@Module/,
|
|
63
|
+
/@Component/, /@Service/, /@Directive/, // Angular
|
|
64
|
+
/@action/, /@computed/, /@observable/, // MobX
|
|
65
|
+
// Java
|
|
66
|
+
/@GetMapping/, /@PostMapping/, /@RequestMapping/,
|
|
67
|
+
/@Autowired/, /@Bean/, /@Component/, /@Service/,
|
|
68
|
+
/@Scheduled/, /@EventListener/,
|
|
69
|
+
/@Test/, /@Before/, /@After/,
|
|
70
|
+
// C#
|
|
71
|
+
/\[HttpGet\]/, /\[HttpPost\]/, /\[Route\]/,
|
|
72
|
+
/\[Fact\]/, /\[Theory\]/, /\[Test\]/,
|
|
73
|
+
];
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// Dead Code Detector
|
|
76
|
+
// ============================================================================
|
|
77
|
+
export class DeadCodeDetector {
|
|
78
|
+
graph;
|
|
79
|
+
entryPointSet;
|
|
80
|
+
constructor(graph) {
|
|
81
|
+
this.graph = graph;
|
|
82
|
+
this.entryPointSet = new Set(graph.entryPoints);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Detect dead code in the codebase
|
|
86
|
+
*/
|
|
87
|
+
detect(options = {}) {
|
|
88
|
+
const { includeExported = false, includeTests = false, minConfidence = 'low', excludePatterns = [], } = options;
|
|
89
|
+
const candidates = [];
|
|
90
|
+
let excludedEntryPoints = 0;
|
|
91
|
+
let excludedWithCallers = 0;
|
|
92
|
+
let excludedFrameworkHooks = 0;
|
|
93
|
+
for (const [id, func] of this.graph.functions) {
|
|
94
|
+
// Skip synthetic module functions (they represent top-level code)
|
|
95
|
+
if (func.name === '__module__') {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// Skip synthetic callback functions (they're implicitly called by the functions they're passed to)
|
|
99
|
+
// These have names like $map$1, $useEffect$1, $forEach$1, etc.
|
|
100
|
+
if (func.name.startsWith('$') && func.name.includes('$')) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
// Skip entry points
|
|
104
|
+
if (this.entryPointSet.has(id)) {
|
|
105
|
+
excludedEntryPoints++;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
// Skip functions with callers
|
|
109
|
+
if (func.calledBy.length > 0) {
|
|
110
|
+
excludedWithCallers++;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
// Skip test files unless requested
|
|
114
|
+
if (!includeTests && this.isTestFile(func.file)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
// Skip excluded patterns
|
|
118
|
+
if (excludePatterns.some(p => func.file.includes(p))) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// Check for framework hooks
|
|
122
|
+
if (this.isFrameworkHook(func)) {
|
|
123
|
+
excludedFrameworkHooks++;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
// Skip exported unless requested
|
|
127
|
+
if (!includeExported && func.isExported && !func.className) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
// Analyze the candidate
|
|
131
|
+
const candidate = this.analyzeCandidate(func);
|
|
132
|
+
// Filter by confidence
|
|
133
|
+
if (this.meetsConfidenceThreshold(candidate.confidence, minConfidence)) {
|
|
134
|
+
candidates.push(candidate);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Sort by confidence (high first), then by lines of code
|
|
138
|
+
candidates.sort((a, b) => {
|
|
139
|
+
const confOrder = { high: 0, medium: 1, low: 2 };
|
|
140
|
+
if (confOrder[a.confidence] !== confOrder[b.confidence]) {
|
|
141
|
+
return confOrder[a.confidence] - confOrder[b.confidence];
|
|
142
|
+
}
|
|
143
|
+
return b.linesOfCode - a.linesOfCode;
|
|
144
|
+
});
|
|
145
|
+
// Build summary
|
|
146
|
+
const summary = this.buildSummary(candidates);
|
|
147
|
+
return {
|
|
148
|
+
candidates,
|
|
149
|
+
summary,
|
|
150
|
+
excluded: {
|
|
151
|
+
entryPoints: excludedEntryPoints,
|
|
152
|
+
withCallers: excludedWithCallers,
|
|
153
|
+
frameworkHooks: excludedFrameworkHooks,
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Analyze a function to determine if it's dead code
|
|
159
|
+
*/
|
|
160
|
+
analyzeCandidate(func) {
|
|
161
|
+
const possibleFalsePositives = [];
|
|
162
|
+
let confidence = 'high';
|
|
163
|
+
// Check for patterns that might indicate false positive
|
|
164
|
+
if (func.isExported) {
|
|
165
|
+
possibleFalsePositives.push('export');
|
|
166
|
+
confidence = 'medium';
|
|
167
|
+
}
|
|
168
|
+
if (func.className) {
|
|
169
|
+
// Methods might be called via interface/base class
|
|
170
|
+
possibleFalsePositives.push('interface-impl');
|
|
171
|
+
if (confidence === 'high')
|
|
172
|
+
confidence = 'medium';
|
|
173
|
+
}
|
|
174
|
+
if (this.hasUsedDecorator(func)) {
|
|
175
|
+
possibleFalsePositives.push('framework-hook');
|
|
176
|
+
confidence = 'low';
|
|
177
|
+
}
|
|
178
|
+
if (this.looksLikeCallback(func)) {
|
|
179
|
+
possibleFalsePositives.push('callback');
|
|
180
|
+
if (confidence === 'high')
|
|
181
|
+
confidence = 'medium';
|
|
182
|
+
}
|
|
183
|
+
if (this.looksLikeDynamicCall(func)) {
|
|
184
|
+
possibleFalsePositives.push('dynamic-call');
|
|
185
|
+
confidence = 'low';
|
|
186
|
+
}
|
|
187
|
+
if (this.looksLikeEventHandler(func)) {
|
|
188
|
+
possibleFalsePositives.push('event-handler');
|
|
189
|
+
if (confidence === 'high')
|
|
190
|
+
confidence = 'medium';
|
|
191
|
+
}
|
|
192
|
+
if (this.looksLikeDI(func)) {
|
|
193
|
+
possibleFalsePositives.push('dependency-injection');
|
|
194
|
+
confidence = 'low';
|
|
195
|
+
}
|
|
196
|
+
if (this.looksLikeSerializer(func)) {
|
|
197
|
+
possibleFalsePositives.push('serialization');
|
|
198
|
+
if (confidence === 'high')
|
|
199
|
+
confidence = 'medium';
|
|
200
|
+
}
|
|
201
|
+
// Check for decorator factory pattern (nested functions named 'decorator', 'wrapper', etc.)
|
|
202
|
+
if (this.looksLikeDecoratorWrapper(func)) {
|
|
203
|
+
possibleFalsePositives.push('callback');
|
|
204
|
+
confidence = 'low';
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
id: func.id,
|
|
208
|
+
name: func.name,
|
|
209
|
+
qualifiedName: func.qualifiedName,
|
|
210
|
+
file: func.file,
|
|
211
|
+
line: func.startLine,
|
|
212
|
+
language: func.language,
|
|
213
|
+
...(func.className ? { className: func.className } : {}),
|
|
214
|
+
confidence,
|
|
215
|
+
possibleFalsePositives,
|
|
216
|
+
linesOfCode: func.endLine - func.startLine + 1,
|
|
217
|
+
hasDataAccess: func.dataAccess.length > 0,
|
|
218
|
+
isExported: func.isExported,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Check if function is a framework hook
|
|
223
|
+
*/
|
|
224
|
+
isFrameworkHook(func) {
|
|
225
|
+
return FRAMEWORK_HOOKS.some(pattern => pattern.test(func.name));
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Check if function has a decorator indicating it's used
|
|
229
|
+
*/
|
|
230
|
+
hasUsedDecorator(func) {
|
|
231
|
+
return func.decorators.some(dec => USED_DECORATOR_PATTERNS.some(pattern => pattern.test(dec)));
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Check if function looks like a callback
|
|
235
|
+
*/
|
|
236
|
+
looksLikeCallback(func) {
|
|
237
|
+
const callbackPatterns = [
|
|
238
|
+
/callback$/i, /handler$/i, /listener$/i,
|
|
239
|
+
/^on_/, /^handle_/, /^process_/,
|
|
240
|
+
/_cb$/, /_fn$/,
|
|
241
|
+
];
|
|
242
|
+
return callbackPatterns.some(p => p.test(func.name));
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Check if function looks like a decorator wrapper (nested function in decorator factory)
|
|
246
|
+
* Common patterns: decorator, wrapper, inner, wrapped
|
|
247
|
+
*/
|
|
248
|
+
looksLikeDecoratorWrapper(func) {
|
|
249
|
+
// Check if it's a nested function with common decorator wrapper names
|
|
250
|
+
const wrapperPatterns = [
|
|
251
|
+
/^decorator$/i, /^wrapper$/i, /^inner$/i, /^wrapped$/i,
|
|
252
|
+
/_decorator$/i, /_wrapper$/i,
|
|
253
|
+
/^_check_/, /^_validate_/, /^_require_/,
|
|
254
|
+
];
|
|
255
|
+
// Check if the function name matches wrapper patterns
|
|
256
|
+
if (wrapperPatterns.some(p => p.test(func.name))) {
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
// Check if it's a nested function (qualifiedName contains a dot and it's not a class method)
|
|
260
|
+
if (func.qualifiedName.includes('.') && !func.className) {
|
|
261
|
+
// Nested functions in Python decorators often have names like 'decorator', 'wrapper'
|
|
262
|
+
const parts = func.qualifiedName.split('.');
|
|
263
|
+
if (parts.length >= 2) {
|
|
264
|
+
const parentName = parts[parts.length - 2];
|
|
265
|
+
const funcName = parts[parts.length - 1];
|
|
266
|
+
// If parent looks like a decorator factory and this is a wrapper
|
|
267
|
+
const decoratorFactoryPatterns = [
|
|
268
|
+
/^rate_limit$/i, /^require_/i, /^check_/i, /^validate_/i,
|
|
269
|
+
/^auth/i, /^permission/i, /^cache/i, /^retry/i,
|
|
270
|
+
/^log/i, /^trace/i, /^measure/i, /^time/i,
|
|
271
|
+
];
|
|
272
|
+
if (decoratorFactoryPatterns.some(p => p.test(parentName))) {
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
// Common wrapper function names
|
|
276
|
+
if (['decorator', 'wrapper', 'inner', 'wrapped', '_check_limit', '_check_tier', '_check_feature'].includes(funcName)) {
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Check if function might be called dynamically
|
|
285
|
+
*/
|
|
286
|
+
looksLikeDynamicCall(func) {
|
|
287
|
+
// Functions with generic names often called via getattr/reflection
|
|
288
|
+
const dynamicPatterns = [
|
|
289
|
+
/^get_/, /^set_/, /^do_/, /^execute_/,
|
|
290
|
+
/^action_/, /^cmd_/, /^command_/,
|
|
291
|
+
];
|
|
292
|
+
return dynamicPatterns.some(p => p.test(func.name));
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Check if function looks like an event handler
|
|
296
|
+
*/
|
|
297
|
+
looksLikeEventHandler(func) {
|
|
298
|
+
const eventPatterns = [
|
|
299
|
+
/^on[A-Z]/, /^handle[A-Z]/,
|
|
300
|
+
/_event$/, /_signal$/, /_hook$/,
|
|
301
|
+
/^emit_/, /^trigger_/,
|
|
302
|
+
];
|
|
303
|
+
return eventPatterns.some(p => p.test(func.name));
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Check if function looks like it's managed by DI
|
|
307
|
+
*/
|
|
308
|
+
looksLikeDI(func) {
|
|
309
|
+
// Check decorators for DI patterns
|
|
310
|
+
const diDecorators = [
|
|
311
|
+
/@inject/i, /@autowired/i, /@bean/i,
|
|
312
|
+
/@service/i, /@component/i, /@provider/i,
|
|
313
|
+
/Depends\(/, // FastAPI
|
|
314
|
+
];
|
|
315
|
+
return func.decorators.some(dec => diDecorators.some(pattern => pattern.test(dec)));
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Check if function is a serializer method
|
|
319
|
+
*/
|
|
320
|
+
looksLikeSerializer(func) {
|
|
321
|
+
const serializerPatterns = [
|
|
322
|
+
/^to_/, /^from_/, /^serialize/, /^deserialize/,
|
|
323
|
+
/^toJSON$/, /^fromJSON$/, /^toDict$/, /^fromDict$/,
|
|
324
|
+
/^as_dict$/, /^to_dict$/, /^from_dict$/,
|
|
325
|
+
];
|
|
326
|
+
return serializerPatterns.some(p => p.test(func.name));
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Check if file is a test file
|
|
330
|
+
*/
|
|
331
|
+
isTestFile(file) {
|
|
332
|
+
return /test[s]?[\/\\]|_test\.|\.test\.|\.spec\.|test_/.test(file);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Check if confidence meets threshold
|
|
336
|
+
*/
|
|
337
|
+
meetsConfidenceThreshold(confidence, threshold) {
|
|
338
|
+
const order = { high: 2, medium: 1, low: 0 };
|
|
339
|
+
return order[confidence] >= order[threshold];
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Build summary statistics
|
|
343
|
+
*/
|
|
344
|
+
buildSummary(candidates) {
|
|
345
|
+
const byLanguage = {};
|
|
346
|
+
const byFileMap = new Map();
|
|
347
|
+
let highConfidence = 0;
|
|
348
|
+
let mediumConfidence = 0;
|
|
349
|
+
let lowConfidence = 0;
|
|
350
|
+
let estimatedDeadLines = 0;
|
|
351
|
+
for (const c of candidates) {
|
|
352
|
+
// By confidence
|
|
353
|
+
if (c.confidence === 'high')
|
|
354
|
+
highConfidence++;
|
|
355
|
+
else if (c.confidence === 'medium')
|
|
356
|
+
mediumConfidence++;
|
|
357
|
+
else
|
|
358
|
+
lowConfidence++;
|
|
359
|
+
// By language
|
|
360
|
+
byLanguage[c.language] = (byLanguage[c.language] ?? 0) + 1;
|
|
361
|
+
// By file
|
|
362
|
+
const fileStats = byFileMap.get(c.file) ?? { count: 0, lines: 0 };
|
|
363
|
+
fileStats.count++;
|
|
364
|
+
fileStats.lines += c.linesOfCode;
|
|
365
|
+
byFileMap.set(c.file, fileStats);
|
|
366
|
+
// Total lines
|
|
367
|
+
estimatedDeadLines += c.linesOfCode;
|
|
368
|
+
}
|
|
369
|
+
// Sort files by count
|
|
370
|
+
const byFile = Array.from(byFileMap.entries())
|
|
371
|
+
.map(([file, stats]) => ({ file, ...stats }))
|
|
372
|
+
.sort((a, b) => b.count - a.count);
|
|
373
|
+
return {
|
|
374
|
+
totalFunctions: this.graph.functions.size,
|
|
375
|
+
deadCandidates: candidates.length,
|
|
376
|
+
highConfidence,
|
|
377
|
+
mediumConfidence,
|
|
378
|
+
lowConfidence,
|
|
379
|
+
estimatedDeadLines,
|
|
380
|
+
byLanguage,
|
|
381
|
+
byFile: byFile.slice(0, 20), // Top 20 files
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// ============================================================================
|
|
386
|
+
// Factory
|
|
387
|
+
// ============================================================================
|
|
388
|
+
export function createDeadCodeDetector(graph) {
|
|
389
|
+
return new DeadCodeDetector(graph);
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=dead-code-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dead-code-detector.js","sourceRoot":"","sources":["../../../src/call-graph/analysis/dead-code-detector.ts"],"names":[],"mappings":"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"}
|