code-auditor-mcp 1.21.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/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 +20 -8
- 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.js +2 -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-tools-shared.d.ts +3 -0
- package/dist/mcp-tools-shared.d.ts.map +1 -1
- package/dist/mcp-tools-shared.js +123 -2
- package/dist/mcp-tools-shared.js.map +1 -1
- package/dist/mcp.js +3 -0
- package/dist/mcp.js.map +1 -1
- 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 +1 -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/package.json +19 -20
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go Language Adapter
|
|
3
|
+
*
|
|
4
|
+
* Provides Go language support through the LanguageAdapter interface.
|
|
5
|
+
* Uses the Go-based analyzer as a child process for proper AST analysis.
|
|
6
|
+
*/
|
|
7
|
+
import { LanguageAdapter, AST, ASTNode, NodePattern, FunctionInfo, ClassInfo, ImportInfo, ExportInfo, SourceLocation } from './LanguageAdapter.js';
|
|
8
|
+
export declare class GoAdapter implements LanguageAdapter {
|
|
9
|
+
readonly name = "go";
|
|
10
|
+
readonly extensions: string[];
|
|
11
|
+
private goAnalyzerProcess;
|
|
12
|
+
private requestId;
|
|
13
|
+
private pendingRequests;
|
|
14
|
+
private goExecutablePath;
|
|
15
|
+
private logFile;
|
|
16
|
+
private isInitialized;
|
|
17
|
+
private initializationPromise;
|
|
18
|
+
private jsonBuffer;
|
|
19
|
+
constructor(goExecutablePath?: string);
|
|
20
|
+
private writeLog;
|
|
21
|
+
private registerProcessCleanup;
|
|
22
|
+
parse(file: string, content: string): Promise<AST>;
|
|
23
|
+
private ensureInitialized;
|
|
24
|
+
private initializeProcess;
|
|
25
|
+
private analyzeFileWithPersistentProcess;
|
|
26
|
+
private analyzeFile;
|
|
27
|
+
private ensureGoAnalyzer;
|
|
28
|
+
private sendPing;
|
|
29
|
+
private convertToAST;
|
|
30
|
+
supportsFile(filePath: string): boolean;
|
|
31
|
+
findNodes(ast: AST, pattern: NodePattern): ASTNode[];
|
|
32
|
+
private createFunctionNode;
|
|
33
|
+
private createStructNode;
|
|
34
|
+
extractFunctions(ast: AST): FunctionInfo[];
|
|
35
|
+
extractClasses(ast: AST): ClassInfo[];
|
|
36
|
+
extractImports(ast: AST): ImportInfo[];
|
|
37
|
+
extractExports(ast: AST): ExportInfo[];
|
|
38
|
+
getParent(node: ASTNode): ASTNode | null;
|
|
39
|
+
getChildren(node: ASTNode): ASTNode[];
|
|
40
|
+
getNodeType(node: ASTNode): string;
|
|
41
|
+
getNodeText(node: ASTNode): string;
|
|
42
|
+
getNodeLocation(node: ASTNode): SourceLocation;
|
|
43
|
+
getNodeName(node: ASTNode): string | null;
|
|
44
|
+
isClass(node: ASTNode): boolean;
|
|
45
|
+
isFunction(node: ASTNode): boolean;
|
|
46
|
+
isMethod(node: ASTNode): boolean;
|
|
47
|
+
isInterface(node: ASTNode): boolean;
|
|
48
|
+
isImport(node: ASTNode): boolean;
|
|
49
|
+
isVariable(node: ASTNode): boolean;
|
|
50
|
+
private processJsonBuffer;
|
|
51
|
+
cleanup(): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=GoAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GoAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/GoAdapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,EACL,eAAe,EACf,GAAG,EACH,OAAO,EACP,WAAW,EACX,YAAY,EACZ,SAAS,EACT,UAAU,EACV,UAAU,EACV,cAAc,EAIf,MAAM,sBAAsB,CAAC;AAqE9B,qBAAa,SAAU,YAAW,eAAe;IAC/C,QAAQ,CAAC,IAAI,QAAQ;IACrB,QAAQ,CAAC,UAAU,WAAW;IAE9B,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,eAAe,CAGlB;IAEL,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,qBAAqB,CAA8B;IAC3D,OAAO,CAAC,UAAU,CAAM;gBAEZ,gBAAgB,GAAE,MAAa;IAmB3C,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,sBAAsB;IAgBxB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;YAgD1C,iBAAiB;YAajB,iBAAiB;YAWjB,gCAAgC;YAsDhC,WAAW;YAoEX,gBAAgB;YAiGhB,QAAQ;IAsBtB,OAAO,CAAC,YAAY;IAmEpB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAKvC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,EAAE;IAmBpD,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,gBAAgB;IAYxB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,YAAY,EAAE;IAuC1C,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,EAAE;IAoBrC,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,EAAE;IAKtC,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,EAAE;IAMtC,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI;IAKxC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,EAAE;IAMrC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM;IAIlC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM;IASlC,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc;IAI9C,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAMzC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAI/B,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAIlC,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAIhC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAInC,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAIhC,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAIlC,OAAO,CAAC,iBAAiB;IAiDnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAuB/B"}
|
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go Language Adapter
|
|
3
|
+
*
|
|
4
|
+
* Provides Go language support through the LanguageAdapter interface.
|
|
5
|
+
* Uses the Go-based analyzer as a child process for proper AST analysis.
|
|
6
|
+
*/
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
// ES module equivalent of __dirname
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
export class GoAdapter {
|
|
15
|
+
name = 'go';
|
|
16
|
+
extensions = ['.go'];
|
|
17
|
+
goAnalyzerProcess = null;
|
|
18
|
+
requestId = 0;
|
|
19
|
+
pendingRequests = new Map();
|
|
20
|
+
goExecutablePath;
|
|
21
|
+
logFile;
|
|
22
|
+
isInitialized = false;
|
|
23
|
+
initializationPromise = null;
|
|
24
|
+
jsonBuffer = '';
|
|
25
|
+
constructor(goExecutablePath = 'go') {
|
|
26
|
+
this.goExecutablePath = goExecutablePath;
|
|
27
|
+
// Create log file for Go child process debugging
|
|
28
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
29
|
+
this.logFile = path.join(process.cwd(), `go-analyzer-${timestamp}.log`);
|
|
30
|
+
console.error(`[DEBUG] Go: Initialized with executable path: ${this.goExecutablePath}`);
|
|
31
|
+
console.error(`[DEBUG] Go: Child process logs will be written to: ${this.logFile}`);
|
|
32
|
+
// Initialize log file
|
|
33
|
+
this.writeLog('=== Go Analyzer Process Log Started ===');
|
|
34
|
+
this.writeLog(`Go executable path: ${this.goExecutablePath}`);
|
|
35
|
+
this.writeLog(`Path is absolute: ${path.isAbsolute(this.goExecutablePath)}`);
|
|
36
|
+
// Register cleanup on process exit
|
|
37
|
+
this.registerProcessCleanup();
|
|
38
|
+
}
|
|
39
|
+
writeLog(message) {
|
|
40
|
+
try {
|
|
41
|
+
const timestamp = new Date().toISOString();
|
|
42
|
+
const logEntry = `[${timestamp}] ${message}\n`;
|
|
43
|
+
fs.appendFileSync(this.logFile, logEntry);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error('[DEBUG] Go: Failed to write to log file:', error);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
registerProcessCleanup() {
|
|
50
|
+
// Cleanup on various exit signals
|
|
51
|
+
const cleanup = () => {
|
|
52
|
+
console.error('[DEBUG] Go: Process cleanup triggered');
|
|
53
|
+
this.writeLog('Process cleanup triggered by exit signal');
|
|
54
|
+
this.cleanup();
|
|
55
|
+
};
|
|
56
|
+
process.on('SIGINT', cleanup);
|
|
57
|
+
process.on('SIGTERM', cleanup);
|
|
58
|
+
process.on('exit', cleanup);
|
|
59
|
+
process.on('beforeExit', cleanup);
|
|
60
|
+
this.writeLog('Registered process cleanup handlers');
|
|
61
|
+
}
|
|
62
|
+
async parse(file, content) {
|
|
63
|
+
console.error(`[DEBUG] Go: Parsing file using persistent child process: ${file} (content length: ${content.length})`);
|
|
64
|
+
this.writeLog(`parse() called for ${file}, content length: ${content.length}`);
|
|
65
|
+
try {
|
|
66
|
+
// Ensure the process is initialized (lazy initialization)
|
|
67
|
+
await this.ensureInitialized();
|
|
68
|
+
// Use persistent process to analyze the file
|
|
69
|
+
const result = await this.analyzeFileWithPersistentProcess(file, content);
|
|
70
|
+
console.error(`[DEBUG] Go: Child process returned result with ${result.Violations?.length || 0} violations and ${result.IndexEntries?.length || 0} entities`);
|
|
71
|
+
this.writeLog(`Child process returned ${result.Violations?.length || 0} violations and ${result.IndexEntries?.length || 0} entities`);
|
|
72
|
+
// Convert Go analysis result to our AST format
|
|
73
|
+
const ast = this.convertToAST(file, content, result);
|
|
74
|
+
console.error(`[DEBUG] Go: Successfully parsed ${file} - AST conversion complete`);
|
|
75
|
+
this.writeLog(`Successfully parsed ${file} - AST conversion complete`);
|
|
76
|
+
return ast;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(`[DEBUG] Go: Error parsing ${file}:`, error);
|
|
80
|
+
console.error(`[DEBUG] Go: Error stack:`, error.stack);
|
|
81
|
+
// Return a minimal AST with error information
|
|
82
|
+
const lines = content.split('\n');
|
|
83
|
+
return {
|
|
84
|
+
root: {
|
|
85
|
+
type: 'SourceFile',
|
|
86
|
+
range: [0, content.length],
|
|
87
|
+
location: {
|
|
88
|
+
start: { line: 1, column: 1 },
|
|
89
|
+
end: { line: lines.length, column: lines[lines.length - 1]?.length || 1 }
|
|
90
|
+
},
|
|
91
|
+
raw: { error: error.message }
|
|
92
|
+
},
|
|
93
|
+
language: this.name,
|
|
94
|
+
filePath: file,
|
|
95
|
+
errors: [{
|
|
96
|
+
message: error.message,
|
|
97
|
+
location: { start: { line: 1, column: 1 }, end: { line: 1, column: 1 } },
|
|
98
|
+
severity: 'error'
|
|
99
|
+
}]
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async ensureInitialized() {
|
|
104
|
+
if (this.isInitialized && this.goAnalyzerProcess) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (this.initializationPromise) {
|
|
108
|
+
return this.initializationPromise;
|
|
109
|
+
}
|
|
110
|
+
this.initializationPromise = this.initializeProcess();
|
|
111
|
+
return this.initializationPromise;
|
|
112
|
+
}
|
|
113
|
+
async initializeProcess() {
|
|
114
|
+
try {
|
|
115
|
+
await this.ensureGoAnalyzer();
|
|
116
|
+
this.isInitialized = true;
|
|
117
|
+
this.writeLog('Persistent Go analyzer process initialized successfully');
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
this.initializationPromise = null;
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async analyzeFileWithPersistentProcess(file, content) {
|
|
125
|
+
if (!this.goAnalyzerProcess) {
|
|
126
|
+
throw new Error('Go analyzer process not available');
|
|
127
|
+
}
|
|
128
|
+
const options = {
|
|
129
|
+
Analyzers: ['solid', 'imports'],
|
|
130
|
+
MinSeverity: 'info',
|
|
131
|
+
IncludeIndexing: true
|
|
132
|
+
};
|
|
133
|
+
const request = {
|
|
134
|
+
method: 'analyzeContent',
|
|
135
|
+
params: {
|
|
136
|
+
file: file,
|
|
137
|
+
content: content,
|
|
138
|
+
options: options
|
|
139
|
+
},
|
|
140
|
+
id: ++this.requestId
|
|
141
|
+
};
|
|
142
|
+
this.writeLog(`Sending analysis request for ${file} (using content instead of file path)`);
|
|
143
|
+
return new Promise((resolve, reject) => {
|
|
144
|
+
// Set timeout for request
|
|
145
|
+
const timeout = setTimeout(() => {
|
|
146
|
+
this.pendingRequests.delete(request.id);
|
|
147
|
+
reject(new Error(`Go analyzer request timeout after 10 seconds`));
|
|
148
|
+
}, 10000);
|
|
149
|
+
this.pendingRequests.set(request.id, {
|
|
150
|
+
resolve: (result) => {
|
|
151
|
+
clearTimeout(timeout);
|
|
152
|
+
resolve(result);
|
|
153
|
+
},
|
|
154
|
+
reject: (error) => {
|
|
155
|
+
clearTimeout(timeout);
|
|
156
|
+
reject(error);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
const requestLine = JSON.stringify(request) + '\n';
|
|
160
|
+
this.writeLog(`Sending JSON-RPC request: ${requestLine.trim()}`);
|
|
161
|
+
try {
|
|
162
|
+
this.goAnalyzerProcess.stdin?.write(requestLine);
|
|
163
|
+
this.writeLog(`Request sent successfully to stdin`);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
this.writeLog(`Error writing to stdin: ${error.message}`);
|
|
167
|
+
reject(error);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
async analyzeFile(file) {
|
|
172
|
+
console.error(`[DEBUG] Go: analyzeFile called for: ${file}`);
|
|
173
|
+
try {
|
|
174
|
+
await this.ensureGoAnalyzer();
|
|
175
|
+
console.error(`[DEBUG] Go: Go analyzer ensured successfully`);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
console.error(`[DEBUG] Go: Failed to ensure analyzer:`, error);
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
const options = {
|
|
182
|
+
Analyzers: ['solid', 'imports'],
|
|
183
|
+
MinSeverity: 'info',
|
|
184
|
+
IncludeIndexing: true
|
|
185
|
+
};
|
|
186
|
+
const request = {
|
|
187
|
+
method: 'analyze',
|
|
188
|
+
params: {
|
|
189
|
+
files: [file],
|
|
190
|
+
options: options
|
|
191
|
+
},
|
|
192
|
+
id: ++this.requestId
|
|
193
|
+
};
|
|
194
|
+
console.error(`[DEBUG] Go: Created request with ID ${request.id}`);
|
|
195
|
+
return new Promise((resolve, reject) => {
|
|
196
|
+
// Set timeout for request
|
|
197
|
+
const timeout = setTimeout(() => {
|
|
198
|
+
this.pendingRequests.delete(request.id);
|
|
199
|
+
reject(new Error(`Go analyzer request timeout after 10 seconds`));
|
|
200
|
+
}, 10000);
|
|
201
|
+
this.pendingRequests.set(request.id, {
|
|
202
|
+
resolve: (result) => {
|
|
203
|
+
clearTimeout(timeout);
|
|
204
|
+
resolve(result);
|
|
205
|
+
},
|
|
206
|
+
reject: (error) => {
|
|
207
|
+
clearTimeout(timeout);
|
|
208
|
+
reject(error);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
if (!this.goAnalyzerProcess) {
|
|
212
|
+
reject(new Error('Go analyzer process not available after ensure'));
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
// Send the request
|
|
216
|
+
const requestLine = JSON.stringify(request) + '\n';
|
|
217
|
+
console.error(`[DEBUG] Go: Sending request to analyzer: ${requestLine.trim()}`);
|
|
218
|
+
this.writeLog(`Sending JSON-RPC request: ${requestLine.trim()}`);
|
|
219
|
+
try {
|
|
220
|
+
this.goAnalyzerProcess.stdin?.write(requestLine);
|
|
221
|
+
console.error(`[DEBUG] Go: Request sent successfully`);
|
|
222
|
+
this.writeLog(`Request sent successfully to stdin`);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
console.error(`[DEBUG] Go: Error writing to stdin:`, error);
|
|
226
|
+
this.writeLog(`Error writing to stdin: ${error.message}`);
|
|
227
|
+
reject(error);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
async ensureGoAnalyzer() {
|
|
232
|
+
if (this.goAnalyzerProcess) {
|
|
233
|
+
console.error('[DEBUG] Go: Analyzer process already running');
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
console.error('[DEBUG] Go: Starting Go analyzer process...');
|
|
237
|
+
// Path to the Go analyzer binary
|
|
238
|
+
// __dirname points to dist/adapters, so we need to go to src/languages/go
|
|
239
|
+
const goAnalyzerPath = path.join(__dirname, '../../src/languages/go/main.go');
|
|
240
|
+
const goModPath = path.dirname(goAnalyzerPath);
|
|
241
|
+
console.error(`[DEBUG] Go: Go analyzer path: ${goAnalyzerPath}`);
|
|
242
|
+
console.error(`[DEBUG] Go: Go mod path: ${goModPath}`);
|
|
243
|
+
try {
|
|
244
|
+
// Start the Go analyzer as a child process
|
|
245
|
+
console.error(`[DEBUG] Go: Spawning ${this.goExecutablePath} run main.go...`);
|
|
246
|
+
this.writeLog(`Starting Go analyzer: ${this.goExecutablePath} run main.go`);
|
|
247
|
+
this.writeLog(`Working directory: ${goModPath}`);
|
|
248
|
+
this.goAnalyzerProcess = spawn(this.goExecutablePath, ['run', 'main.go'], {
|
|
249
|
+
cwd: goModPath,
|
|
250
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
251
|
+
env: process.env // Inherit full environment including PATH
|
|
252
|
+
});
|
|
253
|
+
console.error(`[DEBUG] Go: Process spawned with PID: ${this.goAnalyzerProcess.pid}`);
|
|
254
|
+
this.writeLog(`Process spawned with PID: ${this.goAnalyzerProcess.pid}`);
|
|
255
|
+
// Handle stdout (JSON-RPC responses) with proper buffering for large responses
|
|
256
|
+
this.goAnalyzerProcess.stdout?.on('data', (data) => {
|
|
257
|
+
const dataStr = data.toString();
|
|
258
|
+
console.error(`[DEBUG] Go: Raw stdout chunk (${dataStr.length} chars): ${dataStr.substring(0, 200)}...`);
|
|
259
|
+
this.writeLog(`STDOUT Chunk (${dataStr.length} chars): ${dataStr.substring(0, 200)}${dataStr.length > 200 ? '...[TRUNCATED]' : ''}`);
|
|
260
|
+
// Add to JSON buffer
|
|
261
|
+
this.jsonBuffer += dataStr;
|
|
262
|
+
// Process complete JSON objects from buffer
|
|
263
|
+
this.processJsonBuffer();
|
|
264
|
+
});
|
|
265
|
+
// Handle stderr (debug output)
|
|
266
|
+
this.goAnalyzerProcess.stderr?.on('data', (data) => {
|
|
267
|
+
const stderrStr = data.toString().trim();
|
|
268
|
+
console.error(`[GoAnalyzer] ${stderrStr}`);
|
|
269
|
+
this.writeLog(`STDERR: ${stderrStr}`);
|
|
270
|
+
});
|
|
271
|
+
// Handle process exit
|
|
272
|
+
this.goAnalyzerProcess.on('exit', (code) => {
|
|
273
|
+
console.error(`[DEBUG] Go: Analyzer process exited with code ${code}`);
|
|
274
|
+
this.writeLog(`Process exited with code: ${code}`);
|
|
275
|
+
this.goAnalyzerProcess = null;
|
|
276
|
+
// Reject all pending requests
|
|
277
|
+
for (const [id, pending] of this.pendingRequests) {
|
|
278
|
+
pending.reject(new Error(`Go analyzer process exited with code ${code}`));
|
|
279
|
+
}
|
|
280
|
+
this.pendingRequests.clear();
|
|
281
|
+
});
|
|
282
|
+
// Handle process error
|
|
283
|
+
this.goAnalyzerProcess.on('error', (error) => {
|
|
284
|
+
console.error(`[DEBUG] Go: Process error:`, error);
|
|
285
|
+
this.writeLog(`Process error: ${JSON.stringify(error)}`);
|
|
286
|
+
if (error.code === 'ENOENT') {
|
|
287
|
+
console.error(`[DEBUG] Go: 'go' command not found. Is Go installed and in your system's PATH?`);
|
|
288
|
+
this.writeLog(`ENOENT: Go command not found`);
|
|
289
|
+
}
|
|
290
|
+
this.goAnalyzerProcess = null;
|
|
291
|
+
// Reject all pending requests
|
|
292
|
+
for (const [id, pending] of this.pendingRequests) {
|
|
293
|
+
pending.reject(new Error(`Go command not found: ${error.message}`));
|
|
294
|
+
}
|
|
295
|
+
this.pendingRequests.clear();
|
|
296
|
+
});
|
|
297
|
+
// Wait a bit for the process to start
|
|
298
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
299
|
+
// Test the connection
|
|
300
|
+
console.error('[DEBUG] Go: Testing connection with ping...');
|
|
301
|
+
const pingResult = await this.sendPing();
|
|
302
|
+
console.error('[DEBUG] Go: Analyzer ready, ping result:', pingResult);
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
console.error('[DEBUG] Go: Failed to start analyzer process:', error);
|
|
306
|
+
console.error('[DEBUG] Go: Error stack:', error.stack);
|
|
307
|
+
throw new Error(`Failed to start Go analyzer: ${error.message}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async sendPing() {
|
|
311
|
+
const request = {
|
|
312
|
+
method: 'ping',
|
|
313
|
+
params: {},
|
|
314
|
+
id: ++this.requestId
|
|
315
|
+
};
|
|
316
|
+
return new Promise((resolve, reject) => {
|
|
317
|
+
this.pendingRequests.set(request.id, { resolve, reject });
|
|
318
|
+
if (!this.goAnalyzerProcess) {
|
|
319
|
+
this.writeLog('Ping failed: Go analyzer process not available');
|
|
320
|
+
reject(new Error('Go analyzer process not available'));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
const requestLine = JSON.stringify(request) + '\n';
|
|
324
|
+
this.writeLog(`Sending ping request: ${requestLine.trim()}`);
|
|
325
|
+
this.goAnalyzerProcess.stdin?.write(requestLine);
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
convertToAST(file, content, result) {
|
|
329
|
+
console.error(`[DEBUG] Go: convertToAST called for: ${file}`);
|
|
330
|
+
this.writeLog(`convertToAST() called for ${file}`);
|
|
331
|
+
const lines = content.split('\n');
|
|
332
|
+
// Log the raw result we got from Go analyzer
|
|
333
|
+
console.error(`[DEBUG] Go: Raw result from Go analyzer:`, {
|
|
334
|
+
violations: result.Violations?.length || 0,
|
|
335
|
+
indexEntries: result.IndexEntries?.length || 0,
|
|
336
|
+
errors: result.Errors?.length || 0
|
|
337
|
+
});
|
|
338
|
+
this.writeLog(`Raw result: ${result.Violations?.length || 0} violations, ${result.IndexEntries?.length || 0} index entries, ${result.Errors?.length || 0} errors`);
|
|
339
|
+
if (result.IndexEntries) {
|
|
340
|
+
const functionEntries = result.IndexEntries.filter(e => e.Type === 'function');
|
|
341
|
+
const structEntries = result.IndexEntries.filter(e => e.Type === 'struct');
|
|
342
|
+
const interfaceEntries = result.IndexEntries.filter(e => e.Type === 'interface');
|
|
343
|
+
console.error(`[DEBUG] Go: Filtering IndexEntries - functions: ${functionEntries.length}, structs: ${structEntries.length}, interfaces: ${interfaceEntries.length}`);
|
|
344
|
+
this.writeLog(`Filtering IndexEntries - functions: ${functionEntries.length}, structs: ${structEntries.length}, interfaces: ${interfaceEntries.length}`);
|
|
345
|
+
if (functionEntries.length > 0) {
|
|
346
|
+
console.error(`[DEBUG] Go: Sample function entry:`, functionEntries[0]);
|
|
347
|
+
this.writeLog(`Sample function entry: ${JSON.stringify(functionEntries[0])}`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Convert Go analysis result to our unified AST format
|
|
351
|
+
const entities = {
|
|
352
|
+
functions: result.IndexEntries?.filter(e => e.Type === 'function') || [],
|
|
353
|
+
structs: result.IndexEntries?.filter(e => e.Type === 'struct') || [],
|
|
354
|
+
interfaces: result.IndexEntries?.filter(e => e.Type === 'interface') || [],
|
|
355
|
+
violations: result.Violations || []
|
|
356
|
+
};
|
|
357
|
+
console.error(`[DEBUG] Go: Final entities object:`, {
|
|
358
|
+
functions: entities.functions.length,
|
|
359
|
+
structs: entities.structs.length,
|
|
360
|
+
interfaces: entities.interfaces.length,
|
|
361
|
+
violations: entities.violations.length
|
|
362
|
+
});
|
|
363
|
+
this.writeLog(`Final entities: ${entities.functions.length} functions, ${entities.structs.length} structs, ${entities.interfaces.length} interfaces, ${entities.violations.length} violations`);
|
|
364
|
+
return {
|
|
365
|
+
root: {
|
|
366
|
+
type: 'SourceFile',
|
|
367
|
+
range: [0, content.length],
|
|
368
|
+
location: {
|
|
369
|
+
start: { line: 1, column: 1 },
|
|
370
|
+
end: { line: lines.length, column: lines[lines.length - 1]?.length || 1 }
|
|
371
|
+
},
|
|
372
|
+
raw: entities
|
|
373
|
+
},
|
|
374
|
+
language: this.name,
|
|
375
|
+
filePath: file,
|
|
376
|
+
errors: result.Errors?.map(err => ({
|
|
377
|
+
message: err.Message,
|
|
378
|
+
location: {
|
|
379
|
+
start: { line: err.Line, column: 1 },
|
|
380
|
+
end: { line: err.Line, column: 1 }
|
|
381
|
+
},
|
|
382
|
+
severity: 'error'
|
|
383
|
+
})) || []
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
supportsFile(filePath) {
|
|
387
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
388
|
+
return this.extensions.includes(ext);
|
|
389
|
+
}
|
|
390
|
+
findNodes(ast, pattern) {
|
|
391
|
+
const results = [];
|
|
392
|
+
const entities = ast.root.raw;
|
|
393
|
+
if (pattern.type === 'function' && entities.functions) {
|
|
394
|
+
for (const func of entities.functions) {
|
|
395
|
+
results.push(this.createFunctionNode(func));
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (pattern.type === 'struct' && entities.structs) {
|
|
399
|
+
for (const struct of entities.structs) {
|
|
400
|
+
results.push(this.createStructNode(struct));
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return results;
|
|
404
|
+
}
|
|
405
|
+
createFunctionNode(func) {
|
|
406
|
+
return {
|
|
407
|
+
type: 'function',
|
|
408
|
+
range: [0, 0], // Simplified
|
|
409
|
+
location: {
|
|
410
|
+
start: { line: func.StartLine, column: 1 },
|
|
411
|
+
end: { line: func.EndLine, column: 1 }
|
|
412
|
+
},
|
|
413
|
+
raw: func
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
createStructNode(struct) {
|
|
417
|
+
return {
|
|
418
|
+
type: 'struct',
|
|
419
|
+
range: [0, 0], // Simplified
|
|
420
|
+
location: {
|
|
421
|
+
start: { line: struct.StartLine, column: 1 },
|
|
422
|
+
end: { line: struct.EndLine, column: 1 }
|
|
423
|
+
},
|
|
424
|
+
raw: struct
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
extractFunctions(ast) {
|
|
428
|
+
console.error(`[DEBUG] Go: extractFunctions called for: ${ast.filePath}`);
|
|
429
|
+
this.writeLog(`extractFunctions() called for ${ast.filePath}`);
|
|
430
|
+
const entities = ast.root.raw;
|
|
431
|
+
console.error(`[DEBUG] Go: Raw entities:`, JSON.stringify(entities, null, 2).substring(0, 500) + '...');
|
|
432
|
+
this.writeLog(`Raw entities keys: ${Object.keys(entities || {})}`);
|
|
433
|
+
if (!entities.functions) {
|
|
434
|
+
console.error(`[DEBUG] Go: No functions found in entities for ${ast.filePath}`);
|
|
435
|
+
this.writeLog(`No functions found in entities for ${ast.filePath}`);
|
|
436
|
+
return [];
|
|
437
|
+
}
|
|
438
|
+
console.error(`[DEBUG] Go: Found ${entities.functions.length} functions in ${ast.filePath}`);
|
|
439
|
+
this.writeLog(`Found ${entities.functions.length} functions in ${ast.filePath}`);
|
|
440
|
+
return entities.functions.map((func) => ({
|
|
441
|
+
name: func.Name,
|
|
442
|
+
location: {
|
|
443
|
+
start: { line: func.StartLine, column: 1 },
|
|
444
|
+
end: { line: func.EndLine, column: 1 }
|
|
445
|
+
},
|
|
446
|
+
parameters: (func.Parameters || []).map((param) => ({
|
|
447
|
+
name: param,
|
|
448
|
+
type: 'unknown', // Could be enhanced
|
|
449
|
+
optional: false,
|
|
450
|
+
defaultValue: undefined
|
|
451
|
+
})),
|
|
452
|
+
returnType: func.ReturnType || undefined,
|
|
453
|
+
isAsync: false, // Go doesn't have async/await
|
|
454
|
+
isExported: func.IsExported,
|
|
455
|
+
isMethod: func.Type === 'method',
|
|
456
|
+
className: undefined, // Go uses receivers, not classes
|
|
457
|
+
complexity: func.Complexity || 1,
|
|
458
|
+
lineCount: func.EndLine - func.StartLine + 1
|
|
459
|
+
}));
|
|
460
|
+
}
|
|
461
|
+
extractClasses(ast) {
|
|
462
|
+
const entities = ast.root.raw;
|
|
463
|
+
if (!entities.structs)
|
|
464
|
+
return [];
|
|
465
|
+
// In Go, structs are the closest equivalent to classes
|
|
466
|
+
return entities.structs.map((struct) => ({
|
|
467
|
+
name: struct.Name,
|
|
468
|
+
location: {
|
|
469
|
+
start: { line: struct.StartLine, column: 1 },
|
|
470
|
+
end: { line: struct.EndLine, column: 1 }
|
|
471
|
+
},
|
|
472
|
+
methods: [], // Methods would be found separately
|
|
473
|
+
properties: [], // Could be enhanced to extract fields
|
|
474
|
+
extends: [], // Go uses composition, not inheritance
|
|
475
|
+
implements: [], // Could be enhanced
|
|
476
|
+
isExported: struct.IsExported,
|
|
477
|
+
isAbstract: false // Go doesn't have abstract structs
|
|
478
|
+
}));
|
|
479
|
+
}
|
|
480
|
+
extractImports(ast) {
|
|
481
|
+
// Could be enhanced to extract import information from the Go analyzer
|
|
482
|
+
return [];
|
|
483
|
+
}
|
|
484
|
+
extractExports(ast) {
|
|
485
|
+
// Could be enhanced to extract export information from the Go analyzer
|
|
486
|
+
return [];
|
|
487
|
+
}
|
|
488
|
+
// AST Navigation
|
|
489
|
+
getParent(node) {
|
|
490
|
+
// Simplified implementation - could be enhanced with proper parent tracking
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
getChildren(node) {
|
|
494
|
+
// Simplified implementation - could be enhanced with proper child extraction
|
|
495
|
+
return [];
|
|
496
|
+
}
|
|
497
|
+
// Node Information
|
|
498
|
+
getNodeType(node) {
|
|
499
|
+
return node.type;
|
|
500
|
+
}
|
|
501
|
+
getNodeText(node) {
|
|
502
|
+
// Extract text representation from the Go entity
|
|
503
|
+
const entity = node.raw;
|
|
504
|
+
if (entity.Name) {
|
|
505
|
+
return entity.Name;
|
|
506
|
+
}
|
|
507
|
+
return node.type;
|
|
508
|
+
}
|
|
509
|
+
getNodeLocation(node) {
|
|
510
|
+
return node.location;
|
|
511
|
+
}
|
|
512
|
+
getNodeName(node) {
|
|
513
|
+
const entity = node.raw;
|
|
514
|
+
return entity.Name || null;
|
|
515
|
+
}
|
|
516
|
+
// Pattern Matching
|
|
517
|
+
isClass(node) {
|
|
518
|
+
return node.type === 'struct';
|
|
519
|
+
}
|
|
520
|
+
isFunction(node) {
|
|
521
|
+
return node.type === 'function';
|
|
522
|
+
}
|
|
523
|
+
isMethod(node) {
|
|
524
|
+
return node.type === 'function' && node.raw.Type === 'method';
|
|
525
|
+
}
|
|
526
|
+
isInterface(node) {
|
|
527
|
+
return node.type === 'interface';
|
|
528
|
+
}
|
|
529
|
+
isImport(node) {
|
|
530
|
+
return node.type === 'import';
|
|
531
|
+
}
|
|
532
|
+
isVariable(node) {
|
|
533
|
+
return node.type === 'variable';
|
|
534
|
+
}
|
|
535
|
+
processJsonBuffer() {
|
|
536
|
+
// Look for complete JSON objects (each ends with newline)
|
|
537
|
+
const lines = this.jsonBuffer.split('\n');
|
|
538
|
+
// Keep the last partial line in buffer (it might be incomplete)
|
|
539
|
+
this.jsonBuffer = lines.pop() || '';
|
|
540
|
+
// Process complete lines
|
|
541
|
+
for (const line of lines) {
|
|
542
|
+
const trimmed = line.trim();
|
|
543
|
+
if (!trimmed)
|
|
544
|
+
continue;
|
|
545
|
+
try {
|
|
546
|
+
const response = JSON.parse(trimmed);
|
|
547
|
+
console.error(`[DEBUG] Go: Received complete response for ID ${response.id}`);
|
|
548
|
+
this.writeLog(`Complete JSON-RPC Response for ID ${response.id}: ${JSON.stringify(response).substring(0, 500)}${JSON.stringify(response).length > 500 ? '...[TRUNCATED]' : ''}`);
|
|
549
|
+
const pending = this.pendingRequests.get(response.id);
|
|
550
|
+
if (pending) {
|
|
551
|
+
this.pendingRequests.delete(response.id);
|
|
552
|
+
if (response.error) {
|
|
553
|
+
console.error(`[DEBUG] Go: Response has error:`, response.error);
|
|
554
|
+
this.writeLog(`Response error: ${JSON.stringify(response.error)}`);
|
|
555
|
+
pending.reject(new Error(response.error.message));
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
console.error(`[DEBUG] Go: Response successful, resolving with ${JSON.stringify(response.result).length} chars`);
|
|
559
|
+
this.writeLog(`Response successful for ID ${response.id}, result size: ${JSON.stringify(response.result).length} chars`);
|
|
560
|
+
pending.resolve(response.result);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
console.error(`[DEBUG] Go: No pending request found for ID ${response.id}`);
|
|
565
|
+
this.writeLog(`No pending request found for ID ${response.id}`);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
catch (error) {
|
|
569
|
+
console.error('[DEBUG] Go: Error parsing JSON line:', error.message, 'Line length:', trimmed.length);
|
|
570
|
+
this.writeLog(`JSON Parse Error: ${error.message}, Line length: ${trimmed.length}, Line start: ${trimmed.substring(0, 100)}`);
|
|
571
|
+
// If this line can't be parsed, it might be part of a larger JSON object
|
|
572
|
+
// Put it back in the buffer and hope the next chunk completes it
|
|
573
|
+
if (this.jsonBuffer) {
|
|
574
|
+
this.jsonBuffer = trimmed + '\n' + this.jsonBuffer;
|
|
575
|
+
}
|
|
576
|
+
else {
|
|
577
|
+
this.jsonBuffer = trimmed;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
async cleanup() {
|
|
583
|
+
if (this.goAnalyzerProcess) {
|
|
584
|
+
console.error('[DEBUG] Go: Cleaning up analyzer process...');
|
|
585
|
+
this.writeLog('Cleanup initiated - terminating Go process');
|
|
586
|
+
this.goAnalyzerProcess.kill();
|
|
587
|
+
this.goAnalyzerProcess = null;
|
|
588
|
+
}
|
|
589
|
+
// Clear JSON buffer
|
|
590
|
+
this.jsonBuffer = '';
|
|
591
|
+
// Reject all pending requests
|
|
592
|
+
for (const [id, pending] of this.pendingRequests) {
|
|
593
|
+
pending.reject(new Error('Adapter cleanup'));
|
|
594
|
+
}
|
|
595
|
+
this.pendingRequests.clear();
|
|
596
|
+
// Reset initialization state
|
|
597
|
+
this.isInitialized = false;
|
|
598
|
+
this.initializationPromise = null;
|
|
599
|
+
this.writeLog('Cleanup completed');
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
//# sourceMappingURL=GoAdapter.js.map
|