code-auditor-mcp 2.6.1 → 3.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/README.md +319 -147
- package/dist/analyzers/analyzerUtils.d.ts +13 -11
- package/dist/analyzers/analyzerUtils.d.ts.map +1 -1
- package/dist/analyzers/analyzerUtils.js +22 -56
- package/dist/analyzers/analyzerUtils.js.map +1 -1
- package/dist/analyzers/cross-language/APIContractAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.js.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -1
- package/dist/analyzers/cross-language/SchemaValidator.d.ts.map +1 -1
- package/dist/analyzers/cross-language/SchemaValidator.js.map +1 -1
- package/dist/analyzers/dataAccessAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/dataAccessAnalyzer.js +50 -24
- package/dist/analyzers/dataAccessAnalyzer.js.map +1 -1
- package/dist/analyzers/documentationAnalyzer.d.ts +4 -1
- package/dist/analyzers/documentationAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/documentationAnalyzer.js +210 -111
- package/dist/analyzers/documentationAnalyzer.js.map +1 -1
- package/dist/analyzers/dryAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/dryAnalyzer.js +190 -58
- package/dist/analyzers/dryAnalyzer.js.map +1 -1
- package/dist/analyzers/invariantsAnalyzer.d.ts +20 -0
- package/dist/analyzers/invariantsAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/invariantsAnalyzer.js +148 -0
- package/dist/analyzers/invariantsAnalyzer.js.map +1 -0
- package/dist/analyzers/reactAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/reactAnalyzer.js +2 -2
- package/dist/analyzers/reactAnalyzer.js.map +1 -1
- package/dist/analyzers/schemaAnalyzer.d.ts +2 -0
- package/dist/analyzers/schemaAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/schemaAnalyzer.js +306 -147
- package/dist/analyzers/schemaAnalyzer.js.map +1 -1
- package/dist/analyzers/solidAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/solidAnalyzer.js +145 -119
- package/dist/analyzers/solidAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts +3 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js +41 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +8 -8
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +6 -6
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -1
- package/dist/api/index.js +1 -0
- package/dist/api/index.js.map +1 -1
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +367 -24
- package/dist/auditRunner.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +740 -18
- package/dist/cli.js.map +1 -1
- package/dist/codeIndexDB-enhanced.d.ts +35 -13
- package/dist/codeIndexDB-enhanced.d.ts.map +1 -1
- package/dist/codeIndexDB-enhanced.js +311 -214
- package/dist/codeIndexDB-enhanced.js.map +1 -1
- package/dist/codeIndexDB.d.ts +222 -0
- package/dist/codeIndexDB.d.ts.map +1 -0
- package/dist/codeIndexDB.js +2042 -0
- package/dist/codeIndexDB.js.map +1 -0
- package/dist/codeIndexService.d.ts.map +1 -1
- package/dist/codeIndexService.js.map +1 -1
- package/dist/componentScanner.d.ts +14 -8
- package/dist/componentScanner.d.ts.map +1 -1
- package/dist/componentScanner.js +136 -113
- package/dist/componentScanner.js.map +1 -1
- package/dist/config/configLoader.d.ts.map +1 -1
- package/dist/config/configLoader.js +10 -7
- package/dist/config/configLoader.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/fingerprint.d.ts +15 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +32 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/functionScanner.d.ts +5 -0
- package/dist/functionScanner.d.ts.map +1 -1
- package/dist/functionScanner.js +417 -341
- package/dist/functionScanner.js.map +1 -1
- package/dist/generators/AWSQConfigGenerator.d.ts.map +1 -1
- package/dist/generators/AiderConfigGenerator.d.ts.map +1 -1
- package/dist/generators/BaseConfigGenerator.d.ts.map +1 -1
- package/dist/generators/BaseConfigGenerator.js.map +1 -1
- package/dist/generators/ClaudeConfigGenerator.d.ts.map +1 -1
- package/dist/generators/ClineConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CodeiumConfigGenerator.d.ts.map +1 -1
- package/dist/generators/ConfigGeneratorFactory.d.ts.map +1 -1
- package/dist/generators/ConfigGeneratorFactory.js.map +1 -1
- package/dist/generators/ContinueConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CopilotConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CursorConfigGenerator.d.ts.map +1 -1
- package/dist/generators/JetBrainsConfigGenerator.d.ts.map +1 -1
- package/dist/generators/VSCodeConfigGenerator.d.ts.map +1 -1
- package/dist/grammars/tree-sitter-go.wasm +0 -0
- package/dist/grammars/tree-sitter-javascript.wasm +0 -0
- package/dist/grammars/tree-sitter-tsx.wasm +0 -0
- package/dist/grammars/tree-sitter-typescript.wasm +0 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/invariants/index.d.ts +9 -0
- package/dist/invariants/index.d.ts.map +1 -0
- package/dist/invariants/index.js +4 -0
- package/dist/invariants/index.js.map +1 -0
- package/dist/invariants/invariant-rules.schema.json +137 -0
- package/dist/invariants/ruleEngine.d.ts +32 -0
- package/dist/invariants/ruleEngine.d.ts.map +1 -0
- package/dist/invariants/ruleEngine.js +536 -0
- package/dist/invariants/ruleEngine.js.map +1 -0
- package/dist/invariants/ruleValidator.d.ts +17 -0
- package/dist/invariants/ruleValidator.d.ts.map +1 -0
- package/dist/invariants/ruleValidator.js +264 -0
- package/dist/invariants/ruleValidator.js.map +1 -0
- package/dist/invariants/types.d.ts +78 -0
- package/dist/invariants/types.d.ts.map +1 -0
- package/dist/invariants/types.js +5 -0
- package/dist/invariants/types.js.map +1 -0
- package/dist/languages/LanguageOrchestrator.d.ts.map +1 -1
- package/dist/languages/LanguageOrchestrator.js.map +1 -1
- package/dist/languages/LanguageRegistry.d.ts.map +1 -1
- package/dist/languages/RuntimeManager.d.ts.map +1 -1
- package/dist/languages/RuntimeManager.js +1 -1
- package/dist/languages/RuntimeManager.js.map +1 -1
- package/dist/languages/UniversalAnalyzer.d.ts.map +1 -1
- package/dist/languages/UniversalAnalyzer.js.map +1 -1
- package/dist/languages/adapterBridge.d.ts +102 -0
- package/dist/languages/adapterBridge.d.ts.map +1 -0
- package/dist/languages/adapterBridge.js +382 -0
- package/dist/languages/adapterBridge.js.map +1 -0
- package/dist/languages/go/GoAdapter.d.ts +37 -26
- package/dist/languages/go/GoAdapter.d.ts.map +1 -1
- package/dist/languages/go/GoAdapter.js +560 -281
- package/dist/languages/go/GoAdapter.js.map +1 -1
- package/dist/languages/index.d.ts +5 -2
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +11 -9
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/tree-sitter/converter.d.ts +43 -0
- package/dist/languages/tree-sitter/converter.d.ts.map +1 -0
- package/dist/languages/tree-sitter/converter.js +150 -0
- package/dist/languages/tree-sitter/converter.js.map +1 -0
- package/dist/languages/tree-sitter/parser.d.ts +36 -0
- package/dist/languages/tree-sitter/parser.d.ts.map +1 -0
- package/dist/languages/tree-sitter/parser.js +114 -0
- package/dist/languages/tree-sitter/parser.js.map +1 -0
- package/dist/languages/types.d.ts +11 -0
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts +92 -0
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -0
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +951 -0
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -0
- package/dist/mcp-tools/projectTasks.d.ts +80 -11
- package/dist/mcp-tools/projectTasks.d.ts.map +1 -1
- package/dist/mcp-tools/projectTasks.js +279 -13
- package/dist/mcp-tools/projectTasks.js.map +1 -1
- package/dist/mcp-tools/whitelistTools.d.ts +21 -21
- package/dist/mcp-tools/whitelistTools.d.ts.map +1 -1
- package/dist/mcp-tools/workflowGuide.d.ts.map +1 -1
- package/dist/mcp-tools/workflowGuide.js +130 -126
- package/dist/mcp-tools/workflowGuide.js.map +1 -1
- package/dist/mcp-tools-shared.d.ts.map +1 -1
- package/dist/mcp-tools-shared.js.map +1 -1
- package/dist/mcp-ui-simple.js +1 -1
- package/dist/mcp-ui-simple.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +1455 -1132
- package/dist/mcp.js.map +1 -1
- package/dist/mcpAuditJobs.d.ts +4 -0
- package/dist/mcpAuditJobs.d.ts.map +1 -1
- package/dist/mcpAuditJobs.js +49 -2
- package/dist/mcpAuditJobs.js.map +1 -1
- package/dist/mcpDiagnostics.d.ts.map +1 -1
- package/dist/mcpDiagnostics.js +8 -5
- package/dist/mcpDiagnostics.js.map +1 -1
- package/dist/mcpToolErrors.d.ts.map +1 -1
- package/dist/mcpToolErrors.js.map +1 -1
- package/dist/native/ast-grep-napi.darwin-arm64.node +0 -0
- package/dist/native/ast-grep-napi.darwin-x64.node +0 -0
- package/dist/native/ast-grep-napi.linux-arm64-gnu.node +0 -0
- package/dist/native/ast-grep-napi.linux-arm64-musl.node +0 -0
- package/dist/native/ast-grep-napi.linux-x64-gnu.node +0 -0
- package/dist/native/ast-grep-napi.linux-x64-musl.node +0 -0
- package/dist/native/ast-grep-napi.win32-x64-msvc.node +0 -0
- package/dist/native-bootstrap.d.ts +15 -0
- package/dist/native-bootstrap.d.ts.map +1 -0
- package/dist/native-bootstrap.js +75 -0
- package/dist/native-bootstrap.js.map +1 -0
- package/dist/reporting/csvReportGenerator.d.ts.map +1 -1
- package/dist/reporting/htmlReportGenerator.d.ts.map +1 -1
- package/dist/reporting/jsonReportGenerator.d.ts.map +1 -1
- package/dist/reporting/reportGenerator.d.ts.map +1 -1
- package/dist/reporting/reportGenerator.js +4 -0
- package/dist/reporting/reportGenerator.js.map +1 -1
- package/dist/reporting/sarifReportGenerator.d.ts +39 -0
- package/dist/reporting/sarifReportGenerator.d.ts.map +1 -0
- package/dist/reporting/sarifReportGenerator.js +229 -0
- package/dist/reporting/sarifReportGenerator.js.map +1 -0
- package/dist/search/QueryParser.d.ts +41 -0
- package/dist/search/QueryParser.d.ts.map +1 -1
- package/dist/search/QueryParser.js +200 -19
- package/dist/search/QueryParser.js.map +1 -1
- package/dist/services/CodeMapGenerator.d.ts.map +1 -1
- package/dist/services/CodeMapGenerator.js +4 -4
- package/dist/services/CodeMapGenerator.js.map +1 -1
- package/dist/services/ProjectTaskRepository.d.ts +34 -9
- package/dist/services/ProjectTaskRepository.d.ts.map +1 -1
- package/dist/services/ProjectTaskRepository.js +385 -10
- package/dist/services/ProjectTaskRepository.js.map +1 -1
- package/dist/services/SchemaParser.d.ts.map +1 -1
- package/dist/services/SchemaParser.js +5 -8
- package/dist/services/SchemaParser.js.map +1 -1
- package/dist/services/auditJobService.d.ts +1 -1
- package/dist/services/projectTaskHelpers.js.map +1 -1
- package/dist/services/whitelistService.d.ts.map +1 -1
- package/dist/services/whitelistService.js +1 -1
- package/dist/services/whitelistService.js.map +1 -1
- package/dist/tool-registry.d.ts +79 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +139 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/types/projectTask.d.ts +31 -0
- package/dist/types/projectTask.d.ts.map +1 -1
- package/dist/types.d.ts +26 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/InteractivePrompts.d.ts.map +1 -1
- package/dist/ui/InteractivePrompts.js.map +1 -1
- package/dist/utils/astParser.d.ts +31 -38
- package/dist/utils/astParser.d.ts.map +1 -1
- package/dist/utils/astParser.js +138 -196
- package/dist/utils/astParser.js.map +1 -1
- package/dist/utils/astUtils.d.ts +87 -58
- package/dist/utils/astUtils.d.ts.map +1 -1
- package/dist/utils/astUtils.js +852 -581
- package/dist/utils/astUtils.js.map +1 -1
- package/dist/utils/componentPatterns.js.map +1 -1
- package/dist/utils/componentResponsibility.d.ts +13 -9
- package/dist/utils/componentResponsibility.d.ts.map +1 -1
- package/dist/utils/componentResponsibility.js +236 -206
- package/dist/utils/componentResponsibility.js.map +1 -1
- package/dist/utils/dependencyExtractor.d.ts +11 -6
- package/dist/utils/dependencyExtractor.d.ts.map +1 -1
- package/dist/utils/dependencyExtractor.js +200 -119
- package/dist/utils/dependencyExtractor.js.map +1 -1
- package/dist/utils/fileDiscovery.d.ts +1 -1
- package/dist/utils/fileDiscovery.d.ts.map +1 -1
- package/dist/utils/fileDiscovery.js.map +1 -1
- package/dist/utils/jsDocParser.d.ts +27 -30
- package/dist/utils/jsDocParser.d.ts.map +1 -1
- package/dist/utils/jsDocParser.js +271 -207
- package/dist/utils/jsDocParser.js.map +1 -1
- package/dist/utils/reactDetection.d.ts +27 -12
- package/dist/utils/reactDetection.d.ts.map +1 -1
- package/dist/utils/reactDetection.js +331 -219
- package/dist/utils/reactDetection.js.map +1 -1
- package/dist/workers/auditWorker.js +17 -3
- package/dist/workers/auditWorker.js.map +1 -1
- package/package.json +54 -51
- package/dist/adapters/GoAdapter.d.ts +0 -53
- package/dist/adapters/GoAdapter.d.ts.map +0 -1
- package/dist/adapters/GoAdapter.js +0 -611
- package/dist/adapters/GoAdapter.js.map +0 -1
- package/dist/adapters/GoConfig.d.ts +0 -35
- package/dist/adapters/GoConfig.d.ts.map +0 -1
- package/dist/adapters/GoConfig.js +0 -155
- package/dist/adapters/GoConfig.js.map +0 -1
- package/dist/adapters/LanguageAdapter.d.ts +0 -135
- package/dist/adapters/LanguageAdapter.d.ts.map +0 -1
- package/dist/adapters/LanguageAdapter.js +0 -47
- package/dist/adapters/LanguageAdapter.js.map +0 -1
- package/dist/adapters/TypeScriptAdapter.d.ts +0 -43
- package/dist/adapters/TypeScriptAdapter.d.ts.map +0 -1
- package/dist/adapters/TypeScriptAdapter.js +0 -386
- package/dist/adapters/TypeScriptAdapter.js.map +0 -1
- package/dist/adapters/UniversalAnalyzer.d.ts +0 -42
- package/dist/adapters/UniversalAnalyzer.d.ts.map +0 -1
- package/dist/adapters/UniversalAnalyzer.js +0 -103
- package/dist/adapters/UniversalAnalyzer.js.map +0 -1
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts +0 -48
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts.map +0 -1
- package/dist/adapters/UniversalSOLIDAnalyzer.js +0 -178
- package/dist/adapters/UniversalSOLIDAnalyzer.js.map +0 -1
- package/dist/adapters/solidAnalyzerCompat.d.ts +0 -21
- package/dist/adapters/solidAnalyzerCompat.d.ts.map +0 -1
- package/dist/adapters/solidAnalyzerCompat.js +0 -78
- package/dist/adapters/solidAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/dataAccessAnalyzerCompat.js +0 -59
- package/dist/analyzers/dataAccessAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/documentationAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/documentationAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/documentationAnalyzerCompat.js +0 -52
- package/dist/analyzers/documentationAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/dryAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/dryAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/dryAnalyzerCompat.js +0 -44
- package/dist/analyzers/dryAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/schemaAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/schemaAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/schemaAnalyzerCompat.js +0 -69
- package/dist/analyzers/schemaAnalyzerCompat.js.map +0 -1
- package/dist/analyzers/solidAnalyzerCompat.d.ts +0 -20
- package/dist/analyzers/solidAnalyzerCompat.d.ts.map +0 -1
- package/dist/analyzers/solidAnalyzerCompat.js +0 -78
- package/dist/analyzers/solidAnalyzerCompat.js.map +0 -1
- package/dist/codeIndexDb.d.ts +0 -394
- package/dist/codeIndexDb.d.ts.map +0 -1
- package/dist/codeIndexDb.js +0 -2077
- package/dist/codeIndexDb.js.map +0 -1
- package/dist/languages/typescript/TypeScriptAdapter.d.ts +0 -108
- package/dist/languages/typescript/TypeScriptAdapter.d.ts.map +0 -1
- package/dist/languages/typescript/TypeScriptAdapter.js +0 -567
- package/dist/languages/typescript/TypeScriptAdapter.js.map +0 -1
- package/dist/languages/typescript/test-extraction.d.ts +0 -2
- package/dist/languages/typescript/test-extraction.d.ts.map +0 -1
- package/dist/languages/typescript/test-extraction.js +0 -36
- package/dist/languages/typescript/test-extraction.js.map +0 -1
- package/dist/mcp-hybrid.d.ts +0 -10
- package/dist/mcp-hybrid.d.ts.map +0 -1
- package/dist/mcp-hybrid.js +0 -41
- package/dist/mcp-hybrid.js.map +0 -1
- package/dist/mcp-index.d.ts +0 -13
- package/dist/mcp-index.d.ts.map +0 -1
- package/dist/mcp-index.js +0 -123
- package/dist/mcp-index.js.map +0 -1
- package/dist/mcp-standalone.d.ts +0 -3
- package/dist/mcp-standalone.d.ts.map +0 -1
- package/dist/mcp-standalone.js +0 -1201
- package/dist/mcp-standalone.js.map +0 -1
- package/dist/mcp-ui-server.d.ts +0 -27
- package/dist/mcp-ui-server.d.ts.map +0 -1
- package/dist/mcp-ui-server.js +0 -484
- package/dist/mcp-ui-server.js.map +0 -1
- package/dist/test-multi-strategy-search.d.ts +0 -3
- package/dist/test-multi-strategy-search.d.ts.map +0 -1
- package/dist/test-multi-strategy-search.js +0 -170
- package/dist/test-multi-strategy-search.js.map +0 -1
|
@@ -1,360 +1,639 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Go
|
|
3
|
-
*
|
|
2
|
+
* Go language adapter using tree-sitter-go WASM parser.
|
|
3
|
+
*
|
|
4
|
+
* Provides real AST-based analysis for Go source files. Replaces the previous
|
|
5
|
+
* regex-based stub that returned empty arrays for most queries.
|
|
4
6
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import { getParser } from '../tree-sitter/parser.js';
|
|
8
|
+
import { toASTNode, toSourceLocation } from '../tree-sitter/converter.js';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Source code storage
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
const sourceCodeMap = new WeakMap();
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Adapter
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
export class TreeSitterGoAdapter {
|
|
9
17
|
name = 'go';
|
|
10
18
|
fileExtensions = ['.go'];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
async parse(filePath, content) {
|
|
15
|
-
try {
|
|
16
|
-
console.error('[DEBUG] Go: Parsing file:', filePath);
|
|
17
|
-
// For now, create a simple AST structure
|
|
18
|
-
// TODO: Implement actual Go parser integration
|
|
19
|
-
const ast = {
|
|
20
|
-
root: this.createSimpleGoAST(content, filePath),
|
|
21
|
-
language: 'go',
|
|
22
|
-
filePath,
|
|
23
|
-
errors: []
|
|
24
|
-
};
|
|
25
|
-
console.error('[DEBUG] Go: AST created successfully');
|
|
26
|
-
return ast;
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
console.error('[DEBUG] Go: Parse error:', error);
|
|
30
|
-
return {
|
|
31
|
-
root: {
|
|
32
|
-
type: 'Program',
|
|
33
|
-
range: [0, content.length],
|
|
34
|
-
location: { start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
|
|
35
|
-
raw: null
|
|
36
|
-
},
|
|
37
|
-
language: 'go',
|
|
38
|
-
filePath,
|
|
39
|
-
errors: [{
|
|
40
|
-
message: error instanceof Error ? error.message : String(error),
|
|
41
|
-
location: { start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
|
|
42
|
-
severity: 'error'
|
|
43
|
-
}]
|
|
44
|
-
};
|
|
45
|
-
}
|
|
19
|
+
// -- File detection -------------------------------------------------------
|
|
20
|
+
supportsFile(filePath) {
|
|
21
|
+
return filePath.endsWith('.go');
|
|
46
22
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
children.push({
|
|
62
|
-
type: 'FunctionDeclaration',
|
|
63
|
-
range: [startPos, startPos + match[0].length],
|
|
64
|
-
location: {
|
|
65
|
-
start: { line: startLine, column: 0 },
|
|
66
|
-
end: { line: startLine, column: match[0].length }
|
|
67
|
-
},
|
|
68
|
-
raw: {
|
|
69
|
-
name: functionName,
|
|
70
|
-
match: match[0]
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
// Extract structs using regex
|
|
75
|
-
const structPattern = /^type\s+(\w+)\s+struct\s*\{/gm;
|
|
76
|
-
while ((match = structPattern.exec(content)) !== null) {
|
|
77
|
-
const structName = match[1];
|
|
78
|
-
const startPos = match.index;
|
|
79
|
-
const startLine = content.substring(0, startPos).split('\n').length;
|
|
80
|
-
children.push({
|
|
81
|
-
type: 'StructDeclaration',
|
|
82
|
-
range: [startPos, startPos + match[0].length],
|
|
83
|
-
location: {
|
|
84
|
-
start: { line: startLine, column: 0 },
|
|
85
|
-
end: { line: startLine, column: match[0].length }
|
|
86
|
-
},
|
|
87
|
-
raw: {
|
|
88
|
-
name: structName,
|
|
89
|
-
match: match[0]
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
// Extract interfaces using regex with member parsing
|
|
94
|
-
const interfacePattern = /type\s+(\w+)\s+interface\s*\{([\s\S]*?)\}/gm;
|
|
95
|
-
while ((match = interfacePattern.exec(content)) !== null) {
|
|
96
|
-
const interfaceName = match[1];
|
|
97
|
-
const interfaceBody = match[2];
|
|
98
|
-
const startPos = match.index;
|
|
99
|
-
const startLine = content.substring(0, startPos).split('\n').length;
|
|
100
|
-
// Count interface methods - look for method signatures
|
|
101
|
-
const methodMatches = interfaceBody.match(/^\s*\w+\s*\([^)]*\)\s*(\([^)]*\))?\s*(\w+)?\s*$/gm) || [];
|
|
102
|
-
const memberCount = methodMatches.length;
|
|
103
|
-
console.error(`[DEBUG] Go: Interface ${interfaceName} body:`, JSON.stringify(interfaceBody.substring(0, 200)));
|
|
104
|
-
console.error(`[DEBUG] Go: Interface ${interfaceName} method matches:`, methodMatches.length, methodMatches.slice(0, 3));
|
|
105
|
-
children.push({
|
|
106
|
-
type: 'InterfaceDeclaration',
|
|
107
|
-
range: [startPos, startPos + match[0].length],
|
|
108
|
-
location: {
|
|
109
|
-
start: { line: startLine, column: 0 },
|
|
110
|
-
end: { line: startLine, column: match[0].length }
|
|
111
|
-
},
|
|
112
|
-
raw: {
|
|
113
|
-
name: interfaceName,
|
|
114
|
-
match: match[0],
|
|
115
|
-
memberCount: memberCount,
|
|
116
|
-
methods: methodMatches
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
return {
|
|
121
|
-
type: 'Program',
|
|
122
|
-
range: [0, content.length],
|
|
123
|
-
location: {
|
|
124
|
-
start: { line: 1, column: 0 },
|
|
125
|
-
end: { line: lines.length, column: lines[lines.length - 1]?.length || 0 }
|
|
126
|
-
},
|
|
127
|
-
children,
|
|
128
|
-
raw: { content, filePath }
|
|
23
|
+
// -- Parsing --------------------------------------------------------------
|
|
24
|
+
async parse(filePath, content) {
|
|
25
|
+
const parser = getParser('go');
|
|
26
|
+
const tree = parser.parse(content);
|
|
27
|
+
if (!tree)
|
|
28
|
+
throw new Error(`Failed to parse Go file: ${filePath}`);
|
|
29
|
+
const errors = [];
|
|
30
|
+
this.collectErrors(tree.rootNode, errors);
|
|
31
|
+
const root = toASTNode(tree.rootNode, undefined, 'go');
|
|
32
|
+
const ast = {
|
|
33
|
+
root,
|
|
34
|
+
language: 'go',
|
|
35
|
+
filePath,
|
|
36
|
+
errors,
|
|
129
37
|
};
|
|
38
|
+
sourceCodeMap.set(ast, content);
|
|
39
|
+
return ast;
|
|
130
40
|
}
|
|
131
|
-
|
|
132
|
-
* Check if this adapter supports a file
|
|
133
|
-
*/
|
|
134
|
-
supportsFile(filePath) {
|
|
135
|
-
return this.fileExtensions.some(ext => filePath.endsWith(ext));
|
|
136
|
-
}
|
|
137
|
-
// AST Navigation
|
|
41
|
+
// -- AST Navigation -------------------------------------------------------
|
|
138
42
|
findNodes(ast, pattern) {
|
|
139
43
|
const results = [];
|
|
140
|
-
this.
|
|
44
|
+
this.walk(ast.root, (node) => {
|
|
141
45
|
if (this.matchesPattern(node, pattern)) {
|
|
142
46
|
results.push(node);
|
|
143
47
|
}
|
|
144
48
|
});
|
|
145
49
|
return results;
|
|
146
50
|
}
|
|
147
|
-
walkAST(node, callback) {
|
|
148
|
-
callback(node);
|
|
149
|
-
if (node.children) {
|
|
150
|
-
for (const child of node.children) {
|
|
151
|
-
this.walkAST(child, callback);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
matchesPattern(node, pattern) {
|
|
156
|
-
if (pattern.type) {
|
|
157
|
-
const types = Array.isArray(pattern.type) ? pattern.type : [pattern.type];
|
|
158
|
-
if (!types.includes(node.type))
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
51
|
getParent(node) {
|
|
164
|
-
return node.parent
|
|
52
|
+
return node.parent ?? null;
|
|
165
53
|
}
|
|
166
54
|
getChildren(node) {
|
|
167
|
-
return node.children
|
|
55
|
+
return node.children ?? [];
|
|
168
56
|
}
|
|
169
57
|
getSiblings(node) {
|
|
170
|
-
|
|
171
|
-
if (!parent)
|
|
58
|
+
if (!node.parent?.children)
|
|
172
59
|
return [];
|
|
173
|
-
return
|
|
60
|
+
return node.parent.children.filter((c) => c !== node);
|
|
174
61
|
}
|
|
175
|
-
// Node Information
|
|
62
|
+
// -- Node Information -----------------------------------------------------
|
|
176
63
|
getNodeType(node) {
|
|
177
64
|
return node.type;
|
|
178
65
|
}
|
|
179
66
|
getNodeText(node, sourceCode) {
|
|
180
|
-
|
|
181
|
-
return sourceCode.substring(start, end);
|
|
67
|
+
return sourceCode.slice(node.range[0], node.range[1]);
|
|
182
68
|
}
|
|
183
69
|
getNodeName(node) {
|
|
184
|
-
|
|
185
|
-
return node.raw.name;
|
|
186
|
-
}
|
|
187
|
-
return null;
|
|
70
|
+
return this.extractName(node.raw);
|
|
188
71
|
}
|
|
189
72
|
getNodeLocation(node) {
|
|
190
73
|
return node.location;
|
|
191
74
|
}
|
|
192
|
-
// Language-Specific Extraction
|
|
75
|
+
// -- Language-Specific Extraction -----------------------------------------
|
|
193
76
|
extractFunctions(ast) {
|
|
194
|
-
|
|
77
|
+
const sourceCode = sourceCodeMap.get(ast) ?? '';
|
|
195
78
|
const functions = [];
|
|
196
|
-
this.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
functions.push(
|
|
202
|
-
}
|
|
79
|
+
this.walk(ast.root, (astNode) => {
|
|
80
|
+
const node = astNode.raw;
|
|
81
|
+
if (node.type === 'function_declaration') {
|
|
82
|
+
const fn = this.buildFunctionInfo(node, sourceCode);
|
|
83
|
+
if (fn)
|
|
84
|
+
functions.push(fn);
|
|
203
85
|
}
|
|
204
86
|
});
|
|
205
|
-
console.error('[DEBUG] Go: Total functions extracted:', functions.length);
|
|
206
87
|
return functions;
|
|
207
88
|
}
|
|
208
|
-
extractFunctionInfo(node) {
|
|
209
|
-
if (!this.isFunction(node) || !node.raw?.name)
|
|
210
|
-
return null;
|
|
211
|
-
return {
|
|
212
|
-
name: node.raw.name,
|
|
213
|
-
parameters: [], // TODO: Parse parameters from function signature
|
|
214
|
-
returnType: 'unknown', // TODO: Parse return type
|
|
215
|
-
location: node.location,
|
|
216
|
-
isAsync: false, // Go doesn't have async/await like JS
|
|
217
|
-
isExported: this.isExportedFunction(node.raw.name),
|
|
218
|
-
isMethod: false, // TODO: Detect if this is a method (has receiver)
|
|
219
|
-
className: undefined, // TODO: Extract receiver type for methods
|
|
220
|
-
jsDoc: undefined // Go uses different comment format
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
isExportedFunction(name) {
|
|
224
|
-
// In Go, exported functions start with uppercase letter
|
|
225
|
-
return name.length > 0 && name[0] === name[0].toUpperCase();
|
|
226
|
-
}
|
|
227
89
|
extractClasses(ast) {
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
90
|
+
const sourceCode = sourceCodeMap.get(ast) ?? '';
|
|
91
|
+
const classes = [];
|
|
92
|
+
// Collect all function_declarations so we can match methods to structs
|
|
93
|
+
const allFunctions = this.extractFunctions(ast);
|
|
94
|
+
this.walk(ast.root, (astNode) => {
|
|
95
|
+
const node = astNode.raw;
|
|
96
|
+
if (node.type === 'type_declaration') {
|
|
97
|
+
const specs = this.findNamedChildren(node, 'type_spec');
|
|
98
|
+
for (const spec of specs) {
|
|
99
|
+
const nameNode = spec.childForFieldName?.('name');
|
|
100
|
+
if (!nameNode)
|
|
101
|
+
continue;
|
|
102
|
+
const typeNode = spec.childForFieldName?.('type');
|
|
103
|
+
if (!typeNode || typeNode.type !== 'struct_type')
|
|
104
|
+
continue;
|
|
105
|
+
const structInfo = this.buildStructAsClass(spec, nameNode, typeNode, allFunctions, sourceCode);
|
|
106
|
+
if (structInfo)
|
|
107
|
+
classes.push(structInfo);
|
|
235
108
|
}
|
|
236
109
|
}
|
|
237
110
|
});
|
|
238
|
-
|
|
239
|
-
return structs;
|
|
240
|
-
}
|
|
241
|
-
extractStructInfo(node) {
|
|
242
|
-
if (!this.isStruct(node) || !node.raw?.name)
|
|
243
|
-
return null;
|
|
244
|
-
return {
|
|
245
|
-
name: node.raw.name,
|
|
246
|
-
location: node.location,
|
|
247
|
-
methods: [], // TODO: Extract methods associated with this struct
|
|
248
|
-
properties: [], // TODO: Extract struct fields
|
|
249
|
-
extends: undefined, // Go doesn't have inheritance
|
|
250
|
-
implements: [], // TODO: Check if struct implements interfaces
|
|
251
|
-
isAbstract: false, // Go doesn't have abstract structs
|
|
252
|
-
isExported: this.isExportedStruct(node.raw.name),
|
|
253
|
-
jsDoc: undefined
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
isExportedStruct(name) {
|
|
257
|
-
return name.length > 0 && name[0] === name[0].toUpperCase();
|
|
111
|
+
return classes;
|
|
258
112
|
}
|
|
259
113
|
extractImports(ast) {
|
|
260
|
-
console.error('[DEBUG] Go: extractImports called');
|
|
261
114
|
const imports = [];
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
115
|
+
this.walk(ast.root, (astNode) => {
|
|
116
|
+
const node = astNode.raw;
|
|
117
|
+
if (node.type === 'import_declaration') {
|
|
118
|
+
for (const spec of node.namedChildren) {
|
|
119
|
+
if (spec.type === 'import_spec') {
|
|
120
|
+
const imp = this.buildImportInfo(spec);
|
|
121
|
+
if (imp)
|
|
122
|
+
imports.push(imp);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
265
127
|
return imports;
|
|
266
128
|
}
|
|
267
129
|
extractExports(ast) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if (iface) {
|
|
280
|
-
console.error('[DEBUG] Go: Extracted interface:', iface.name, 'with', iface.members?.length, 'members');
|
|
281
|
-
interfaces.push(iface);
|
|
130
|
+
const exports = [];
|
|
131
|
+
this.walk(ast.root, (astNode) => {
|
|
132
|
+
const node = astNode.raw;
|
|
133
|
+
if (node.type === 'function_declaration') {
|
|
134
|
+
const name = this.extractName(node);
|
|
135
|
+
if (name && this.isExportedGo(name)) {
|
|
136
|
+
exports.push({
|
|
137
|
+
name,
|
|
138
|
+
location: toSourceLocation(node),
|
|
139
|
+
isDefault: false,
|
|
140
|
+
});
|
|
282
141
|
}
|
|
283
142
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
members.push({
|
|
296
|
-
name: `method${i + 1}`, // Simple naming since we can't parse method names easily with regex
|
|
297
|
-
type: 'method',
|
|
298
|
-
location: node.location // Use interface location as approximation
|
|
299
|
-
});
|
|
143
|
+
else if (node.type === 'type_declaration') {
|
|
144
|
+
for (const spec of this.findNamedChildren(node, 'type_spec')) {
|
|
145
|
+
const nameNode = spec.childForFieldName?.('name');
|
|
146
|
+
if (nameNode && this.isExportedGo(nameNode.text)) {
|
|
147
|
+
exports.push({
|
|
148
|
+
name: nameNode.text,
|
|
149
|
+
location: toSourceLocation(nameNode),
|
|
150
|
+
isDefault: false,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
300
154
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
155
|
+
else if (node.type === 'var_declaration') {
|
|
156
|
+
for (const spec of this.findNamedChildren(node, 'var_spec')) {
|
|
157
|
+
const nameNode = spec.childForFieldName?.('name');
|
|
158
|
+
if (nameNode && this.isExportedGo(nameNode.text)) {
|
|
159
|
+
exports.push({
|
|
160
|
+
name: nameNode.text,
|
|
161
|
+
location: toSourceLocation(nameNode),
|
|
162
|
+
isDefault: false,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
return exports;
|
|
312
169
|
}
|
|
313
|
-
// Pattern Matching Helpers
|
|
170
|
+
// -- Pattern Matching Helpers ---------------------------------------------
|
|
314
171
|
isClass(node) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
172
|
+
const n = node.raw;
|
|
173
|
+
if (n.type === 'type_spec') {
|
|
174
|
+
const typeNode = n.childForFieldName?.('type');
|
|
175
|
+
return typeNode?.type === 'struct_type';
|
|
176
|
+
}
|
|
177
|
+
return n.type === 'struct_type';
|
|
319
178
|
}
|
|
320
179
|
isFunction(node) {
|
|
321
|
-
return node.type === '
|
|
180
|
+
return node.raw.type === 'function_declaration';
|
|
322
181
|
}
|
|
323
182
|
isMethod(node) {
|
|
324
|
-
|
|
325
|
-
|
|
183
|
+
const n = node.raw;
|
|
184
|
+
if (n.type !== 'function_declaration')
|
|
185
|
+
return false;
|
|
186
|
+
return n.childForFieldName?.('receiver') != null;
|
|
326
187
|
}
|
|
327
188
|
isInterface(node) {
|
|
328
|
-
|
|
189
|
+
const n = node.raw;
|
|
190
|
+
if (n.type === 'type_spec') {
|
|
191
|
+
const typeNode = n.childForFieldName?.('type');
|
|
192
|
+
return typeNode?.type === 'interface_type';
|
|
193
|
+
}
|
|
194
|
+
return n.type === 'interface_type';
|
|
329
195
|
}
|
|
330
196
|
isImport(node) {
|
|
331
|
-
return node.type === '
|
|
197
|
+
return node.raw.type === 'import_declaration';
|
|
332
198
|
}
|
|
333
199
|
isExport(node) {
|
|
334
|
-
// Go
|
|
335
|
-
return false;
|
|
200
|
+
return false; // Go has no export keyword
|
|
336
201
|
}
|
|
337
202
|
isLoop(node) {
|
|
338
|
-
return
|
|
203
|
+
return node.raw.type === 'for_statement';
|
|
339
204
|
}
|
|
340
205
|
isConditional(node) {
|
|
341
|
-
|
|
206
|
+
const t = node.raw.type;
|
|
207
|
+
return (t === 'if_statement' ||
|
|
208
|
+
t === 'switch_statement' ||
|
|
209
|
+
t === 'expression_switch_statement' ||
|
|
210
|
+
t === 'type_switch_statement');
|
|
342
211
|
}
|
|
343
212
|
isVariableDeclaration(node) {
|
|
344
|
-
|
|
213
|
+
const t = node.raw.type;
|
|
214
|
+
return (t === 'var_declaration' ||
|
|
215
|
+
t === 'short_var_declaration' ||
|
|
216
|
+
t === 'var_spec' ||
|
|
217
|
+
t === 'const_declaration');
|
|
345
218
|
}
|
|
346
|
-
// Advanced Features
|
|
219
|
+
// -- Advanced Features ----------------------------------------------------
|
|
347
220
|
getTypeInfo(node) {
|
|
348
|
-
|
|
221
|
+
const n = node.raw;
|
|
222
|
+
if (n.type === 'function_declaration') {
|
|
223
|
+
const result = n.childForFieldName?.('result');
|
|
224
|
+
if (result)
|
|
225
|
+
return result.text.trim();
|
|
226
|
+
}
|
|
227
|
+
if (n.type === 'var_spec' || n.type === 'const_spec') {
|
|
228
|
+
const typeNode = n.childForFieldName?.('type');
|
|
229
|
+
if (typeNode)
|
|
230
|
+
return typeNode.text.trim();
|
|
231
|
+
}
|
|
232
|
+
if (n.type === 'field_declaration') {
|
|
233
|
+
const typeNode = n.childForFieldName?.('type');
|
|
234
|
+
if (typeNode)
|
|
235
|
+
return typeNode.text.trim();
|
|
236
|
+
}
|
|
349
237
|
return null;
|
|
350
238
|
}
|
|
351
239
|
getDocumentation(node) {
|
|
352
|
-
|
|
353
|
-
return null;
|
|
240
|
+
return this.extractDocumentation(node.raw);
|
|
354
241
|
}
|
|
355
242
|
getComplexity(node) {
|
|
356
|
-
|
|
357
|
-
|
|
243
|
+
return this.calculateComplexity(node.raw);
|
|
244
|
+
}
|
|
245
|
+
// -- Optional: Interfaces -------------------------------------------------
|
|
246
|
+
extractInterfaces(ast) {
|
|
247
|
+
const interfaces = [];
|
|
248
|
+
this.walk(ast.root, (astNode) => {
|
|
249
|
+
const node = astNode.raw;
|
|
250
|
+
if (node.type === 'type_declaration') {
|
|
251
|
+
const specs = this.findNamedChildren(node, 'type_spec');
|
|
252
|
+
for (const spec of specs) {
|
|
253
|
+
const nameNode = spec.childForFieldName?.('name');
|
|
254
|
+
const typeNode = spec.childForFieldName?.('type');
|
|
255
|
+
if (nameNode && typeNode?.type === 'interface_type') {
|
|
256
|
+
const ifaceInfo = this.buildInterfaceInfo(nameNode, typeNode);
|
|
257
|
+
if (ifaceInfo)
|
|
258
|
+
interfaces.push(ifaceInfo);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
return interfaces;
|
|
264
|
+
}
|
|
265
|
+
// -- Optional: Raw imports ------------------------------------------------
|
|
266
|
+
extractRawImports(_filePath, content) {
|
|
267
|
+
const results = [];
|
|
268
|
+
const parser = getParser('go');
|
|
269
|
+
const tree = parser.parse(content);
|
|
270
|
+
if (!tree)
|
|
271
|
+
return results;
|
|
272
|
+
this.walkRaw(tree.rootNode, (node) => {
|
|
273
|
+
if (node.type === 'import_declaration') {
|
|
274
|
+
for (const spec of node.namedChildren) {
|
|
275
|
+
if (spec.type === 'import_spec') {
|
|
276
|
+
for (const child of spec.namedChildren) {
|
|
277
|
+
if (child.type === 'interpreted_string_literal' ||
|
|
278
|
+
child.type === 'raw_string_literal') {
|
|
279
|
+
results.push({
|
|
280
|
+
moduleSpecifier: child.text.slice(1, -1),
|
|
281
|
+
isStatic: true,
|
|
282
|
+
isDynamic: false,
|
|
283
|
+
isRequire: false,
|
|
284
|
+
line: child.startPosition.row,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
return results;
|
|
293
|
+
}
|
|
294
|
+
// -- Optional: Exported symbols -------------------------------------------
|
|
295
|
+
extractExportedSymbols(ast) {
|
|
296
|
+
return this.extractExports(ast).map((e) => ({
|
|
297
|
+
name: e.name,
|
|
298
|
+
line: e.location.start.line,
|
|
299
|
+
}));
|
|
300
|
+
}
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
// Internal helpers
|
|
303
|
+
// ---------------------------------------------------------------------------
|
|
304
|
+
walk(node, visitor) {
|
|
305
|
+
visitor(node);
|
|
306
|
+
if (node.children) {
|
|
307
|
+
for (const child of node.children) {
|
|
308
|
+
this.walk(child, visitor);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
walkRaw(node, visitor) {
|
|
313
|
+
visitor(node);
|
|
314
|
+
for (const child of node.children) {
|
|
315
|
+
this.walkRaw(child, visitor);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
collectErrors(node, errors) {
|
|
319
|
+
if (node.type === 'ERROR' || node.isError) {
|
|
320
|
+
errors.push({
|
|
321
|
+
message: `Parse error near "${node.text.slice(0, 50)}"`,
|
|
322
|
+
location: toSourceLocation(node),
|
|
323
|
+
severity: 'error',
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
for (const child of node.children) {
|
|
327
|
+
this.collectErrors(child, errors);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
matchesPattern(node, pattern) {
|
|
331
|
+
const syntaxNode = node.raw;
|
|
332
|
+
if (pattern.type !== undefined) {
|
|
333
|
+
const types = Array.isArray(pattern.type) ? pattern.type : [pattern.type];
|
|
334
|
+
if (!types.includes(syntaxNode.type))
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
if (pattern.name !== undefined) {
|
|
338
|
+
const nodeName = this.extractName(syntaxNode);
|
|
339
|
+
if (nodeName === null)
|
|
340
|
+
return false;
|
|
341
|
+
if (typeof pattern.name === 'string') {
|
|
342
|
+
if (nodeName !== pattern.name)
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
else if (pattern.name instanceof RegExp) {
|
|
346
|
+
if (!pattern.name.test(nodeName))
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (pattern.hasChild !== undefined) {
|
|
351
|
+
const childNodes = node.children ?? [];
|
|
352
|
+
if (!childNodes.some((c) => this.matchesPattern(c, pattern.hasChild))) {
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (pattern.hasParent !== undefined) {
|
|
357
|
+
if (!node.parent)
|
|
358
|
+
return false;
|
|
359
|
+
if (!this.matchesPattern(node.parent, pattern.hasParent))
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
if (pattern.custom !== undefined) {
|
|
363
|
+
if (!pattern.custom(node))
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
extractName(node) {
|
|
369
|
+
switch (node.type) {
|
|
370
|
+
case 'function_declaration':
|
|
371
|
+
case 'type_spec':
|
|
372
|
+
case 'field_declaration':
|
|
373
|
+
case 'method_spec': {
|
|
374
|
+
const nameNode = node.childForFieldName?.('name');
|
|
375
|
+
if (nameNode)
|
|
376
|
+
return nameNode.text;
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
case 'import_spec': {
|
|
380
|
+
const nameNode = node.childForFieldName?.('name');
|
|
381
|
+
if (nameNode)
|
|
382
|
+
return nameNode.text;
|
|
383
|
+
for (const child of node.namedChildren) {
|
|
384
|
+
if (child.type === 'interpreted_string_literal' ||
|
|
385
|
+
child.type === 'raw_string_literal') {
|
|
386
|
+
return child.text.slice(1, -1);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
case 'package_identifier':
|
|
392
|
+
case 'identifier':
|
|
393
|
+
return node.text;
|
|
394
|
+
default:
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
extractDocumentation(node) {
|
|
399
|
+
const parent = node.parent;
|
|
400
|
+
if (!parent)
|
|
401
|
+
return null;
|
|
402
|
+
const siblings = parent.namedChildren;
|
|
403
|
+
let myIndex = -1;
|
|
404
|
+
for (let i = 0; i < siblings.length; i++) {
|
|
405
|
+
if (siblings[i] === node) {
|
|
406
|
+
myIndex = i;
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (myIndex === -1)
|
|
411
|
+
return null;
|
|
412
|
+
const comments = [];
|
|
413
|
+
for (let i = myIndex - 1; i >= 0; i--) {
|
|
414
|
+
const sibling = siblings[i];
|
|
415
|
+
if (sibling.type === 'comment') {
|
|
416
|
+
comments.unshift(sibling.text);
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (comments.length === 0)
|
|
423
|
+
return null;
|
|
424
|
+
return this.cleanCommentText(comments.join('\n').trim());
|
|
425
|
+
}
|
|
426
|
+
cleanCommentText(comment) {
|
|
427
|
+
if (comment.startsWith('/*')) {
|
|
428
|
+
let inner = comment.slice(2, -2);
|
|
429
|
+
inner = inner
|
|
430
|
+
.split('\n')
|
|
431
|
+
.map((line) => line.replace(/^\s*\*\s?/, ''))
|
|
432
|
+
.join('\n');
|
|
433
|
+
return inner.trim();
|
|
434
|
+
}
|
|
435
|
+
if (comment.startsWith('//')) {
|
|
436
|
+
return comment.replace(/^\/\/\s*/, '').trim();
|
|
437
|
+
}
|
|
438
|
+
return comment.trim();
|
|
439
|
+
}
|
|
440
|
+
calculateComplexity(node) {
|
|
441
|
+
let complexity = 1;
|
|
442
|
+
this.walkRaw(node, (child) => {
|
|
443
|
+
if (child === node)
|
|
444
|
+
return;
|
|
445
|
+
switch (child.type) {
|
|
446
|
+
case 'if_statement':
|
|
447
|
+
case 'for_statement':
|
|
448
|
+
case 'switch_statement':
|
|
449
|
+
case 'expression_switch_statement':
|
|
450
|
+
case 'type_switch_statement':
|
|
451
|
+
case 'select_statement':
|
|
452
|
+
case 'type_case_clause':
|
|
453
|
+
case 'expression_case_clause':
|
|
454
|
+
case 'default_case':
|
|
455
|
+
case 'communication_case':
|
|
456
|
+
complexity++;
|
|
457
|
+
break;
|
|
458
|
+
case 'binary_expression': {
|
|
459
|
+
const op = this.getOperator(child);
|
|
460
|
+
if (op === '&&' || op === '||')
|
|
461
|
+
complexity++;
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
return complexity;
|
|
467
|
+
}
|
|
468
|
+
getOperator(node) {
|
|
469
|
+
for (const child of node.children) {
|
|
470
|
+
if (!child.isNamed &&
|
|
471
|
+
['&&', '||', '+', '-', '*', '/', '%', '==', '!='].includes(child.type)) {
|
|
472
|
+
return child.type;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
// -- Build helpers ---------------------------------------------------------
|
|
478
|
+
buildFunctionInfo(node, sourceCode) {
|
|
479
|
+
const name = this.extractName(node);
|
|
480
|
+
const isMethod = node.childForFieldName?.('receiver') != null;
|
|
481
|
+
const isExported = name ? this.isExportedGo(name) : false;
|
|
482
|
+
const className = isMethod ? this.getReceiverType(node) : undefined;
|
|
483
|
+
const returnType = this.getReturnType(node);
|
|
484
|
+
const jsDoc = this.extractDocumentation(node);
|
|
485
|
+
const parameters = this.extractParameters(node, sourceCode);
|
|
486
|
+
return {
|
|
487
|
+
name: name ?? '<anonymous>',
|
|
488
|
+
location: toSourceLocation(node),
|
|
489
|
+
parameters,
|
|
490
|
+
returnType: returnType ?? undefined,
|
|
491
|
+
isAsync: false,
|
|
492
|
+
isExported,
|
|
493
|
+
isMethod,
|
|
494
|
+
className,
|
|
495
|
+
jsDoc: jsDoc ?? undefined,
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
buildStructAsClass(_typeSpec, nameNode, typeNode, allFunctions, _sourceCode) {
|
|
499
|
+
const name = nameNode.text;
|
|
500
|
+
const isExported = this.isExportedGo(name);
|
|
501
|
+
const jsDoc = this.extractDocumentation(_typeSpec);
|
|
502
|
+
// Collect fields as properties
|
|
503
|
+
const properties = [];
|
|
504
|
+
for (const field of this.findNamedChildren(typeNode, 'field_declaration')) {
|
|
505
|
+
const propName = this.extractName(field);
|
|
506
|
+
const typeNode_ = field.childForFieldName?.('type');
|
|
507
|
+
if (propName) {
|
|
508
|
+
properties.push({
|
|
509
|
+
name: propName,
|
|
510
|
+
type: typeNode_?.text,
|
|
511
|
+
visibility: this.isExportedGo(propName) ? 'public' : 'private',
|
|
512
|
+
isStatic: false,
|
|
513
|
+
isReadonly: false,
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
// Match methods with this receiver type
|
|
518
|
+
const methods = allFunctions.filter((fn) => fn.className === name || fn.className === `*${name}`);
|
|
519
|
+
return {
|
|
520
|
+
name,
|
|
521
|
+
location: toSourceLocation(nameNode),
|
|
522
|
+
methods,
|
|
523
|
+
properties,
|
|
524
|
+
isAbstract: false,
|
|
525
|
+
isExported,
|
|
526
|
+
jsDoc: jsDoc ?? undefined,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
buildImportInfo(spec) {
|
|
530
|
+
let source = '';
|
|
531
|
+
let alias;
|
|
532
|
+
for (const child of spec.namedChildren) {
|
|
533
|
+
if (child.type === 'interpreted_string_literal' ||
|
|
534
|
+
child.type === 'raw_string_literal') {
|
|
535
|
+
source = child.text.slice(1, -1);
|
|
536
|
+
}
|
|
537
|
+
else if (child.type === 'package_identifier' ||
|
|
538
|
+
child.type === 'identifier') {
|
|
539
|
+
alias = child.text;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
if (!source)
|
|
543
|
+
return null;
|
|
544
|
+
return {
|
|
545
|
+
source,
|
|
546
|
+
specifiers: [
|
|
547
|
+
{
|
|
548
|
+
name: source,
|
|
549
|
+
alias,
|
|
550
|
+
isDefault: false,
|
|
551
|
+
isNamespace: false,
|
|
552
|
+
},
|
|
553
|
+
],
|
|
554
|
+
location: toSourceLocation(spec),
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
buildInterfaceInfo(nameNode, typeNode) {
|
|
558
|
+
const name = nameNode.text;
|
|
559
|
+
const isExported = this.isExportedGo(name);
|
|
560
|
+
const members = [];
|
|
561
|
+
for (const member of typeNode.namedChildren) {
|
|
562
|
+
if (member.type === 'method_spec') {
|
|
563
|
+
const memberNameNode = member.childForFieldName?.('name');
|
|
564
|
+
if (memberNameNode) {
|
|
565
|
+
members.push({
|
|
566
|
+
name: memberNameNode.text,
|
|
567
|
+
type: 'method',
|
|
568
|
+
location: toSourceLocation(member),
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
else if (member.type === 'type_elem') {
|
|
573
|
+
const embeddedName = member.childForFieldName?.('name')?.text ?? member.text;
|
|
574
|
+
if (embeddedName) {
|
|
575
|
+
members.push({
|
|
576
|
+
name: embeddedName,
|
|
577
|
+
type: 'property',
|
|
578
|
+
location: toSourceLocation(member),
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
return {
|
|
584
|
+
name,
|
|
585
|
+
location: toSourceLocation(nameNode),
|
|
586
|
+
members,
|
|
587
|
+
isExported,
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
extractParameters(node, _sourceCode) {
|
|
591
|
+
const params = [];
|
|
592
|
+
const paramList = node.childForFieldName?.('parameters');
|
|
593
|
+
if (!paramList)
|
|
594
|
+
return params;
|
|
595
|
+
for (const child of paramList.namedChildren) {
|
|
596
|
+
if (child.type === 'parameter_declaration') {
|
|
597
|
+
const nameNode = child.childForFieldName?.('name');
|
|
598
|
+
const typeNode = child.childForFieldName?.('type');
|
|
599
|
+
const name = nameNode?.text ?? typeNode?.text ?? child.text;
|
|
600
|
+
params.push({
|
|
601
|
+
name: name || '<unknown>',
|
|
602
|
+
type: typeNode?.text,
|
|
603
|
+
optional: false,
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return params;
|
|
608
|
+
}
|
|
609
|
+
// -- Go-specific helpers ---------------------------------------------------
|
|
610
|
+
isExportedGo(name) {
|
|
611
|
+
return name.length > 0 && name[0] === name[0].toUpperCase();
|
|
612
|
+
}
|
|
613
|
+
getReceiverType(node) {
|
|
614
|
+
const receiver = node.childForFieldName?.('receiver');
|
|
615
|
+
if (!receiver)
|
|
616
|
+
return undefined;
|
|
617
|
+
for (const child of receiver.namedChildren) {
|
|
618
|
+
if (child.type === 'parameter_declaration') {
|
|
619
|
+
const typeNode = child.childForFieldName?.('type');
|
|
620
|
+
if (typeNode)
|
|
621
|
+
return typeNode.text;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return undefined;
|
|
625
|
+
}
|
|
626
|
+
getReturnType(node) {
|
|
627
|
+
if (node.type !== 'function_declaration')
|
|
628
|
+
return null;
|
|
629
|
+
const result = node.childForFieldName?.('result');
|
|
630
|
+
if (result)
|
|
631
|
+
return result.text.trim();
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
// -- Tree traversal helpers ------------------------------------------------
|
|
635
|
+
findNamedChildren(node, type) {
|
|
636
|
+
return node.namedChildren.filter((c) => c.type === type);
|
|
358
637
|
}
|
|
359
638
|
}
|
|
360
639
|
//# sourceMappingURL=GoAdapter.js.map
|