code-auditor-mcp 1.20.0 → 2.0.0
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/adapters/GoAdapter.d.ts +53 -0
- package/dist/adapters/GoAdapter.d.ts.map +1 -0
- package/dist/adapters/GoAdapter.js +602 -0
- package/dist/adapters/GoAdapter.js.map +1 -0
- package/dist/adapters/GoConfig.d.ts +35 -0
- package/dist/adapters/GoConfig.d.ts.map +1 -0
- package/dist/adapters/GoConfig.js +155 -0
- package/dist/adapters/GoConfig.js.map +1 -0
- package/dist/adapters/LanguageAdapter.d.ts +135 -0
- package/dist/adapters/LanguageAdapter.d.ts.map +1 -0
- package/dist/adapters/LanguageAdapter.js +47 -0
- package/dist/adapters/LanguageAdapter.js.map +1 -0
- package/dist/adapters/TypeScriptAdapter.d.ts +43 -0
- package/dist/adapters/TypeScriptAdapter.d.ts.map +1 -0
- package/dist/adapters/TypeScriptAdapter.js +386 -0
- package/dist/adapters/TypeScriptAdapter.js.map +1 -0
- package/dist/adapters/UniversalAnalyzer.d.ts +42 -0
- package/dist/adapters/UniversalAnalyzer.d.ts.map +1 -0
- package/dist/adapters/UniversalAnalyzer.js +103 -0
- package/dist/adapters/UniversalAnalyzer.js.map +1 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts +48 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts.map +1 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.js +178 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.js.map +1 -0
- package/dist/adapters/solidAnalyzerCompat.d.ts +21 -0
- package/dist/adapters/solidAnalyzerCompat.d.ts.map +1 -0
- package/dist/adapters/solidAnalyzerCompat.js +78 -0
- package/dist/adapters/solidAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.d.ts +103 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.js +425 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.js.map +1 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.d.ts +117 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.js +618 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.js.map +1 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts +129 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js +473 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -0
- package/dist/analyzers/cross-language/SchemaValidator.d.ts +126 -0
- package/dist/analyzers/cross-language/SchemaValidator.d.ts.map +1 -0
- package/dist/analyzers/cross-language/SchemaValidator.js +522 -0
- package/dist/analyzers/cross-language/SchemaValidator.js.map +1 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.js +59 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/documentationAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/documentationAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/documentationAnalyzerCompat.js +52 -0
- package/dist/analyzers/documentationAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/dryAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/dryAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/dryAnalyzerCompat.js +44 -0
- package/dist/analyzers/dryAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/schemaAnalyzer.d.ts +21 -0
- package/dist/analyzers/schemaAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/schemaAnalyzer.js +405 -0
- package/dist/analyzers/schemaAnalyzer.js.map +1 -0
- package/dist/analyzers/schemaAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/schemaAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/schemaAnalyzerCompat.js +69 -0
- package/dist/analyzers/schemaAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/solidAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/solidAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/solidAnalyzerCompat.js +78 -0
- package/dist/analyzers/solidAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts +71 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js +276 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +82 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +489 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts +48 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +175 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts +64 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +286 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts +119 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +812 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -0
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +23 -7
- package/dist/auditRunner.js.map +1 -1
- package/dist/codeIndexDB-enhanced.d.ts +80 -0
- package/dist/codeIndexDB-enhanced.d.ts.map +1 -0
- package/dist/codeIndexDB-enhanced.js +488 -0
- package/dist/codeIndexDB-enhanced.js.map +1 -0
- package/dist/codeIndexDb.d.ts +70 -1
- package/dist/codeIndexDb.d.ts.map +1 -1
- package/dist/codeIndexDb.js +199 -2
- package/dist/codeIndexDb.js.map +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/languages/LanguageOrchestrator.d.ts +181 -0
- package/dist/languages/LanguageOrchestrator.d.ts.map +1 -0
- package/dist/languages/LanguageOrchestrator.js +365 -0
- package/dist/languages/LanguageOrchestrator.js.map +1 -0
- package/dist/languages/LanguageRegistry.d.ts +43 -0
- package/dist/languages/LanguageRegistry.d.ts.map +1 -0
- package/dist/languages/LanguageRegistry.js +86 -0
- package/dist/languages/LanguageRegistry.js.map +1 -0
- package/dist/languages/RuntimeManager.d.ts +181 -0
- package/dist/languages/RuntimeManager.d.ts.map +1 -0
- package/dist/languages/RuntimeManager.js +841 -0
- package/dist/languages/RuntimeManager.js.map +1 -0
- package/dist/languages/UniversalAnalyzer.d.ts +37 -0
- package/dist/languages/UniversalAnalyzer.d.ts.map +1 -0
- package/dist/languages/UniversalAnalyzer.js +101 -0
- package/dist/languages/UniversalAnalyzer.js.map +1 -0
- package/dist/languages/go/GoAdapter.d.ts +57 -0
- package/dist/languages/go/GoAdapter.d.ts.map +1 -0
- package/dist/languages/go/GoAdapter.js +360 -0
- package/dist/languages/go/GoAdapter.js.map +1 -0
- package/dist/languages/index.d.ts +13 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +23 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/types.d.ts +182 -0
- package/dist/languages/types.d.ts.map +1 -0
- package/dist/languages/types.js +5 -0
- package/dist/languages/types.js.map +1 -0
- package/dist/languages/typescript/TypeScriptAdapter.d.ts +108 -0
- package/dist/languages/typescript/TypeScriptAdapter.d.ts.map +1 -0
- package/dist/languages/typescript/TypeScriptAdapter.js +567 -0
- package/dist/languages/typescript/TypeScriptAdapter.js.map +1 -0
- package/dist/languages/typescript/test-extraction.d.ts +2 -0
- package/dist/languages/typescript/test-extraction.d.ts.map +1 -0
- package/dist/languages/typescript/test-extraction.js +36 -0
- package/dist/languages/typescript/test-extraction.js.map +1 -0
- package/dist/mcp-hybrid.d.ts +10 -0
- package/dist/mcp-hybrid.d.ts.map +1 -0
- package/dist/mcp-hybrid.js +41 -0
- package/dist/mcp-hybrid.js.map +1 -0
- package/dist/mcp-index.d.ts +11 -0
- package/dist/mcp-index.d.ts.map +1 -0
- package/dist/mcp-index.js +101 -0
- package/dist/mcp-index.js.map +1 -0
- package/dist/mcp-tools/workflowGuide.d.ts.map +1 -1
- package/dist/mcp-tools/workflowGuide.js +67 -10
- package/dist/mcp-tools/workflowGuide.js.map +1 -1
- package/dist/mcp-tools-shared.d.ts +49 -0
- package/dist/mcp-tools-shared.d.ts.map +1 -0
- package/dist/mcp-tools-shared.js +1282 -0
- package/dist/mcp-tools-shared.js.map +1 -0
- package/dist/mcp-ui-server.d.ts +27 -0
- package/dist/mcp-ui-server.d.ts.map +1 -0
- package/dist/mcp-ui-server.js +484 -0
- package/dist/mcp-ui-server.js.map +1 -0
- package/dist/mcp-ui-simple.d.ts +27 -0
- package/dist/mcp-ui-simple.d.ts.map +1 -0
- package/dist/mcp-ui-simple.js +425 -0
- package/dist/mcp-ui-simple.js.map +1 -0
- package/dist/mcp.js +7 -4
- package/dist/mcp.js.map +1 -1
- package/dist/services/SchemaParser.d.ts +89 -0
- package/dist/services/SchemaParser.d.ts.map +1 -0
- package/dist/services/SchemaParser.js +434 -0
- package/dist/services/SchemaParser.js.map +1 -0
- package/dist/types/crossLanguage.d.ts +267 -0
- package/dist/types/crossLanguage.d.ts.map +1 -0
- package/dist/types/crossLanguage.js +6 -0
- package/dist/types/crossLanguage.js.map +1 -0
- package/dist/types.d.ts +128 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/fileDiscovery.d.ts +6 -0
- package/dist/utils/fileDiscovery.d.ts.map +1 -1
- package/dist/utils/fileDiscovery.js +12 -1
- package/dist/utils/fileDiscovery.js.map +1 -1
- package/examples/schema-example.json +364 -0
- package/examples/schema-example.yaml +137 -0
- package/package.json +10 -3
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal Documentation Analyzer
|
|
3
|
+
* Works across multiple programming languages using the adapter pattern
|
|
4
|
+
*/
|
|
5
|
+
import { UniversalAnalyzer } from '../../languages/UniversalAnalyzer.js';
|
|
6
|
+
export const DEFAULT_DOCUMENTATION_CONFIG = {
|
|
7
|
+
requireFunctionDocs: true,
|
|
8
|
+
requireClassDocs: true,
|
|
9
|
+
requireFileDocs: true,
|
|
10
|
+
requireParamDocs: true,
|
|
11
|
+
requireReturnDocs: true,
|
|
12
|
+
minDescriptionLength: 10,
|
|
13
|
+
checkExportedOnly: false,
|
|
14
|
+
exemptPatterns: [
|
|
15
|
+
'\\.test\\.', // files like user.test.ts
|
|
16
|
+
'\\.spec\\.', // files like user.spec.ts
|
|
17
|
+
'\\.d\\.ts$', // TypeScript declaration files
|
|
18
|
+
'mock', // mock files
|
|
19
|
+
'fixture', // fixture files
|
|
20
|
+
'__tests__', // __tests__ directories
|
|
21
|
+
'/tests?/', // /test/ or /tests/ directories
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
export class UniversalDocumentationAnalyzer extends UniversalAnalyzer {
|
|
25
|
+
name = 'documentation';
|
|
26
|
+
description = 'Analyzes documentation quality across the codebase';
|
|
27
|
+
category = 'documentation';
|
|
28
|
+
async analyzeAST(ast, adapter, config, sourceCode) {
|
|
29
|
+
console.log('[DEBUG] UniversalDocumentationAnalyzer.analyzeAST called for:', ast.filePath);
|
|
30
|
+
const violations = [];
|
|
31
|
+
const finalConfig = { ...DEFAULT_DOCUMENTATION_CONFIG, ...config };
|
|
32
|
+
console.log('[DEBUG] Documentation config:', finalConfig);
|
|
33
|
+
// Check if file is exempt
|
|
34
|
+
if (this.isExempt(ast.filePath, finalConfig.exemptPatterns)) {
|
|
35
|
+
console.log('[DEBUG] File is exempt from documentation analysis:', ast.filePath);
|
|
36
|
+
return violations;
|
|
37
|
+
}
|
|
38
|
+
console.log('[DEBUG] File is NOT exempt, proceeding with analysis:', ast.filePath);
|
|
39
|
+
// Check file-level documentation
|
|
40
|
+
if (finalConfig.requireFileDocs) {
|
|
41
|
+
const fileDoc = this.getFileDocumentation(ast, adapter);
|
|
42
|
+
if (!fileDoc || fileDoc.length < finalConfig.minDescriptionLength) {
|
|
43
|
+
violations.push(this.createViolation(ast.filePath, { line: 1, column: 1 }, 'File lacks proper documentation header', 'warning', 'file-documentation'));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Check function documentation
|
|
47
|
+
if (finalConfig.requireFunctionDocs) {
|
|
48
|
+
const functions = adapter.extractFunctions(ast);
|
|
49
|
+
console.log('[DEBUG] Extracted functions count:', functions.length);
|
|
50
|
+
for (const func of functions) {
|
|
51
|
+
// Skip if checking exported only and function is not exported
|
|
52
|
+
if (finalConfig.checkExportedOnly && !func.isExported) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
// Skip if function name matches exempt pattern
|
|
56
|
+
if (this.isExempt(func.name, finalConfig.exemptPatterns)) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const doc = func.jsDoc || '';
|
|
60
|
+
// Debug logging
|
|
61
|
+
console.log('[DEBUG] Checking function:', {
|
|
62
|
+
name: func.name,
|
|
63
|
+
jsDoc: func.jsDoc,
|
|
64
|
+
docLength: doc.length,
|
|
65
|
+
minLength: finalConfig.minDescriptionLength
|
|
66
|
+
});
|
|
67
|
+
// Check if documentation exists and is adequate
|
|
68
|
+
if (!doc || doc.length < finalConfig.minDescriptionLength) {
|
|
69
|
+
violations.push(this.createViolation(ast.filePath, func.location.start, `Function '${func.name}' lacks proper documentation`, 'warning', 'function-documentation'));
|
|
70
|
+
}
|
|
71
|
+
else if (finalConfig.requireParamDocs && func.parameters.length > 0) {
|
|
72
|
+
// Check parameter documentation
|
|
73
|
+
const missingParamDocs = this.checkParameterDocumentation(doc, func.parameters.map(p => p.name));
|
|
74
|
+
for (const param of missingParamDocs) {
|
|
75
|
+
violations.push(this.createViolation(ast.filePath, func.location.start, `Function '${func.name}' missing documentation for parameter '${param}'`, 'suggestion', 'parameter-documentation'));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Check return documentation for non-void functions
|
|
79
|
+
if (finalConfig.requireReturnDocs &&
|
|
80
|
+
func.returnType &&
|
|
81
|
+
func.returnType !== 'void' &&
|
|
82
|
+
!this.hasReturnDocumentation(doc)) {
|
|
83
|
+
violations.push(this.createViolation(ast.filePath, func.location.start, `Function '${func.name}' missing return value documentation`, 'suggestion', 'return-documentation'));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Check class documentation
|
|
88
|
+
if (finalConfig.requireClassDocs) {
|
|
89
|
+
const classes = adapter.extractClasses(ast);
|
|
90
|
+
for (const cls of classes) {
|
|
91
|
+
// Skip if checking exported only and class is not exported
|
|
92
|
+
if (finalConfig.checkExportedOnly && !cls.isExported) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
// Skip if class name matches exempt pattern
|
|
96
|
+
if (this.isExempt(cls.name, finalConfig.exemptPatterns)) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const doc = cls.jsDoc || '';
|
|
100
|
+
if (!doc || doc.length < finalConfig.minDescriptionLength) {
|
|
101
|
+
violations.push(this.createViolation(ast.filePath, cls.location.start, `Class '${cls.name}' lacks proper documentation`, 'warning', 'class-documentation'));
|
|
102
|
+
}
|
|
103
|
+
// Check method documentation
|
|
104
|
+
if (finalConfig.requireFunctionDocs) {
|
|
105
|
+
for (const method of cls.methods) {
|
|
106
|
+
const methodDoc = method.jsDoc || '';
|
|
107
|
+
if (!methodDoc || methodDoc.length < finalConfig.minDescriptionLength) {
|
|
108
|
+
violations.push(this.createViolation(ast.filePath, method.location.start, `Method '${cls.name}.${method.name}' lacks proper documentation`, 'warning', 'method-documentation'));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return violations;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Check if a name matches any exempt patterns
|
|
118
|
+
*/
|
|
119
|
+
isExempt(name, patterns) {
|
|
120
|
+
return patterns.some(pattern => {
|
|
121
|
+
const regex = new RegExp(pattern, 'i');
|
|
122
|
+
return regex.test(name);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get file-level documentation (usually at the top)
|
|
127
|
+
*/
|
|
128
|
+
getFileDocumentation(ast, adapter) {
|
|
129
|
+
// Look for documentation at the beginning of the file
|
|
130
|
+
const firstChild = ast.root.children?.[0];
|
|
131
|
+
if (firstChild) {
|
|
132
|
+
return adapter.getDocumentation(firstChild);
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Find a node by its location
|
|
138
|
+
*/
|
|
139
|
+
findNodeByLocation(root, location) {
|
|
140
|
+
const queue = [root];
|
|
141
|
+
while (queue.length > 0) {
|
|
142
|
+
const node = queue.shift();
|
|
143
|
+
if (node.location.start.line === location.line &&
|
|
144
|
+
node.location.start.column === location.column) {
|
|
145
|
+
return node;
|
|
146
|
+
}
|
|
147
|
+
if (node.children) {
|
|
148
|
+
queue.push(...node.children);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Check which parameters are missing documentation
|
|
155
|
+
*/
|
|
156
|
+
checkParameterDocumentation(doc, paramNames) {
|
|
157
|
+
const missingParams = [];
|
|
158
|
+
for (const param of paramNames) {
|
|
159
|
+
// Look for @param tags in various formats
|
|
160
|
+
const paramRegex = new RegExp(`@param\\s+(?:\\{[^}]+\\}\\s+)?${param}\\b`, 'i');
|
|
161
|
+
if (!paramRegex.test(doc)) {
|
|
162
|
+
missingParams.push(param);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return missingParams;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Check if documentation contains return value documentation
|
|
169
|
+
*/
|
|
170
|
+
hasReturnDocumentation(doc) {
|
|
171
|
+
// Look for @return or @returns tags
|
|
172
|
+
return /@returns?\b/i.test(doc);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=UniversalDocumentationAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UniversalDocumentationAnalyzer.js","sourceRoot":"","sources":["../../../src/analyzers/universal/UniversalDocumentationAnalyzer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAkBzE,MAAM,CAAC,MAAM,4BAA4B,GAAgC;IACvE,mBAAmB,EAAE,IAAI;IACzB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,IAAI;IACtB,iBAAiB,EAAE,IAAI;IACvB,oBAAoB,EAAE,EAAE;IACxB,iBAAiB,EAAE,KAAK;IACxB,cAAc,EAAE;QACd,YAAY,EAAI,0BAA0B;QAC1C,YAAY,EAAI,4BAA4B;QAC5C,YAAY,EAAI,+BAA+B;QAC/C,MAAM,EAAU,aAAa;QAC7B,SAAS,EAAO,gBAAgB;QAChC,WAAW,EAAK,wBAAwB;QACxC,UAAU,EAAM,gCAAgC;KACjD;CACF,CAAC;AAEF,MAAM,OAAO,8BAA+B,SAAQ,iBAAiB;IAC1D,IAAI,GAAG,eAAe,CAAC;IACvB,WAAW,GAAG,oDAAoD,CAAC;IACnE,QAAQ,GAAG,eAAe,CAAC;IAE1B,KAAK,CAAC,UAAU,CACxB,GAAQ,EACR,OAAwB,EACxB,MAAmC,EACnC,UAAkB;QAElB,OAAO,CAAC,GAAG,CAAC,+DAA+D,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3F,MAAM,UAAU,GAAgB,EAAE,CAAC;QACnC,MAAM,WAAW,GAAG,EAAE,GAAG,4BAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,WAAW,CAAC,CAAC;QAE1D,0BAA0B;QAC1B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;YAC5D,OAAO,CAAC,GAAG,CAAC,qDAAqD,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;YACjF,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,uDAAuD,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEnF,iCAAiC;QACjC,IAAI,WAAW,CAAC,eAAe,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACxD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,oBAAoB,EAAE,CAAC;gBAClE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAClC,GAAG,CAAC,QAAQ,EACZ,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EACtB,wCAAwC,EACxC,SAAS,EACT,oBAAoB,CACrB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,IAAI,WAAW,CAAC,mBAAmB,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,oCAAoC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;YAEpE,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,8DAA8D;gBAC9D,IAAI,WAAW,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;oBACtD,SAAS;gBACX,CAAC;gBAED,+CAA+C;gBAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;oBACzD,SAAS;gBACX,CAAC;gBAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;gBAE7B,gBAAgB;gBAChB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE;oBACxC,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,SAAS,EAAE,GAAG,CAAC,MAAM;oBACrB,SAAS,EAAE,WAAW,CAAC,oBAAoB;iBAC5C,CAAC,CAAC;gBAEH,gDAAgD;gBAChD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,oBAAoB,EAAE,CAAC;oBAC1D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAClC,GAAG,CAAC,QAAQ,EACZ,IAAI,CAAC,QAAQ,CAAC,KAAK,EACnB,aAAa,IAAI,CAAC,IAAI,8BAA8B,EACpD,SAAS,EACT,wBAAwB,CACzB,CAAC,CAAC;gBACL,CAAC;qBAAM,IAAI,WAAW,CAAC,gBAAgB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACtE,gCAAgC;oBAChC,MAAM,gBAAgB,GAAG,IAAI,CAAC,2BAA2B,CACvD,GAAG,EACH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACjC,CAAC;oBAEF,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;wBACrC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAClC,GAAG,CAAC,QAAQ,EACZ,IAAI,CAAC,QAAQ,CAAC,KAAK,EACnB,aAAa,IAAI,CAAC,IAAI,0CAA0C,KAAK,GAAG,EACxE,YAAY,EACZ,yBAAyB,CAC1B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAED,oDAAoD;gBACpD,IAAI,WAAW,CAAC,iBAAiB;oBAC7B,IAAI,CAAC,UAAU;oBACf,IAAI,CAAC,UAAU,KAAK,MAAM;oBAC1B,CAAC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;oBACtC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAClC,GAAG,CAAC,QAAQ,EACZ,IAAI,CAAC,QAAQ,CAAC,KAAK,EACnB,aAAa,IAAI,CAAC,IAAI,sCAAsC,EAC5D,YAAY,EACZ,sBAAsB,CACvB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,IAAI,WAAW,CAAC,gBAAgB,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YAE5C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,2DAA2D;gBAC3D,IAAI,WAAW,CAAC,iBAAiB,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;oBACrD,SAAS;gBACX,CAAC;gBAED,4CAA4C;gBAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;oBACxD,SAAS;gBACX,CAAC;gBAED,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;gBAE5B,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,oBAAoB,EAAE,CAAC;oBAC1D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAClC,GAAG,CAAC,QAAQ,EACZ,GAAG,CAAC,QAAQ,CAAC,KAAK,EAClB,UAAU,GAAG,CAAC,IAAI,8BAA8B,EAChD,SAAS,EACT,qBAAqB,CACtB,CAAC,CAAC;gBACL,CAAC;gBAED,6BAA6B;gBAC7B,IAAI,WAAW,CAAC,mBAAmB,EAAE,CAAC;oBACpC,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;wBACjC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;wBAErC,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,WAAW,CAAC,oBAAoB,EAAE,CAAC;4BACtE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAClC,GAAG,CAAC,QAAQ,EACZ,MAAM,CAAC,QAAQ,CAAC,KAAK,EACrB,WAAW,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,8BAA8B,EAChE,SAAS,EACT,sBAAsB,CACvB,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,IAAY,EAAE,QAAkB;QAC/C,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YAC7B,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACvC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,GAAQ,EAAE,OAAwB;QAC7D,sDAAsD;QACtD,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,OAAO,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,IAAa,EAAE,QAA0C;QAClF,MAAM,KAAK,GAAc,CAAC,IAAI,CAAC,CAAC;QAEhC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;YAE5B,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;gBAC1C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACnD,OAAO,IAAI,CAAC;YACd,CAAC;YAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,2BAA2B,CAAC,GAAW,EAAE,UAAoB;QACnE,MAAM,aAAa,GAAa,EAAE,CAAC;QAEnC,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,0CAA0C;YAC1C,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,iCAAiC,KAAK,KAAK,EAAE,GAAG,CAAC,CAAC;YAChF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,OAAO,aAAa,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,GAAW;QACxC,oCAAoC;QACpC,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal SOLID Principles Analyzer
|
|
3
|
+
* Works across multiple programming languages using the adapter pattern
|
|
4
|
+
*/
|
|
5
|
+
import { UniversalAnalyzer } from '../../languages/UniversalAnalyzer.js';
|
|
6
|
+
import type { Violation } from '../../types.js';
|
|
7
|
+
import type { AST, LanguageAdapter } from '../../languages/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration for SOLID analyzer
|
|
10
|
+
*/
|
|
11
|
+
export interface SOLIDAnalyzerConfig {
|
|
12
|
+
maxMethodsPerClass?: number;
|
|
13
|
+
maxLinesPerMethod?: number;
|
|
14
|
+
maxParametersPerMethod?: number;
|
|
15
|
+
maxClassComplexity?: number;
|
|
16
|
+
maxInterfaceMembers?: number;
|
|
17
|
+
checkDependencyInversion?: boolean;
|
|
18
|
+
checkInterfaceSegregation?: boolean;
|
|
19
|
+
checkLiskovSubstitution?: boolean;
|
|
20
|
+
skipTestFiles?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare const DEFAULT_SOLID_CONFIG: SOLIDAnalyzerConfig;
|
|
23
|
+
export declare class UniversalSOLIDAnalyzer extends UniversalAnalyzer {
|
|
24
|
+
readonly name = "solid";
|
|
25
|
+
readonly description = "Detects violations of SOLID principles";
|
|
26
|
+
readonly category = "architecture";
|
|
27
|
+
protected analyzeAST(ast: AST, adapter: LanguageAdapter, config: SOLIDAnalyzerConfig, sourceCode: string): Promise<Violation[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Analyze a class for SOLID violations
|
|
30
|
+
*/
|
|
31
|
+
private analyzeClass;
|
|
32
|
+
/**
|
|
33
|
+
* Analyze a function for SOLID violations
|
|
34
|
+
*/
|
|
35
|
+
private analyzeFunction;
|
|
36
|
+
/**
|
|
37
|
+
* Analyze an interface for Interface Segregation Principle
|
|
38
|
+
*/
|
|
39
|
+
private analyzeInterface;
|
|
40
|
+
/**
|
|
41
|
+
* Calculate class complexity
|
|
42
|
+
*/
|
|
43
|
+
private calculateClassComplexity;
|
|
44
|
+
/**
|
|
45
|
+
* Check for modification patterns (Open/Closed Principle)
|
|
46
|
+
*/
|
|
47
|
+
private hasModificationPatterns;
|
|
48
|
+
/**
|
|
49
|
+
* Check Liskov Substitution Principle
|
|
50
|
+
*/
|
|
51
|
+
private checkLiskovSubstitution;
|
|
52
|
+
/**
|
|
53
|
+
* Check Dependency Inversion Principle
|
|
54
|
+
*/
|
|
55
|
+
private checkDependencyInversion;
|
|
56
|
+
/**
|
|
57
|
+
* Helper methods
|
|
58
|
+
*/
|
|
59
|
+
private isTestFile;
|
|
60
|
+
private isPrimitiveConstructor;
|
|
61
|
+
private findNodeByLocation;
|
|
62
|
+
private walkAST;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=UniversalSOLIDAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UniversalSOLIDAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/universal/UniversalSOLIDAnalyzer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,eAAe,EAAmD,MAAM,0BAA0B,CAAC;AAEtH;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,oBAAoB,EAAE,mBAUlC,CAAC;AAEF,qBAAa,sBAAuB,SAAQ,iBAAiB;IAC3D,QAAQ,CAAC,IAAI,WAAW;IACxB,QAAQ,CAAC,WAAW,4CAA4C;IAChE,QAAQ,CAAC,QAAQ,kBAAkB;cAEnB,UAAU,CACxB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,EAAE,CAAC;IA6CvB;;OAEG;IACH,OAAO,CAAC,YAAY;IA+DpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmCvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsCxB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAgChC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA2B/B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAuC/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA6DhC;;OAEG;IACH,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,sBAAsB;IAK9B,OAAO,CAAC,kBAAkB;IAmB1B,OAAO,CAAC,OAAO;CAQhB"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal SOLID Principles Analyzer
|
|
3
|
+
* Works across multiple programming languages using the adapter pattern
|
|
4
|
+
*/
|
|
5
|
+
import { UniversalAnalyzer } from '../../languages/UniversalAnalyzer.js';
|
|
6
|
+
export const DEFAULT_SOLID_CONFIG = {
|
|
7
|
+
maxMethodsPerClass: 15,
|
|
8
|
+
maxLinesPerMethod: 50,
|
|
9
|
+
maxParametersPerMethod: 4,
|
|
10
|
+
maxClassComplexity: 50,
|
|
11
|
+
maxInterfaceMembers: 20,
|
|
12
|
+
checkDependencyInversion: true,
|
|
13
|
+
checkInterfaceSegregation: true,
|
|
14
|
+
checkLiskovSubstitution: true,
|
|
15
|
+
skipTestFiles: true
|
|
16
|
+
};
|
|
17
|
+
export class UniversalSOLIDAnalyzer extends UniversalAnalyzer {
|
|
18
|
+
name = 'solid';
|
|
19
|
+
description = 'Detects violations of SOLID principles';
|
|
20
|
+
category = 'architecture';
|
|
21
|
+
async analyzeAST(ast, adapter, config, sourceCode) {
|
|
22
|
+
console.error('[DEBUG] SOLID: analyzeAST called for:', ast.filePath);
|
|
23
|
+
console.error('[DEBUG] SOLID: Input config:', config);
|
|
24
|
+
console.error('[DEBUG] SOLID: DEFAULT_SOLID_CONFIG:', DEFAULT_SOLID_CONFIG);
|
|
25
|
+
const violations = [];
|
|
26
|
+
const finalConfig = { ...DEFAULT_SOLID_CONFIG, ...config };
|
|
27
|
+
console.error('[DEBUG] SOLID: Final config:', finalConfig);
|
|
28
|
+
// Skip test files if configured
|
|
29
|
+
if (finalConfig.skipTestFiles && this.isTestFile(ast.filePath)) {
|
|
30
|
+
return violations;
|
|
31
|
+
}
|
|
32
|
+
// Analyze classes
|
|
33
|
+
const classes = adapter.extractClasses(ast);
|
|
34
|
+
console.error(`[DEBUG] SOLID: Extracted ${classes.length} classes:`, classes.map(c => c.name));
|
|
35
|
+
for (const cls of classes) {
|
|
36
|
+
console.error(`[DEBUG] SOLID: Analyzing class: ${cls.name}`);
|
|
37
|
+
violations.push(...this.analyzeClass(cls, ast, adapter, sourceCode, finalConfig));
|
|
38
|
+
}
|
|
39
|
+
// Analyze standalone functions
|
|
40
|
+
const functions = adapter.extractFunctions(ast);
|
|
41
|
+
for (const func of functions) {
|
|
42
|
+
if (!func.isMethod) { // Skip methods as they're analyzed with their classes
|
|
43
|
+
violations.push(...this.analyzeFunction(func, ast, adapter, sourceCode, finalConfig));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Analyze interfaces if supported
|
|
47
|
+
if (adapter.extractInterfaces) {
|
|
48
|
+
console.error('[DEBUG] SOLID: extractInterfaces method exists, calling it...');
|
|
49
|
+
const interfaces = adapter.extractInterfaces(ast);
|
|
50
|
+
console.error('[DEBUG] SOLID: Extracted interfaces count:', interfaces.length);
|
|
51
|
+
for (const iface of interfaces) {
|
|
52
|
+
console.error('[DEBUG] SOLID: Analyzing interface:', iface.name, 'with', iface.members.length, 'members');
|
|
53
|
+
violations.push(...this.analyzeInterface(iface, ast, adapter, sourceCode, finalConfig));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.error('[DEBUG] SOLID: extractInterfaces method not available on adapter');
|
|
58
|
+
}
|
|
59
|
+
return violations;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Analyze a class for SOLID violations
|
|
63
|
+
*/
|
|
64
|
+
analyzeClass(cls, ast, adapter, sourceCode, config) {
|
|
65
|
+
const violations = [];
|
|
66
|
+
// Single Responsibility Principle - too many methods
|
|
67
|
+
if (cls.methods.length > (config.maxMethodsPerClass || 15)) {
|
|
68
|
+
violations.push(this.createViolation(ast.filePath, cls.location.start, `Class "${cls.name}" has ${cls.methods.length} methods, exceeding the maximum of ${config.maxMethodsPerClass || 15}. Consider splitting responsibilities.`, 'warning', 'single-responsibility'));
|
|
69
|
+
}
|
|
70
|
+
// Calculate class complexity
|
|
71
|
+
const complexity = this.calculateClassComplexity(cls, ast, adapter, sourceCode);
|
|
72
|
+
if (complexity > (config.maxClassComplexity || 50)) {
|
|
73
|
+
violations.push(this.createViolation(ast.filePath, cls.location.start, `Class "${cls.name}" has a complexity of ${complexity}, exceeding the maximum of ${config.maxClassComplexity || 50}. Consider refactoring.`, 'critical', 'single-responsibility'));
|
|
74
|
+
}
|
|
75
|
+
// Analyze each method
|
|
76
|
+
for (const method of cls.methods) {
|
|
77
|
+
violations.push(...this.analyzeFunction(method, ast, adapter, sourceCode, config));
|
|
78
|
+
}
|
|
79
|
+
// Open/Closed Principle - check for modification patterns
|
|
80
|
+
if (this.hasModificationPatterns(cls, ast, adapter, sourceCode)) {
|
|
81
|
+
violations.push(this.createViolation(ast.filePath, cls.location.start, `Class "${cls.name}" appears to be frequently modified. Consider using composition or inheritance for extension.`, 'suggestion', 'open-closed'));
|
|
82
|
+
}
|
|
83
|
+
// Liskov Substitution Principle
|
|
84
|
+
if (config.checkLiskovSubstitution && cls.extends) {
|
|
85
|
+
const lspViolations = this.checkLiskovSubstitution(cls, ast, adapter);
|
|
86
|
+
violations.push(...lspViolations);
|
|
87
|
+
}
|
|
88
|
+
// Dependency Inversion Principle
|
|
89
|
+
if (config.checkDependencyInversion) {
|
|
90
|
+
const dipViolations = this.checkDependencyInversion(cls, ast, adapter, sourceCode);
|
|
91
|
+
violations.push(...dipViolations);
|
|
92
|
+
}
|
|
93
|
+
return violations;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Analyze a function for SOLID violations
|
|
97
|
+
*/
|
|
98
|
+
analyzeFunction(func, ast, adapter, sourceCode, config) {
|
|
99
|
+
const violations = [];
|
|
100
|
+
// Too many parameters
|
|
101
|
+
if (func.parameters.length > (config.maxParametersPerMethod || 4)) {
|
|
102
|
+
violations.push(this.createViolation(ast.filePath, func.location.start, `Function "${func.name}" has ${func.parameters.length} parameters, exceeding the maximum of ${config.maxParametersPerMethod || 4}. Consider using an options object.`, 'warning', 'single-responsibility'));
|
|
103
|
+
}
|
|
104
|
+
// Function too long
|
|
105
|
+
const lineCount = func.location.end.line - func.location.start.line + 1;
|
|
106
|
+
if (lineCount > (config.maxLinesPerMethod || 50)) {
|
|
107
|
+
violations.push(this.createViolation(ast.filePath, func.location.start, `Function "${func.name}" has ${lineCount} lines, exceeding the maximum of ${config.maxLinesPerMethod || 50}. Consider breaking it down.`, 'warning', 'single-responsibility'));
|
|
108
|
+
}
|
|
109
|
+
return violations;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Analyze an interface for Interface Segregation Principle
|
|
113
|
+
*/
|
|
114
|
+
analyzeInterface(iface, ast, adapter, sourceCode, config) {
|
|
115
|
+
const violations = [];
|
|
116
|
+
console.error(`[DEBUG] SOLID: analyzeInterface called for ${iface.name}`);
|
|
117
|
+
console.error(`[DEBUG] SOLID: checkInterfaceSegregation = ${config.checkInterfaceSegregation}`);
|
|
118
|
+
console.error(`[DEBUG] SOLID: maxInterfaceMembers = ${config.maxInterfaceMembers}`);
|
|
119
|
+
if (!config.checkInterfaceSegregation) {
|
|
120
|
+
console.error(`[DEBUG] SOLID: Skipping interface segregation check for ${iface.name}`);
|
|
121
|
+
return violations;
|
|
122
|
+
}
|
|
123
|
+
const memberCount = iface.members?.length || 0;
|
|
124
|
+
const maxMembers = config.maxInterfaceMembers || 20;
|
|
125
|
+
console.error(`[DEBUG] SOLID: Interface ${iface.name} has ${memberCount} members, max allowed: ${maxMembers}`);
|
|
126
|
+
if (memberCount > maxMembers) {
|
|
127
|
+
console.error(`[DEBUG] SOLID: Creating violation for ${iface.name}`);
|
|
128
|
+
violations.push(this.createViolation(ast.filePath, iface.location.start, `Interface "${iface.name}" has ${memberCount} members, exceeding the maximum of ${maxMembers}. Consider splitting into smaller interfaces.`, 'warning', 'interface-segregation'));
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
console.error(`[DEBUG] SOLID: No violation for ${iface.name} (${memberCount} <= ${maxMembers})`);
|
|
132
|
+
}
|
|
133
|
+
return violations;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Calculate class complexity
|
|
137
|
+
*/
|
|
138
|
+
calculateClassComplexity(cls, ast, adapter, sourceCode) {
|
|
139
|
+
let complexity = 0;
|
|
140
|
+
// Base complexity for the class itself
|
|
141
|
+
complexity += 1;
|
|
142
|
+
// Add complexity for each method
|
|
143
|
+
complexity += cls.methods.length * 2;
|
|
144
|
+
// Add complexity for properties
|
|
145
|
+
complexity += cls.properties.length;
|
|
146
|
+
// Add complexity for inheritance
|
|
147
|
+
if (cls.extends)
|
|
148
|
+
complexity += 5;
|
|
149
|
+
if (cls.implements && cls.implements.length > 0) {
|
|
150
|
+
complexity += cls.implements.length * 2;
|
|
151
|
+
}
|
|
152
|
+
// Add complexity based on method sizes
|
|
153
|
+
for (const method of cls.methods) {
|
|
154
|
+
const lineCount = method.location.end.line - method.location.start.line + 1;
|
|
155
|
+
complexity += Math.floor(lineCount / 10);
|
|
156
|
+
}
|
|
157
|
+
return complexity;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Check for modification patterns (Open/Closed Principle)
|
|
161
|
+
*/
|
|
162
|
+
hasModificationPatterns(cls, ast, adapter, sourceCode) {
|
|
163
|
+
// Look for switch statements or if-else chains that check types
|
|
164
|
+
const classNode = this.findNodeByLocation(ast.root, cls.location.start);
|
|
165
|
+
if (!classNode)
|
|
166
|
+
return false;
|
|
167
|
+
let hasTypeChecking = false;
|
|
168
|
+
this.walkAST(classNode, node => {
|
|
169
|
+
// Check for switch statements
|
|
170
|
+
if (node.type.includes('Switch')) {
|
|
171
|
+
hasTypeChecking = true;
|
|
172
|
+
}
|
|
173
|
+
// Check for instanceof chains
|
|
174
|
+
if (node.type.includes('Binary') && adapter.getNodeText(node, sourceCode).includes('instanceof')) {
|
|
175
|
+
hasTypeChecking = true;
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
return hasTypeChecking;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check Liskov Substitution Principle
|
|
182
|
+
*/
|
|
183
|
+
checkLiskovSubstitution(cls, ast, adapter) {
|
|
184
|
+
const violations = [];
|
|
185
|
+
// Check if class overrides parent methods with incompatible signatures
|
|
186
|
+
// This would require more sophisticated type analysis
|
|
187
|
+
// For now, we'll check basic patterns
|
|
188
|
+
for (const method of cls.methods) {
|
|
189
|
+
if (method.name === 'constructor')
|
|
190
|
+
continue;
|
|
191
|
+
// Check for methods that throw exceptions when parent doesn't
|
|
192
|
+
const methodNode = this.findNodeByLocation(ast.root, method.location.start);
|
|
193
|
+
if (methodNode) {
|
|
194
|
+
let hasThrow = false;
|
|
195
|
+
this.walkAST(methodNode, node => {
|
|
196
|
+
if (node.type.includes('Throw')) {
|
|
197
|
+
hasThrow = true;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
if (hasThrow) {
|
|
201
|
+
violations.push(this.createViolation(ast.filePath, method.location.start, `Method "${cls.name}.${method.name}" throws exceptions. Ensure this doesn't violate parent class contract.`, 'suggestion', 'liskov-substitution'));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return violations;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Check Dependency Inversion Principle
|
|
209
|
+
*/
|
|
210
|
+
checkDependencyInversion(cls, ast, adapter, sourceCode) {
|
|
211
|
+
const violations = [];
|
|
212
|
+
console.error(`[DEBUG] SOLID: checkDependencyInversion called for class: ${cls.name}`);
|
|
213
|
+
// Check for direct instantiation of dependencies
|
|
214
|
+
const classNode = this.findNodeByLocation(ast.root, cls.location.start);
|
|
215
|
+
if (!classNode) {
|
|
216
|
+
console.error(`[DEBUG] SOLID: Could not find class node for ${cls.name}`);
|
|
217
|
+
return violations;
|
|
218
|
+
}
|
|
219
|
+
let hasDirectInstantiation = false;
|
|
220
|
+
let concreteImports = 0;
|
|
221
|
+
// Count concrete class imports vs interface imports
|
|
222
|
+
const imports = adapter.extractImports(ast);
|
|
223
|
+
for (const imp of imports) {
|
|
224
|
+
if (imp.source.includes('/') && !imp.source.includes('interface') && !imp.source.includes('types')) {
|
|
225
|
+
concreteImports++;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
this.walkAST(classNode, node => {
|
|
229
|
+
// Check for 'new' expressions
|
|
230
|
+
if (node.type.includes('New')) {
|
|
231
|
+
const text = adapter.getNodeText(node, sourceCode);
|
|
232
|
+
// Ignore primitive constructors like Date, Array, etc.
|
|
233
|
+
if (!this.isPrimitiveConstructor(text)) {
|
|
234
|
+
hasDirectInstantiation = true;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
if (hasDirectInstantiation) {
|
|
239
|
+
violations.push(this.createViolation(ast.filePath, cls.location.start, `Class "${cls.name}" directly instantiates dependencies. Consider dependency injection.`, 'suggestion', 'dependency-inversion'));
|
|
240
|
+
}
|
|
241
|
+
if (concreteImports > 3) {
|
|
242
|
+
violations.push(this.createViolation(ast.filePath, cls.location.start, `Class "${cls.name}" imports ${concreteImports} concrete implementations. Consider depending on abstractions.`, 'suggestion', 'dependency-inversion'));
|
|
243
|
+
}
|
|
244
|
+
return violations;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Helper methods
|
|
248
|
+
*/
|
|
249
|
+
isTestFile(filePath) {
|
|
250
|
+
const testPatterns = [
|
|
251
|
+
/\.test\.[jt]sx?$/,
|
|
252
|
+
/\.spec\.[jt]sx?$/,
|
|
253
|
+
/__tests__\//,
|
|
254
|
+
/test\//,
|
|
255
|
+
/tests\//
|
|
256
|
+
];
|
|
257
|
+
return testPatterns.some(pattern => pattern.test(filePath));
|
|
258
|
+
}
|
|
259
|
+
isPrimitiveConstructor(text) {
|
|
260
|
+
const primitives = ['Date', 'Array', 'Object', 'Map', 'Set', 'Promise', 'Error', 'RegExp'];
|
|
261
|
+
return primitives.some(p => text.includes(`new ${p}`));
|
|
262
|
+
}
|
|
263
|
+
findNodeByLocation(root, location) {
|
|
264
|
+
const queue = [root];
|
|
265
|
+
while (queue.length > 0) {
|
|
266
|
+
const node = queue.shift();
|
|
267
|
+
if (node.location.start.line === location.line &&
|
|
268
|
+
node.location.start.column === location.column) {
|
|
269
|
+
return node;
|
|
270
|
+
}
|
|
271
|
+
if (node.children) {
|
|
272
|
+
queue.push(...node.children);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
walkAST(node, callback) {
|
|
278
|
+
callback(node);
|
|
279
|
+
if (node.children) {
|
|
280
|
+
for (const child of node.children) {
|
|
281
|
+
this.walkAST(child, callback);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=UniversalSOLIDAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UniversalSOLIDAnalyzer.js","sourceRoot":"","sources":["../../../src/analyzers/universal/UniversalSOLIDAnalyzer.ts"],"names":[],"mappings":"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"}
|