@defai.digital/ax-cli 3.15.21 → 3.15.24
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/README.md +22 -2
- package/dist/agent/agent-executor.d.ts +1 -1
- package/dist/agent/agent-executor.js +15 -17
- package/dist/agent/agent-executor.js.map +1 -1
- package/dist/agent/execution/tool-executor.d.ts +6 -0
- package/dist/agent/execution/tool-executor.js +16 -1
- package/dist/agent/execution/tool-executor.js.map +1 -1
- package/dist/agent/llm-agent.js +91 -22
- package/dist/agent/llm-agent.js.map +1 -1
- package/dist/agent/parallel-tools.d.ts +65 -0
- package/dist/agent/parallel-tools.js +146 -0
- package/dist/agent/parallel-tools.js.map +1 -0
- package/dist/llm/tools.js +1 -1
- package/dist/llm/tools.js.map +1 -1
- package/dist/ui/components/chat-interface.js +14 -0
- package/dist/ui/components/chat-interface.js.map +1 -1
- package/dist/ui/hooks/use-input-handler.js +2 -2
- package/dist/ui/hooks/use-input-handler.js.map +1 -1
- package/dist/ui/utils/image-handler.js +8 -5
- package/dist/ui/utils/image-handler.js.map +1 -1
- package/package.json +1 -1
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.d.ts +0 -29
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js +0 -103
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js.map +0 -1
- package/dist/analyzers/architecture/architecture-analyzer.d.ts +0 -58
- package/dist/analyzers/architecture/architecture-analyzer.js +0 -276
- package/dist/analyzers/architecture/architecture-analyzer.js.map +0 -1
- package/dist/analyzers/architecture/index.d.ts +0 -12
- package/dist/analyzers/architecture/index.js +0 -14
- package/dist/analyzers/architecture/index.js.map +0 -1
- package/dist/analyzers/architecture/pattern-detectors/base-detector.d.ts +0 -27
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js +0 -31
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js.map +0 -1
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.d.ts +0 -11
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js +0 -57
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js.map +0 -1
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.d.ts +0 -11
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js +0 -43
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js.map +0 -1
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.d.ts +0 -11
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js +0 -49
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js.map +0 -1
- package/dist/analyzers/architecture/project-structure-scanner.d.ts +0 -54
- package/dist/analyzers/architecture/project-structure-scanner.js +0 -204
- package/dist/analyzers/architecture/project-structure-scanner.js.map +0 -1
- package/dist/analyzers/ast/index.d.ts +0 -13
- package/dist/analyzers/ast/index.js +0 -16
- package/dist/analyzers/ast/index.js.map +0 -1
- package/dist/analyzers/ast/language-parser.d.ts +0 -59
- package/dist/analyzers/ast/language-parser.js +0 -107
- package/dist/analyzers/ast/language-parser.js.map +0 -1
- package/dist/analyzers/ast/multi-language-parser.d.ts +0 -79
- package/dist/analyzers/ast/multi-language-parser.js +0 -157
- package/dist/analyzers/ast/multi-language-parser.js.map +0 -1
- package/dist/analyzers/ast/node-helpers.d.ts +0 -81
- package/dist/analyzers/ast/node-helpers.js +0 -128
- package/dist/analyzers/ast/node-helpers.js.map +0 -1
- package/dist/analyzers/ast/parser.d.ts +0 -60
- package/dist/analyzers/ast/parser.js +0 -305
- package/dist/analyzers/ast/parser.js.map +0 -1
- package/dist/analyzers/ast/traverser.d.ts +0 -67
- package/dist/analyzers/ast/traverser.js +0 -156
- package/dist/analyzers/ast/traverser.js.map +0 -1
- package/dist/analyzers/ast/types.d.ts +0 -107
- package/dist/analyzers/ast/types.js +0 -7
- package/dist/analyzers/ast/types.js.map +0 -1
- package/dist/analyzers/best-practices/base-rule.d.ts +0 -45
- package/dist/analyzers/best-practices/base-rule.js +0 -45
- package/dist/analyzers/best-practices/base-rule.js.map +0 -1
- package/dist/analyzers/best-practices/best-practice-validator.d.ts +0 -35
- package/dist/analyzers/best-practices/best-practice-validator.js +0 -181
- package/dist/analyzers/best-practices/best-practice-validator.js.map +0 -1
- package/dist/analyzers/best-practices/index.d.ts +0 -10
- package/dist/analyzers/best-practices/index.js +0 -11
- package/dist/analyzers/best-practices/index.js.map +0 -1
- package/dist/analyzers/best-practices/rules/index.d.ts +0 -7
- package/dist/analyzers/best-practices/rules/index.js +0 -56
- package/dist/analyzers/best-practices/rules/index.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.d.ts +0 -17
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js +0 -41
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.d.ts +0 -27
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js +0 -76
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/index.d.ts +0 -15
- package/dist/analyzers/best-practices/rules/typescript/index.js +0 -16
- package/dist/analyzers/best-practices/rules/typescript/index.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.d.ts +0 -18
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js +0 -25
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.d.ts +0 -17
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js +0 -27
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.d.ts +0 -18
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js +0 -39
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.d.ts +0 -17
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js +0 -38
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.d.ts +0 -17
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js +0 -38
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.d.ts +0 -17
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js +0 -35
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.d.ts +0 -17
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js +0 -36
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js.map +0 -1
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.d.ts +0 -17
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js +0 -27
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js.map +0 -1
- package/dist/analyzers/best-practices/types.d.ts +0 -86
- package/dist/analyzers/best-practices/types.js +0 -7
- package/dist/analyzers/best-practices/types.js.map +0 -1
- package/dist/analyzers/cache/analysis-cache.d.ts +0 -41
- package/dist/analyzers/cache/analysis-cache.js +0 -84
- package/dist/analyzers/cache/analysis-cache.js.map +0 -1
- package/dist/analyzers/code-smells/base-smell-detector.d.ts +0 -30
- package/dist/analyzers/code-smells/base-smell-detector.js +0 -44
- package/dist/analyzers/code-smells/base-smell-detector.js.map +0 -1
- package/dist/analyzers/code-smells/code-smell-analyzer.d.ts +0 -30
- package/dist/analyzers/code-smells/code-smell-analyzer.js +0 -167
- package/dist/analyzers/code-smells/code-smell-analyzer.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/data-clumps-detector.d.ts +0 -11
- package/dist/analyzers/code-smells/detectors/data-clumps-detector.js +0 -64
- package/dist/analyzers/code-smells/detectors/data-clumps-detector.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/dead-code-detector.d.ts +0 -11
- package/dist/analyzers/code-smells/detectors/dead-code-detector.js +0 -58
- package/dist/analyzers/code-smells/detectors/dead-code-detector.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/duplicate-code-detector.d.ts +0 -11
- package/dist/analyzers/code-smells/detectors/duplicate-code-detector.js +0 -69
- package/dist/analyzers/code-smells/detectors/duplicate-code-detector.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/feature-envy-detector.d.ts +0 -11
- package/dist/analyzers/code-smells/detectors/feature-envy-detector.js +0 -70
- package/dist/analyzers/code-smells/detectors/feature-envy-detector.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.d.ts +0 -11
- package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.js +0 -59
- package/dist/analyzers/code-smells/detectors/inappropriate-intimacy-detector.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/large-class-detector.d.ts +0 -13
- package/dist/analyzers/code-smells/detectors/large-class-detector.js +0 -61
- package/dist/analyzers/code-smells/detectors/large-class-detector.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/long-method-detector.d.ts +0 -12
- package/dist/analyzers/code-smells/detectors/long-method-detector.js +0 -55
- package/dist/analyzers/code-smells/detectors/long-method-detector.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.d.ts +0 -12
- package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.js +0 -53
- package/dist/analyzers/code-smells/detectors/long-parameter-list-detector.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/magic-numbers-detector.d.ts +0 -12
- package/dist/analyzers/code-smells/detectors/magic-numbers-detector.js +0 -56
- package/dist/analyzers/code-smells/detectors/magic-numbers-detector.js.map +0 -1
- package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.d.ts +0 -13
- package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.js +0 -77
- package/dist/analyzers/code-smells/detectors/nested-conditionals-detector.js.map +0 -1
- package/dist/analyzers/code-smells/index.d.ts +0 -16
- package/dist/analyzers/code-smells/index.js +0 -19
- package/dist/analyzers/code-smells/index.js.map +0 -1
- package/dist/analyzers/code-smells/types.d.ts +0 -82
- package/dist/analyzers/code-smells/types.js +0 -30
- package/dist/analyzers/code-smells/types.js.map +0 -1
- package/dist/analyzers/dependency/circular-detector.d.ts +0 -17
- package/dist/analyzers/dependency/circular-detector.js +0 -73
- package/dist/analyzers/dependency/circular-detector.js.map +0 -1
- package/dist/analyzers/dependency/coupling-calculator.d.ts +0 -24
- package/dist/analyzers/dependency/coupling-calculator.js +0 -86
- package/dist/analyzers/dependency/coupling-calculator.js.map +0 -1
- package/dist/analyzers/dependency/dependency-analyzer.d.ts +0 -44
- package/dist/analyzers/dependency/dependency-analyzer.js +0 -218
- package/dist/analyzers/dependency/dependency-analyzer.js.map +0 -1
- package/dist/analyzers/dependency/dependency-graph.d.ts +0 -57
- package/dist/analyzers/dependency/dependency-graph.js +0 -198
- package/dist/analyzers/dependency/dependency-graph.js.map +0 -1
- package/dist/analyzers/dependency/index.d.ts +0 -8
- package/dist/analyzers/dependency/index.js +0 -8
- package/dist/analyzers/dependency/index.js.map +0 -1
- package/dist/analyzers/dependency/types.d.ts +0 -105
- package/dist/analyzers/dependency/types.js +0 -5
- package/dist/analyzers/dependency/types.js.map +0 -1
- package/dist/analyzers/errors.d.ts +0 -51
- package/dist/analyzers/errors.js +0 -79
- package/dist/analyzers/errors.js.map +0 -1
- package/dist/analyzers/git/churn-calculator.d.ts +0 -36
- package/dist/analyzers/git/churn-calculator.js +0 -257
- package/dist/analyzers/git/churn-calculator.js.map +0 -1
- package/dist/analyzers/git/git-analyzer.d.ts +0 -19
- package/dist/analyzers/git/git-analyzer.js +0 -79
- package/dist/analyzers/git/git-analyzer.js.map +0 -1
- package/dist/analyzers/git/hotspot-detector.d.ts +0 -34
- package/dist/analyzers/git/hotspot-detector.js +0 -173
- package/dist/analyzers/git/hotspot-detector.js.map +0 -1
- package/dist/analyzers/git/index.d.ts +0 -7
- package/dist/analyzers/git/index.js +0 -7
- package/dist/analyzers/git/index.js.map +0 -1
- package/dist/analyzers/git/types.d.ts +0 -88
- package/dist/analyzers/git/types.js +0 -5
- package/dist/analyzers/git/types.js.map +0 -1
- package/dist/analyzers/metrics/halstead-calculator.d.ts +0 -30
- package/dist/analyzers/metrics/halstead-calculator.js +0 -150
- package/dist/analyzers/metrics/halstead-calculator.js.map +0 -1
- package/dist/analyzers/metrics/index.d.ts +0 -9
- package/dist/analyzers/metrics/index.js +0 -9
- package/dist/analyzers/metrics/index.js.map +0 -1
- package/dist/analyzers/metrics/maintainability-calculator.d.ts +0 -17
- package/dist/analyzers/metrics/maintainability-calculator.js +0 -46
- package/dist/analyzers/metrics/maintainability-calculator.js.map +0 -1
- package/dist/analyzers/metrics/metrics-analyzer.d.ts +0 -32
- package/dist/analyzers/metrics/metrics-analyzer.js +0 -144
- package/dist/analyzers/metrics/metrics-analyzer.js.map +0 -1
- package/dist/analyzers/metrics/types.d.ts +0 -67
- package/dist/analyzers/metrics/types.js +0 -5
- package/dist/analyzers/metrics/types.js.map +0 -1
- package/dist/analyzers/security/base-detector.d.ts +0 -58
- package/dist/analyzers/security/base-detector.js +0 -104
- package/dist/analyzers/security/base-detector.js.map +0 -1
- package/dist/analyzers/security/detectors/command-injection-detector.d.ts +0 -12
- package/dist/analyzers/security/detectors/command-injection-detector.js +0 -84
- package/dist/analyzers/security/detectors/command-injection-detector.js.map +0 -1
- package/dist/analyzers/security/detectors/hardcoded-secrets-detector.d.ts +0 -16
- package/dist/analyzers/security/detectors/hardcoded-secrets-detector.js +0 -140
- package/dist/analyzers/security/detectors/hardcoded-secrets-detector.js.map +0 -1
- package/dist/analyzers/security/detectors/insecure-deserialization-detector.d.ts +0 -12
- package/dist/analyzers/security/detectors/insecure-deserialization-detector.js +0 -109
- package/dist/analyzers/security/detectors/insecure-deserialization-detector.js.map +0 -1
- package/dist/analyzers/security/detectors/insecure-random-detector.d.ts +0 -12
- package/dist/analyzers/security/detectors/insecure-random-detector.js +0 -61
- package/dist/analyzers/security/detectors/insecure-random-detector.js.map +0 -1
- package/dist/analyzers/security/detectors/path-traversal-detector.d.ts +0 -12
- package/dist/analyzers/security/detectors/path-traversal-detector.js +0 -82
- package/dist/analyzers/security/detectors/path-traversal-detector.js.map +0 -1
- package/dist/analyzers/security/detectors/sql-injection-detector.d.ts +0 -12
- package/dist/analyzers/security/detectors/sql-injection-detector.js +0 -88
- package/dist/analyzers/security/detectors/sql-injection-detector.js.map +0 -1
- package/dist/analyzers/security/detectors/weak-crypto-detector.d.ts +0 -12
- package/dist/analyzers/security/detectors/weak-crypto-detector.js +0 -104
- package/dist/analyzers/security/detectors/weak-crypto-detector.js.map +0 -1
- package/dist/analyzers/security/detectors/xss-detector.d.ts +0 -12
- package/dist/analyzers/security/detectors/xss-detector.js +0 -90
- package/dist/analyzers/security/detectors/xss-detector.js.map +0 -1
- package/dist/analyzers/security/index.d.ts +0 -16
- package/dist/analyzers/security/index.js +0 -18
- package/dist/analyzers/security/index.js.map +0 -1
- package/dist/analyzers/security/security-analyzer.d.ts +0 -38
- package/dist/analyzers/security/security-analyzer.js +0 -215
- package/dist/analyzers/security/security-analyzer.js.map +0 -1
- package/dist/analyzers/security/types.d.ts +0 -95
- package/dist/analyzers/security/types.js +0 -7
- package/dist/analyzers/security/types.js.map +0 -1
- package/dist/tools/analysis-tools/architecture-tool.d.ts +0 -46
- package/dist/tools/analysis-tools/architecture-tool.js +0 -124
- package/dist/tools/analysis-tools/architecture-tool.js.map +0 -1
- package/dist/tools/analysis-tools/validation-tool.d.ts +0 -51
- package/dist/tools/analysis-tools/validation-tool.js +0 -121
- package/dist/tools/analysis-tools/validation-tool.js.map +0 -1
- package/dist/tools/analysis-tools.d.ts +0 -73
- package/dist/tools/analysis-tools.js +0 -422
- package/dist/tools/analysis-tools.js.map +0 -1
- package/dist/types/analysis.d.ts +0 -177
- package/dist/types/analysis.js +0 -8
- package/dist/types/analysis.js.map +0 -1
- package/dist/utils/analysis-logger.d.ts +0 -50
- package/dist/utils/analysis-logger.js +0 -73
- package/dist/utils/analysis-logger.js.map +0 -1
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Analysis Cache
|
|
3
|
-
*
|
|
4
|
-
* LRU cache for analysis results with TTL and content hash validation.
|
|
5
|
-
* Prevents re-analyzing unchanged projects.
|
|
6
|
-
*/
|
|
7
|
-
export class AnalysisCache {
|
|
8
|
-
cache = new Map();
|
|
9
|
-
ttl;
|
|
10
|
-
maxSize;
|
|
11
|
-
/**
|
|
12
|
-
* Create new analysis cache
|
|
13
|
-
* @param ttl Time-to-live in milliseconds (default: 5 minutes)
|
|
14
|
-
* @param maxSize Maximum number of entries (default: 100)
|
|
15
|
-
*/
|
|
16
|
-
constructor(ttl = 5 * 60 * 1000, maxSize = 100) {
|
|
17
|
-
this.ttl = ttl;
|
|
18
|
-
this.maxSize = maxSize;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Get cached value if it exists and is valid
|
|
22
|
-
*/
|
|
23
|
-
async get(key, hash) {
|
|
24
|
-
const entry = this.cache.get(key);
|
|
25
|
-
if (!entry) {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
// Check if expired
|
|
29
|
-
if (Date.now() - entry.timestamp > this.ttl) {
|
|
30
|
-
this.cache.delete(key);
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
// Check if content changed
|
|
34
|
-
if (entry.hash !== hash) {
|
|
35
|
-
this.cache.delete(key);
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
// Move to end (LRU)
|
|
39
|
-
this.cache.delete(key);
|
|
40
|
-
this.cache.set(key, entry);
|
|
41
|
-
return entry.value;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Set cached value
|
|
45
|
-
*/
|
|
46
|
-
set(key, value, hash) {
|
|
47
|
-
// Implement LRU eviction if cache is full
|
|
48
|
-
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
|
|
49
|
-
// Remove oldest entry (first in map)
|
|
50
|
-
const oldestKey = this.cache.keys().next().value;
|
|
51
|
-
if (oldestKey !== undefined) {
|
|
52
|
-
this.cache.delete(oldestKey);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
this.cache.set(key, {
|
|
56
|
-
value,
|
|
57
|
-
timestamp: Date.now(),
|
|
58
|
-
hash,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Check if key exists in cache (doesn't validate expiration)
|
|
63
|
-
*/
|
|
64
|
-
has(key) {
|
|
65
|
-
return this.cache.has(key);
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Clear entire cache
|
|
69
|
-
*/
|
|
70
|
-
clear() {
|
|
71
|
-
this.cache.clear();
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Get cache statistics
|
|
75
|
-
*/
|
|
76
|
-
getStats() {
|
|
77
|
-
return {
|
|
78
|
-
size: this.cache.size,
|
|
79
|
-
maxSize: this.maxSize,
|
|
80
|
-
ttl: this.ttl,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=analysis-cache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"analysis-cache.js","sourceRoot":"","sources":["../../../src/analyzers/cache/analysis-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,OAAO,aAAa;IAChB,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChC,GAAG,CAAS;IACZ,OAAO,CAAS;IAEjC;;;;OAIG;IACH,YAAY,MAAc,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,UAAkB,GAAG;QAC5D,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,IAAY;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mBAAmB;QACnB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,2BAA2B;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE3B,OAAO,KAAK,CAAC,KAAK,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW,EAAE,KAAQ,EAAE,IAAY;QACrC,0CAA0C;QAC1C,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5D,qCAAqC;YACrC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YACjD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,QAAQ;QAKN,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base Smell Detector
|
|
3
|
-
*
|
|
4
|
-
* Abstract base class for all smell detectors
|
|
5
|
-
*/
|
|
6
|
-
import { type MultiLanguageParser } from '../ast/multi-language-parser.js';
|
|
7
|
-
import type { SmellDetector, CodeSmell, SmellType, DetectorConfig } from './types.js';
|
|
8
|
-
import { SmellSeverity } from './types.js';
|
|
9
|
-
export declare abstract class BaseSmellDetector implements SmellDetector {
|
|
10
|
-
readonly type: SmellType;
|
|
11
|
-
readonly config: DetectorConfig;
|
|
12
|
-
protected astParser: MultiLanguageParser;
|
|
13
|
-
constructor(type: SmellType, config: DetectorConfig);
|
|
14
|
-
/**
|
|
15
|
-
* Detect smells in a file
|
|
16
|
-
*/
|
|
17
|
-
abstract detect(filePath: string): Promise<CodeSmell[]>;
|
|
18
|
-
/**
|
|
19
|
-
* Check if detector is enabled
|
|
20
|
-
*/
|
|
21
|
-
protected isEnabled(): boolean;
|
|
22
|
-
/**
|
|
23
|
-
* Get threshold value
|
|
24
|
-
*/
|
|
25
|
-
protected getThreshold(key: string, defaultValue: number): number;
|
|
26
|
-
/**
|
|
27
|
-
* Create a code smell object
|
|
28
|
-
*/
|
|
29
|
-
protected createSmell(filePath: string, startLine: number, endLine: number, message: string, suggestion: string, severity: SmellSeverity, metadata?: Record<string, unknown>): CodeSmell;
|
|
30
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Base Smell Detector
|
|
3
|
-
*
|
|
4
|
-
* Abstract base class for all smell detectors
|
|
5
|
-
*/
|
|
6
|
-
import { getMultiLanguageParser } from '../ast/multi-language-parser.js';
|
|
7
|
-
export class BaseSmellDetector {
|
|
8
|
-
type;
|
|
9
|
-
config;
|
|
10
|
-
astParser;
|
|
11
|
-
constructor(type, config) {
|
|
12
|
-
this.type = type;
|
|
13
|
-
this.config = config;
|
|
14
|
-
this.astParser = getMultiLanguageParser();
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Check if detector is enabled
|
|
18
|
-
*/
|
|
19
|
-
isEnabled() {
|
|
20
|
-
return this.config.enabled;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Get threshold value
|
|
24
|
-
*/
|
|
25
|
-
getThreshold(key, defaultValue) {
|
|
26
|
-
return this.config.thresholds?.[key] ?? defaultValue;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Create a code smell object
|
|
30
|
-
*/
|
|
31
|
-
createSmell(filePath, startLine, endLine, message, suggestion, severity, metadata = {}) {
|
|
32
|
-
return Object.freeze({
|
|
33
|
-
type: this.type,
|
|
34
|
-
severity,
|
|
35
|
-
filePath,
|
|
36
|
-
startLine,
|
|
37
|
-
endLine,
|
|
38
|
-
message,
|
|
39
|
-
suggestion,
|
|
40
|
-
metadata: Object.freeze(metadata),
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=base-smell-detector.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base-smell-detector.js","sourceRoot":"","sources":["../../../src/analyzers/code-smells/base-smell-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,sBAAsB,EAA4B,MAAM,iCAAiC,CAAC;AAInG,MAAM,OAAgB,iBAAiB;IAInB;IACA;IAJR,SAAS,CAAsB;IAEzC,YACkB,IAAe,EACf,MAAsB;QADtB,SAAI,GAAJ,IAAI,CAAW;QACf,WAAM,GAAN,MAAM,CAAgB;QAEtC,IAAI,CAAC,SAAS,GAAG,sBAAsB,EAAE,CAAC;IAC5C,CAAC;IAOD;;OAEG;IACO,SAAS;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED;;OAEG;IACO,YAAY,CAAC,GAAW,EAAE,YAAoB;QACtD,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC;IACvD,CAAC;IAED;;OAEG;IACO,WAAW,CACnB,QAAgB,EAChB,SAAiB,EACjB,OAAe,EACf,OAAe,EACf,UAAkB,EAClB,QAAuB,EACvB,WAAoC,EAAE;QAEtC,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ;YACR,QAAQ;YACR,SAAS;YACT,OAAO;YACP,OAAO;YACP,UAAU;YACV,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Code Smell Analyzer
|
|
3
|
-
*
|
|
4
|
-
* Main orchestrator for code smell detection
|
|
5
|
-
*/
|
|
6
|
-
import { type CodeSmell, type CodeSmellAnalysisResult, type CodeSmellAnalysisOptions } from './types.js';
|
|
7
|
-
export declare class CodeSmellAnalyzer {
|
|
8
|
-
private detectors;
|
|
9
|
-
constructor(options?: CodeSmellAnalysisOptions);
|
|
10
|
-
/**
|
|
11
|
-
* Initialize all detectors with configuration
|
|
12
|
-
*/
|
|
13
|
-
private initializeDetectors;
|
|
14
|
-
/**
|
|
15
|
-
* Analyze directory for code smells
|
|
16
|
-
*/
|
|
17
|
-
analyzeDirectory(directory: string, pattern?: string, options?: CodeSmellAnalysisOptions): Promise<CodeSmellAnalysisResult>;
|
|
18
|
-
/**
|
|
19
|
-
* Analyze single file
|
|
20
|
-
*/
|
|
21
|
-
analyzeFile(filePath: string): Promise<CodeSmell[]>;
|
|
22
|
-
/**
|
|
23
|
-
* Calculate summary statistics
|
|
24
|
-
*/
|
|
25
|
-
private calculateSummary;
|
|
26
|
-
/**
|
|
27
|
-
* Calculate code health score (0-100)
|
|
28
|
-
*/
|
|
29
|
-
private calculateHealthScore;
|
|
30
|
-
}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Code Smell Analyzer
|
|
3
|
-
*
|
|
4
|
-
* Main orchestrator for code smell detection
|
|
5
|
-
*/
|
|
6
|
-
import { glob } from 'glob';
|
|
7
|
-
import { SmellType, SmellSeverity } from './types.js';
|
|
8
|
-
import { LongMethodDetector } from './detectors/long-method-detector.js';
|
|
9
|
-
import { LargeClassDetector } from './detectors/large-class-detector.js';
|
|
10
|
-
import { LongParameterListDetector } from './detectors/long-parameter-list-detector.js';
|
|
11
|
-
import { MagicNumbersDetector } from './detectors/magic-numbers-detector.js';
|
|
12
|
-
import { NestedConditionalsDetector } from './detectors/nested-conditionals-detector.js';
|
|
13
|
-
import { DeadCodeDetector } from './detectors/dead-code-detector.js';
|
|
14
|
-
import { DuplicateCodeDetector } from './detectors/duplicate-code-detector.js';
|
|
15
|
-
import { FeatureEnvyDetector } from './detectors/feature-envy-detector.js';
|
|
16
|
-
import { DataClumpsDetector } from './detectors/data-clumps-detector.js';
|
|
17
|
-
import { InappropriateIntimacyDetector } from './detectors/inappropriate-intimacy-detector.js';
|
|
18
|
-
export class CodeSmellAnalyzer {
|
|
19
|
-
detectors;
|
|
20
|
-
constructor(options = {}) {
|
|
21
|
-
this.detectors = new Map();
|
|
22
|
-
this.initializeDetectors(options);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Initialize all detectors with configuration
|
|
26
|
-
*/
|
|
27
|
-
initializeDetectors(options) {
|
|
28
|
-
const defaultConfig = { enabled: true };
|
|
29
|
-
const detectorClasses = [
|
|
30
|
-
LongMethodDetector,
|
|
31
|
-
LargeClassDetector,
|
|
32
|
-
LongParameterListDetector,
|
|
33
|
-
MagicNumbersDetector,
|
|
34
|
-
NestedConditionalsDetector,
|
|
35
|
-
DeadCodeDetector,
|
|
36
|
-
DuplicateCodeDetector,
|
|
37
|
-
FeatureEnvyDetector,
|
|
38
|
-
DataClumpsDetector,
|
|
39
|
-
InappropriateIntimacyDetector,
|
|
40
|
-
];
|
|
41
|
-
for (const DetectorClass of detectorClasses) {
|
|
42
|
-
const detector = new DetectorClass(defaultConfig);
|
|
43
|
-
const config = options.detectorConfigs?.[detector.type] ?? defaultConfig;
|
|
44
|
-
const configuredDetector = new DetectorClass(config);
|
|
45
|
-
this.detectors.set(configuredDetector.type, configuredDetector);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Analyze directory for code smells
|
|
50
|
-
*/
|
|
51
|
-
async analyzeDirectory(directory, pattern = '**/*.{ts,tsx,js,jsx}', options = {}) {
|
|
52
|
-
const timestamp = new Date();
|
|
53
|
-
// Find all files
|
|
54
|
-
const ignorePatterns = [
|
|
55
|
-
'**/node_modules/**',
|
|
56
|
-
'**/dist/**',
|
|
57
|
-
'**/build/**',
|
|
58
|
-
'**/.git/**',
|
|
59
|
-
'**/*.test.{ts,tsx,js,jsx}',
|
|
60
|
-
'**/*.spec.{ts,tsx,js,jsx}',
|
|
61
|
-
...(options.ignorePatterns || []),
|
|
62
|
-
];
|
|
63
|
-
const files = await glob(pattern, {
|
|
64
|
-
cwd: directory,
|
|
65
|
-
absolute: true,
|
|
66
|
-
nodir: true,
|
|
67
|
-
ignore: ignorePatterns,
|
|
68
|
-
});
|
|
69
|
-
// Analyze all files
|
|
70
|
-
const allSmells = [];
|
|
71
|
-
const filesWithSmells = new Set();
|
|
72
|
-
for (const file of files) {
|
|
73
|
-
for (const detector of this.detectors.values()) {
|
|
74
|
-
try {
|
|
75
|
-
const smells = await detector.detect(file);
|
|
76
|
-
if (smells.length > 0) {
|
|
77
|
-
allSmells.push(...smells);
|
|
78
|
-
filesWithSmells.add(file);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
// Skip detector errors
|
|
83
|
-
console.error(`Error running ${detector.type} on ${file}:`, error);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// Calculate summary
|
|
88
|
-
const summary = this.calculateSummary(allSmells, files.length, filesWithSmells.size);
|
|
89
|
-
return Object.freeze({
|
|
90
|
-
smells: Object.freeze(allSmells),
|
|
91
|
-
summary: Object.freeze(summary),
|
|
92
|
-
timestamp,
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Analyze single file
|
|
97
|
-
*/
|
|
98
|
-
async analyzeFile(filePath) {
|
|
99
|
-
const smells = [];
|
|
100
|
-
for (const detector of this.detectors.values()) {
|
|
101
|
-
try {
|
|
102
|
-
const detectedSmells = await detector.detect(filePath);
|
|
103
|
-
smells.push(...detectedSmells);
|
|
104
|
-
}
|
|
105
|
-
catch (error) {
|
|
106
|
-
console.error(`Error running ${detector.type} on ${filePath}:`, error);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return smells;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Calculate summary statistics
|
|
113
|
-
*/
|
|
114
|
-
calculateSummary(smells, totalFiles, filesWithSmells) {
|
|
115
|
-
// Count by type
|
|
116
|
-
const smellsByType = {};
|
|
117
|
-
for (const type of Object.values(SmellType)) {
|
|
118
|
-
smellsByType[type] = 0;
|
|
119
|
-
}
|
|
120
|
-
for (const smell of smells) {
|
|
121
|
-
smellsByType[smell.type]++;
|
|
122
|
-
}
|
|
123
|
-
// Count by severity
|
|
124
|
-
const smellsBySeverity = {};
|
|
125
|
-
for (const severity of Object.values(SmellSeverity)) {
|
|
126
|
-
smellsBySeverity[severity] = 0;
|
|
127
|
-
}
|
|
128
|
-
for (const smell of smells) {
|
|
129
|
-
smellsBySeverity[smell.severity]++;
|
|
130
|
-
}
|
|
131
|
-
// Calculate health score
|
|
132
|
-
const codeHealthScore = this.calculateHealthScore(smells, totalFiles);
|
|
133
|
-
return {
|
|
134
|
-
totalSmells: smells.length,
|
|
135
|
-
smellsByType: Object.freeze(smellsByType),
|
|
136
|
-
smellsBySeverity: Object.freeze(smellsBySeverity),
|
|
137
|
-
filesAnalyzed: totalFiles,
|
|
138
|
-
filesWithSmells,
|
|
139
|
-
averageSmellsPerFile: totalFiles > 0 ? smells.length / totalFiles : 0,
|
|
140
|
-
codeHealthScore,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Calculate code health score (0-100)
|
|
145
|
-
*/
|
|
146
|
-
calculateHealthScore(smells, totalFiles) {
|
|
147
|
-
if (totalFiles === 0)
|
|
148
|
-
return 100;
|
|
149
|
-
// Weighted penalties by severity
|
|
150
|
-
const severityWeights = {
|
|
151
|
-
[SmellSeverity.LOW]: 1,
|
|
152
|
-
[SmellSeverity.MEDIUM]: 3,
|
|
153
|
-
[SmellSeverity.HIGH]: 7,
|
|
154
|
-
[SmellSeverity.CRITICAL]: 15,
|
|
155
|
-
};
|
|
156
|
-
let totalPenalty = 0;
|
|
157
|
-
for (const smell of smells) {
|
|
158
|
-
totalPenalty += severityWeights[smell.severity];
|
|
159
|
-
}
|
|
160
|
-
// Normalize penalty per file (penalty per file should reduce score)
|
|
161
|
-
const penaltyPerFile = totalPenalty / totalFiles;
|
|
162
|
-
// Score calculation: 100 - (penalty per file, capped at 100)
|
|
163
|
-
const score = Math.max(0, 100 - Math.min(100, penaltyPerFile * 2));
|
|
164
|
-
return Math.round(score);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
//# sourceMappingURL=code-smell-analyzer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"code-smell-analyzer.js","sourceRoot":"","sources":["../../../src/analyzers/code-smells/code-smell-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Data Clumps Detector
|
|
3
|
-
*
|
|
4
|
-
* Detects groups of parameters that frequently appear together
|
|
5
|
-
*/
|
|
6
|
-
import { BaseSmellDetector } from '../base-smell-detector.js';
|
|
7
|
-
import { type CodeSmell, type DetectorConfig } from '../types.js';
|
|
8
|
-
export declare class DataClumpsDetector extends BaseSmellDetector {
|
|
9
|
-
constructor(config?: DetectorConfig);
|
|
10
|
-
detect(filePath: string): Promise<CodeSmell[]>;
|
|
11
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Data Clumps Detector
|
|
3
|
-
*
|
|
4
|
-
* Detects groups of parameters that frequently appear together
|
|
5
|
-
*/
|
|
6
|
-
import { BaseSmellDetector } from '../base-smell-detector.js';
|
|
7
|
-
import { SmellType, SmellSeverity } from '../types.js';
|
|
8
|
-
export class DataClumpsDetector extends BaseSmellDetector {
|
|
9
|
-
constructor(config = { enabled: true, thresholds: { minOccurrences: 3, minParams: 3 } }) {
|
|
10
|
-
super(SmellType.DATA_CLUMPS, config);
|
|
11
|
-
}
|
|
12
|
-
async detect(filePath) {
|
|
13
|
-
if (!this.isEnabled())
|
|
14
|
-
return [];
|
|
15
|
-
const smells = [];
|
|
16
|
-
const minOccurrences = this.getThreshold('minOccurrences', 3);
|
|
17
|
-
const minParams = this.getThreshold('minParams', 3);
|
|
18
|
-
try {
|
|
19
|
-
const ast = await this.astParser.parseFile(filePath);
|
|
20
|
-
// Collect parameter combinations
|
|
21
|
-
const paramCombinations = new Map();
|
|
22
|
-
// Check functions
|
|
23
|
-
for (const func of ast.functions) {
|
|
24
|
-
if (func.parameters.length >= minParams) {
|
|
25
|
-
const paramNames = func.parameters.map(p => p.name).sort().join(',');
|
|
26
|
-
const existing = paramCombinations.get(paramNames) ?? [];
|
|
27
|
-
existing.push({
|
|
28
|
-
location: `function ${func.name}`,
|
|
29
|
-
line: func.startLine,
|
|
30
|
-
params: func.parameters.map(p => p.name),
|
|
31
|
-
});
|
|
32
|
-
paramCombinations.set(paramNames, existing);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
// Check methods
|
|
36
|
-
for (const cls of ast.classes) {
|
|
37
|
-
for (const method of cls.methods) {
|
|
38
|
-
if (method.parameters.length >= minParams) {
|
|
39
|
-
const paramNames = method.parameters.map(p => p.name).sort().join(',');
|
|
40
|
-
const existing = paramCombinations.get(paramNames) ?? [];
|
|
41
|
-
existing.push({
|
|
42
|
-
location: `${cls.name}.${method.name}`,
|
|
43
|
-
line: method.startLine,
|
|
44
|
-
params: method.parameters.map(p => p.name),
|
|
45
|
-
});
|
|
46
|
-
paramCombinations.set(paramNames, existing);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
// Report data clumps
|
|
51
|
-
for (const [, occurrences] of paramCombinations.entries()) {
|
|
52
|
-
if (occurrences.length >= minOccurrences) {
|
|
53
|
-
const firstOccurrence = occurrences[0];
|
|
54
|
-
smells.push(this.createSmell(filePath, firstOccurrence.line, firstOccurrence.line, `Data clump detected: Parameters (${firstOccurrence.params.join(', ')}) appear together in ${occurrences.length} locations`, `Consider creating a data class or configuration object to group these related parameters.`, occurrences.length >= 5 ? SmellSeverity.HIGH : SmellSeverity.MEDIUM, { parameters: firstOccurrence.params, occurrences: occurrences.length, locations: occurrences.map(o => o.location) }));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
// Skip files that can't be parsed
|
|
60
|
-
}
|
|
61
|
-
return smells;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=data-clumps-detector.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-clumps-detector.js","sourceRoot":"","sources":["../../../../src/analyzers/code-smells/detectors/data-clumps-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dead Code Detector
|
|
3
|
-
*
|
|
4
|
-
* Detects unused exports and variables
|
|
5
|
-
*/
|
|
6
|
-
import { BaseSmellDetector } from '../base-smell-detector.js';
|
|
7
|
-
import { type CodeSmell, type DetectorConfig } from '../types.js';
|
|
8
|
-
export declare class DeadCodeDetector extends BaseSmellDetector {
|
|
9
|
-
constructor(config?: DetectorConfig);
|
|
10
|
-
detect(filePath: string): Promise<CodeSmell[]>;
|
|
11
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dead Code Detector
|
|
3
|
-
*
|
|
4
|
-
* Detects unused exports and variables
|
|
5
|
-
*/
|
|
6
|
-
import { BaseSmellDetector } from '../base-smell-detector.js';
|
|
7
|
-
import { SmellType, SmellSeverity } from '../types.js';
|
|
8
|
-
export class DeadCodeDetector extends BaseSmellDetector {
|
|
9
|
-
constructor(config = { enabled: true }) {
|
|
10
|
-
super(SmellType.DEAD_CODE, config);
|
|
11
|
-
}
|
|
12
|
-
async detect(filePath) {
|
|
13
|
-
if (!this.isEnabled())
|
|
14
|
-
return [];
|
|
15
|
-
const smells = [];
|
|
16
|
-
try {
|
|
17
|
-
// This detector requires ts-morph semantic analysis (TypeScript/JavaScript only)
|
|
18
|
-
const sourceFile = this.astParser.getSourceFile(filePath);
|
|
19
|
-
if (!sourceFile) {
|
|
20
|
-
// Skip non-TS/JS files - they don't support reference analysis
|
|
21
|
-
return [];
|
|
22
|
-
}
|
|
23
|
-
const ast = await this.astParser.parseFile(filePath);
|
|
24
|
-
// Find all exported symbols
|
|
25
|
-
const exportedSymbols = new Set(ast.exports.map(e => e.name));
|
|
26
|
-
// Find all variable declarations
|
|
27
|
-
const variables = sourceFile.getVariableDeclarations();
|
|
28
|
-
for (const variable of variables) {
|
|
29
|
-
const name = variable.getName();
|
|
30
|
-
// Skip exported variables
|
|
31
|
-
if (exportedSymbols.has(name))
|
|
32
|
-
continue;
|
|
33
|
-
// Check if variable is referenced
|
|
34
|
-
const references = variable.findReferencesAsNodes();
|
|
35
|
-
// If only 1 reference (the declaration itself), it's unused
|
|
36
|
-
if (references.length <= 1) {
|
|
37
|
-
smells.push(this.createSmell(filePath, variable.getStartLineNumber(), variable.getEndLineNumber(), `Unused variable '${name}'`, `Remove this unused variable or export it if needed elsewhere.`, SmellSeverity.LOW, { variableName: name, references: references.length }));
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// Check for unused functions (not exported and not called)
|
|
41
|
-
const functions = sourceFile.getFunctions();
|
|
42
|
-
for (const func of functions) {
|
|
43
|
-
const name = func.getName();
|
|
44
|
-
if (!name || exportedSymbols.has(name))
|
|
45
|
-
continue;
|
|
46
|
-
const references = func.findReferencesAsNodes();
|
|
47
|
-
if (references.length <= 1) {
|
|
48
|
-
smells.push(this.createSmell(filePath, func.getStartLineNumber(), func.getEndLineNumber(), `Unused function '${name}'`, `Remove this unused function or export it if needed.`, SmellSeverity.MEDIUM, { functionName: name, references: references.length }));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
// Skip files that can't be parsed
|
|
54
|
-
}
|
|
55
|
-
return smells;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
//# sourceMappingURL=dead-code-detector.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dead-code-detector.js","sourceRoot":"","sources":["../../../../src/analyzers/code-smells/detectors/dead-code-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAuC,MAAM,aAAa,CAAC;AAE5F,MAAM,OAAO,gBAAiB,SAAQ,iBAAiB;IACrD,YAAY,SAAyB,EAAE,OAAO,EAAE,IAAI,EAAE;QACpD,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC3B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,EAAE,CAAC;QAEjC,MAAM,MAAM,GAAgB,EAAE,CAAC;QAE/B,IAAI,CAAC;YACH,iFAAiF;YACjF,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC1D,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,+DAA+D;gBAC/D,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAErD,4BAA4B;YAC5B,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAE9D,iCAAiC;YACjC,MAAM,SAAS,GAAG,UAAU,CAAC,uBAAuB,EAAE,CAAC;YAEvD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;gBAEhC,0BAA0B;gBAC1B,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAExC,kCAAkC;gBAClC,MAAM,UAAU,GAAG,QAAQ,CAAC,qBAAqB,EAAE,CAAC;gBAEpD,4DAA4D;gBAC5D,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;oBAC3B,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,WAAW,CACd,QAAQ,EACR,QAAQ,CAAC,kBAAkB,EAAE,EAC7B,QAAQ,CAAC,gBAAgB,EAAE,EAC3B,oBAAoB,IAAI,GAAG,EAC3B,+DAA+D,EAC/D,aAAa,CAAC,GAAG,EACjB,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,CACtD,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,2DAA2D;YAC3D,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,EAAE,CAAC;YAC5C,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,IAAI,IAAI,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAEjD,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAChD,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;oBAC3B,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,WAAW,CACd,QAAQ,EACR,IAAI,CAAC,kBAAkB,EAAE,EACzB,IAAI,CAAC,gBAAgB,EAAE,EACvB,oBAAoB,IAAI,GAAG,EAC3B,qDAAqD,EACrD,aAAa,CAAC,MAAM,EACpB,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,CACtD,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Duplicate Code Detector
|
|
3
|
-
*
|
|
4
|
-
* Detects similar code blocks (simplified heuristic-based detection)
|
|
5
|
-
*/
|
|
6
|
-
import { BaseSmellDetector } from '../base-smell-detector.js';
|
|
7
|
-
import { type CodeSmell, type DetectorConfig } from '../types.js';
|
|
8
|
-
export declare class DuplicateCodeDetector extends BaseSmellDetector {
|
|
9
|
-
constructor(config?: DetectorConfig);
|
|
10
|
-
detect(filePath: string): Promise<CodeSmell[]>;
|
|
11
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Duplicate Code Detector
|
|
3
|
-
*
|
|
4
|
-
* Detects similar code blocks (simplified heuristic-based detection)
|
|
5
|
-
*/
|
|
6
|
-
import { BaseSmellDetector } from '../base-smell-detector.js';
|
|
7
|
-
import { SmellType, SmellSeverity } from '../types.js';
|
|
8
|
-
export class DuplicateCodeDetector extends BaseSmellDetector {
|
|
9
|
-
constructor(config = { enabled: true, thresholds: { minLines: 5 } }) {
|
|
10
|
-
super(SmellType.DUPLICATE_CODE, config);
|
|
11
|
-
}
|
|
12
|
-
async detect(filePath) {
|
|
13
|
-
if (!this.isEnabled())
|
|
14
|
-
return [];
|
|
15
|
-
const smells = [];
|
|
16
|
-
try {
|
|
17
|
-
const ast = await this.astParser.parseFile(filePath);
|
|
18
|
-
// Simplified detection: Check for functions/methods with identical names (potential copy-paste)
|
|
19
|
-
const functionSignatures = new Map();
|
|
20
|
-
// Collect function signatures
|
|
21
|
-
for (const func of ast.functions) {
|
|
22
|
-
const signature = `${func.name}_${func.parameters.length}`;
|
|
23
|
-
const existing = functionSignatures.get(signature) ?? [];
|
|
24
|
-
existing.push({
|
|
25
|
-
name: func.name,
|
|
26
|
-
line: func.startLine,
|
|
27
|
-
params: func.parameters.length,
|
|
28
|
-
});
|
|
29
|
-
functionSignatures.set(signature, existing);
|
|
30
|
-
}
|
|
31
|
-
// Check for methods with very similar signatures across classes
|
|
32
|
-
const methodMap = new Map();
|
|
33
|
-
for (const cls of ast.classes) {
|
|
34
|
-
for (const method of cls.methods) {
|
|
35
|
-
const key = `${method.name}_${method.parameters.length}`;
|
|
36
|
-
const existing = methodMap.get(key) ?? [];
|
|
37
|
-
existing.push({
|
|
38
|
-
line: method.startLine,
|
|
39
|
-
endLine: method.endLine,
|
|
40
|
-
className: cls.name,
|
|
41
|
-
});
|
|
42
|
-
methodMap.set(key, existing);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
// Report duplicate methods (only once per signature)
|
|
46
|
-
for (const [key, occurrences] of methodMap.entries()) {
|
|
47
|
-
if (occurrences.length > 1) {
|
|
48
|
-
// EDGE CASE FIX: Split on last underscore to extract method name and param count
|
|
49
|
-
// Handle edge case where underscore might be at position 0 (e.g., "_3" for anonymous function)
|
|
50
|
-
const lastUnderscoreIndex = key.lastIndexOf('_');
|
|
51
|
-
if (lastUnderscoreIndex === -1) {
|
|
52
|
-
// No underscore found - shouldn't happen with our format, but handle defensively
|
|
53
|
-
console.warn(`Invalid method signature format: ${key}`);
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
const methodName = key.substring(0, lastUnderscoreIndex);
|
|
57
|
-
const paramCount = key.substring(lastUnderscoreIndex + 1);
|
|
58
|
-
const firstOccurrence = occurrences[0];
|
|
59
|
-
smells.push(this.createSmell(filePath, firstOccurrence.line, firstOccurrence.endLine, `Potential code duplication: Method '${methodName}' with ${paramCount} parameters appears in ${occurrences.length} classes`, `Consider extracting common logic into a shared utility function or base class.`, SmellSeverity.MEDIUM, { methodName, occurrences: occurrences.length, classes: occurrences.map(o => o.className) }));
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
// Skip files that can't be parsed
|
|
65
|
-
}
|
|
66
|
-
return smells;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=duplicate-code-detector.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"duplicate-code-detector.js","sourceRoot":"","sources":["../../../../src/analyzers/code-smells/detectors/duplicate-code-detector.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAuC,MAAM,aAAa,CAAC;AAE5F,MAAM,OAAO,qBAAsB,SAAQ,iBAAiB;IAC1D,YAAY,SAAyB,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE;QACjF,KAAK,CAAC,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC3B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,OAAO,EAAE,CAAC;QAEjC,MAAM,MAAM,GAAgB,EAAE,CAAC;QAE/B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAErD,gGAAgG;YAChG,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAiE,CAAC;YAEpG,8BAA8B;YAC9B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;gBACjC,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;gBAC3D,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBACzD,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,IAAI,EAAE,IAAI,CAAC,SAAS;oBACpB,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM;iBAC/B,CAAC,CAAC;gBACH,kBAAkB,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC9C,CAAC;YAED,gEAAgE;YAChE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAuE,CAAC;YACjG,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAC9B,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;oBACjC,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;oBACzD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;oBAC1C,QAAQ,CAAC,IAAI,CAAC;wBACZ,IAAI,EAAE,MAAM,CAAC,SAAS;wBACtB,OAAO,EAAE,MAAM,CAAC,OAAO;wBACvB,SAAS,EAAE,GAAG,CAAC,IAAI;qBACpB,CAAC,CAAC;oBACH,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;YAED,qDAAqD;YACrD,KAAK,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;gBACrD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3B,iFAAiF;oBACjF,+FAA+F;oBAC/F,MAAM,mBAAmB,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;oBACjD,IAAI,mBAAmB,KAAK,CAAC,CAAC,EAAE,CAAC;wBAC/B,iFAAiF;wBACjF,OAAO,CAAC,IAAI,CAAC,oCAAoC,GAAG,EAAE,CAAC,CAAC;wBACxD,SAAS;oBACX,CAAC;oBACD,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;oBACzD,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC;oBAC1D,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;oBACvC,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,WAAW,CACd,QAAQ,EACR,eAAe,CAAC,IAAI,EACpB,eAAe,CAAC,OAAO,EACvB,uCAAuC,UAAU,UAAU,UAAU,0BAA0B,WAAW,CAAC,MAAM,UAAU,EAC3H,gFAAgF,EAChF,aAAa,CAAC,MAAM,EACpB,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAC5F,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;QACpC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Feature Envy Detector
|
|
3
|
-
*
|
|
4
|
-
* Detects methods that use more features from other classes than their own
|
|
5
|
-
*/
|
|
6
|
-
import { BaseSmellDetector } from '../base-smell-detector.js';
|
|
7
|
-
import { type CodeSmell, type DetectorConfig } from '../types.js';
|
|
8
|
-
export declare class FeatureEnvyDetector extends BaseSmellDetector {
|
|
9
|
-
constructor(config?: DetectorConfig);
|
|
10
|
-
detect(filePath: string): Promise<CodeSmell[]>;
|
|
11
|
-
}
|