codeguardian-mcp 1.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/LICENSE +21 -0
- package/README.md +348 -0
- package/dist/agent/agentTools.d.ts +26 -0
- package/dist/agent/agentTools.d.ts.map +1 -0
- package/dist/agent/agentTools.js +699 -0
- package/dist/agent/agentTools.js.map +1 -0
- package/dist/agent/autoValidator.d.ts +110 -0
- package/dist/agent/autoValidator.d.ts.map +1 -0
- package/dist/agent/autoValidator.js +964 -0
- package/dist/agent/autoValidator.js.map +1 -0
- package/dist/agent/fileWatcher.d.ts +28 -0
- package/dist/agent/fileWatcher.d.ts.map +1 -0
- package/dist/agent/fileWatcher.js +88 -0
- package/dist/agent/fileWatcher.js.map +1 -0
- package/dist/agent/guardianPersistence.d.ts +98 -0
- package/dist/agent/guardianPersistence.d.ts.map +1 -0
- package/dist/agent/guardianPersistence.js +296 -0
- package/dist/agent/guardianPersistence.js.map +1 -0
- package/dist/agent/mcpNotifications.d.ts +38 -0
- package/dist/agent/mcpNotifications.d.ts.map +1 -0
- package/dist/agent/mcpNotifications.js +81 -0
- package/dist/agent/mcpNotifications.js.map +1 -0
- package/dist/analyzers/aiPatterns.d.ts +16 -0
- package/dist/analyzers/aiPatterns.d.ts.map +1 -0
- package/dist/analyzers/aiPatterns.js +103 -0
- package/dist/analyzers/aiPatterns.js.map +1 -0
- package/dist/analyzers/antiPatterns.d.ts +60 -0
- package/dist/analyzers/antiPatterns.d.ts.map +1 -0
- package/dist/analyzers/antiPatterns.js +198 -0
- package/dist/analyzers/antiPatterns.js.map +1 -0
- package/dist/analyzers/builtinTypes.d.ts +18 -0
- package/dist/analyzers/builtinTypes.d.ts.map +1 -0
- package/dist/analyzers/builtinTypes.js +1275 -0
- package/dist/analyzers/builtinTypes.js.map +1 -0
- package/dist/analyzers/complexity.d.ts +14 -0
- package/dist/analyzers/complexity.d.ts.map +1 -0
- package/dist/analyzers/complexity.js +610 -0
- package/dist/analyzers/complexity.js.map +1 -0
- package/dist/analyzers/findingVerifier.d.ts +59 -0
- package/dist/analyzers/findingVerifier.d.ts.map +1 -0
- package/dist/analyzers/findingVerifier.js +1169 -0
- package/dist/analyzers/findingVerifier.js.map +1 -0
- package/dist/analyzers/impactAnalyzer.d.ts +53 -0
- package/dist/analyzers/impactAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/impactAnalyzer.js +152 -0
- package/dist/analyzers/impactAnalyzer.js.map +1 -0
- package/dist/analyzers/languageDetector.d.ts +48 -0
- package/dist/analyzers/languageDetector.d.ts.map +1 -0
- package/dist/analyzers/languageDetector.js +404 -0
- package/dist/analyzers/languageDetector.js.map +1 -0
- package/dist/analyzers/parsers/incrementalParser.d.ts +53 -0
- package/dist/analyzers/parsers/incrementalParser.d.ts.map +1 -0
- package/dist/analyzers/parsers/incrementalParser.js +193 -0
- package/dist/analyzers/parsers/incrementalParser.js.map +1 -0
- package/dist/analyzers/parsers/scopeResolver.d.ts +92 -0
- package/dist/analyzers/parsers/scopeResolver.d.ts.map +1 -0
- package/dist/analyzers/parsers/scopeResolver.js +324 -0
- package/dist/analyzers/parsers/scopeResolver.js.map +1 -0
- package/dist/analyzers/parsers/semanticIndex.d.ts +127 -0
- package/dist/analyzers/parsers/semanticIndex.d.ts.map +1 -0
- package/dist/analyzers/parsers/semanticIndex.js +429 -0
- package/dist/analyzers/parsers/semanticIndex.js.map +1 -0
- package/dist/analyzers/parsers/sessionDiffAnalyzer.d.ts +42 -0
- package/dist/analyzers/parsers/sessionDiffAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/parsers/sessionDiffAnalyzer.js +233 -0
- package/dist/analyzers/parsers/sessionDiffAnalyzer.js.map +1 -0
- package/dist/analyzers/parsers/treeSitterParser.d.ts +76 -0
- package/dist/analyzers/parsers/treeSitterParser.d.ts.map +1 -0
- package/dist/analyzers/parsers/treeSitterParser.js +709 -0
- package/dist/analyzers/parsers/treeSitterParser.js.map +1 -0
- package/dist/analyzers/relevanceScorer.d.ts +43 -0
- package/dist/analyzers/relevanceScorer.d.ts.map +1 -0
- package/dist/analyzers/relevanceScorer.js +200 -0
- package/dist/analyzers/relevanceScorer.js.map +1 -0
- package/dist/analyzers/standardLibrary.d.ts +22 -0
- package/dist/analyzers/standardLibrary.d.ts.map +1 -0
- package/dist/analyzers/standardLibrary.js +211 -0
- package/dist/analyzers/standardLibrary.js.map +1 -0
- package/dist/analyzers/symbolGraph.d.ts +30 -0
- package/dist/analyzers/symbolGraph.d.ts.map +1 -0
- package/dist/analyzers/symbolGraph.js +380 -0
- package/dist/analyzers/symbolGraph.js.map +1 -0
- package/dist/analyzers/symbolTable.d.ts +18 -0
- package/dist/analyzers/symbolTable.d.ts.map +1 -0
- package/dist/analyzers/symbolTable.js +176 -0
- package/dist/analyzers/symbolTable.js.map +1 -0
- package/dist/analyzers/typeChecker.d.ts +13 -0
- package/dist/analyzers/typeChecker.d.ts.map +1 -0
- package/dist/analyzers/typeChecker.js +580 -0
- package/dist/analyzers/typeChecker.js.map +1 -0
- package/dist/analyzers/usagePatterns.d.ts +42 -0
- package/dist/analyzers/usagePatterns.d.ts.map +1 -0
- package/dist/analyzers/usagePatterns.js +75 -0
- package/dist/analyzers/usagePatterns.js.map +1 -0
- package/dist/api-contract/context/backend.d.ts +19 -0
- package/dist/api-contract/context/backend.d.ts.map +1 -0
- package/dist/api-contract/context/backend.js +64 -0
- package/dist/api-contract/context/backend.js.map +1 -0
- package/dist/api-contract/context/contract.d.ts +34 -0
- package/dist/api-contract/context/contract.d.ts.map +1 -0
- package/dist/api-contract/context/contract.js +306 -0
- package/dist/api-contract/context/contract.js.map +1 -0
- package/dist/api-contract/context/frontend.d.ts +19 -0
- package/dist/api-contract/context/frontend.d.ts.map +1 -0
- package/dist/api-contract/context/frontend.js +64 -0
- package/dist/api-contract/context/frontend.js.map +1 -0
- package/dist/api-contract/detector.d.ts +28 -0
- package/dist/api-contract/detector.d.ts.map +1 -0
- package/dist/api-contract/detector.js +393 -0
- package/dist/api-contract/detector.js.map +1 -0
- package/dist/api-contract/extractors/python.d.ts +32 -0
- package/dist/api-contract/extractors/python.d.ts.map +1 -0
- package/dist/api-contract/extractors/python.js +521 -0
- package/dist/api-contract/extractors/python.js.map +1 -0
- package/dist/api-contract/extractors/pythonAstUtils.d.ts +44 -0
- package/dist/api-contract/extractors/pythonAstUtils.d.ts.map +1 -0
- package/dist/api-contract/extractors/pythonAstUtils.js +489 -0
- package/dist/api-contract/extractors/pythonAstUtils.js.map +1 -0
- package/dist/api-contract/extractors/tsAstUtils.d.ts +47 -0
- package/dist/api-contract/extractors/tsAstUtils.d.ts.map +1 -0
- package/dist/api-contract/extractors/tsAstUtils.js +173 -0
- package/dist/api-contract/extractors/tsAstUtils.js.map +1 -0
- package/dist/api-contract/extractors/typescript.d.ts +32 -0
- package/dist/api-contract/extractors/typescript.d.ts.map +1 -0
- package/dist/api-contract/extractors/typescript.js +666 -0
- package/dist/api-contract/extractors/typescript.js.map +1 -0
- package/dist/api-contract/index.d.ts +104 -0
- package/dist/api-contract/index.d.ts.map +1 -0
- package/dist/api-contract/index.js +232 -0
- package/dist/api-contract/index.js.map +1 -0
- package/dist/api-contract/types.d.ts +151 -0
- package/dist/api-contract/types.d.ts.map +1 -0
- package/dist/api-contract/types.js +19 -0
- package/dist/api-contract/types.js.map +1 -0
- package/dist/api-contract/validators/endpoint.d.ts +21 -0
- package/dist/api-contract/validators/endpoint.d.ts.map +1 -0
- package/dist/api-contract/validators/endpoint.js +224 -0
- package/dist/api-contract/validators/endpoint.js.map +1 -0
- package/dist/api-contract/validators/index.d.ts +40 -0
- package/dist/api-contract/validators/index.d.ts.map +1 -0
- package/dist/api-contract/validators/index.js +875 -0
- package/dist/api-contract/validators/index.js.map +1 -0
- package/dist/api-contract/validators/parameter.d.ts +17 -0
- package/dist/api-contract/validators/parameter.d.ts.map +1 -0
- package/dist/api-contract/validators/parameter.js +250 -0
- package/dist/api-contract/validators/parameter.js.map +1 -0
- package/dist/api-contract/validators/type.d.ts +38 -0
- package/dist/api-contract/validators/type.d.ts.map +1 -0
- package/dist/api-contract/validators/type.js +244 -0
- package/dist/api-contract/validators/type.js.map +1 -0
- package/dist/context/apiContract/complexTypeSupport.d.ts +83 -0
- package/dist/context/apiContract/complexTypeSupport.d.ts.map +1 -0
- package/dist/context/apiContract/complexTypeSupport.js +665 -0
- package/dist/context/apiContract/complexTypeSupport.js.map +1 -0
- package/dist/context/apiContract/graphqlSupport.d.ts +105 -0
- package/dist/context/apiContract/graphqlSupport.d.ts.map +1 -0
- package/dist/context/apiContract/graphqlSupport.js +671 -0
- package/dist/context/apiContract/graphqlSupport.js.map +1 -0
- package/dist/context/apiContract/index.d.ts +14 -0
- package/dist/context/apiContract/index.d.ts.map +1 -0
- package/dist/context/apiContract/index.js +17 -0
- package/dist/context/apiContract/index.js.map +1 -0
- package/dist/context/apiContract/webSocketSupport.d.ts +104 -0
- package/dist/context/apiContract/webSocketSupport.d.ts.map +1 -0
- package/dist/context/apiContract/webSocketSupport.js +465 -0
- package/dist/context/apiContract/webSocketSupport.js.map +1 -0
- package/dist/context/apiContractContext.d.ts +15 -0
- package/dist/context/apiContractContext.d.ts.map +1 -0
- package/dist/context/apiContractContext.js +979 -0
- package/dist/context/apiContractContext.js.map +1 -0
- package/dist/context/apiContractExtraction.d.ts +52 -0
- package/dist/context/apiContractExtraction.d.ts.map +1 -0
- package/dist/context/apiContractExtraction.js +438 -0
- package/dist/context/apiContractExtraction.js.map +1 -0
- package/dist/context/contextLineage.d.ts +79 -0
- package/dist/context/contextLineage.d.ts.map +1 -0
- package/dist/context/contextLineage.js +259 -0
- package/dist/context/contextLineage.js.map +1 -0
- package/dist/context/contextOrchestrator.d.ts +57 -0
- package/dist/context/contextOrchestrator.d.ts.map +1 -0
- package/dist/context/contextOrchestrator.js +162 -0
- package/dist/context/contextOrchestrator.js.map +1 -0
- package/dist/context/intentTracker.d.ts +73 -0
- package/dist/context/intentTracker.d.ts.map +1 -0
- package/dist/context/intentTracker.js +168 -0
- package/dist/context/intentTracker.js.map +1 -0
- package/dist/context/projectContext.d.ts +219 -0
- package/dist/context/projectContext.d.ts.map +1 -0
- package/dist/context/projectContext.js +1984 -0
- package/dist/context/projectContext.js.map +1 -0
- package/dist/prompts/index.d.ts +17 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +260 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/library.d.ts +51 -0
- package/dist/prompts/library.d.ts.map +1 -0
- package/dist/prompts/library.js +65 -0
- package/dist/prompts/library.js.map +1 -0
- package/dist/prompts/templates.d.ts +44 -0
- package/dist/prompts/templates.d.ts.map +1 -0
- package/dist/prompts/templates.js +97 -0
- package/dist/prompts/templates.js.map +1 -0
- package/dist/queue/jobPersistence.d.ts +46 -0
- package/dist/queue/jobPersistence.d.ts.map +1 -0
- package/dist/queue/jobPersistence.js +158 -0
- package/dist/queue/jobPersistence.js.map +1 -0
- package/dist/queue/jobQueue.d.ts +116 -0
- package/dist/queue/jobQueue.d.ts.map +1 -0
- package/dist/queue/jobQueue.js +275 -0
- package/dist/queue/jobQueue.js.map +1 -0
- package/dist/queue/validationJob.d.ts +69 -0
- package/dist/queue/validationJob.d.ts.map +1 -0
- package/dist/queue/validationJob.js +435 -0
- package/dist/queue/validationJob.js.map +1 -0
- package/dist/resources/index.d.ts +15 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +328 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/validationReportStore.d.ts +170 -0
- package/dist/resources/validationReportStore.d.ts.map +1 -0
- package/dist/resources/validationReportStore.js +515 -0
- package/dist/resources/validationReportStore.js.map +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +102 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/asyncValidation.d.ts +19 -0
- package/dist/tools/asyncValidation.d.ts.map +1 -0
- package/dist/tools/asyncValidation.js +346 -0
- package/dist/tools/asyncValidation.js.map +1 -0
- package/dist/tools/buildContext.d.ts +17 -0
- package/dist/tools/buildContext.d.ts.map +1 -0
- package/dist/tools/buildContext.js +188 -0
- package/dist/tools/buildContext.js.map +1 -0
- package/dist/tools/getDependencyGraph.d.ts +16 -0
- package/dist/tools/getDependencyGraph.d.ts.map +1 -0
- package/dist/tools/getDependencyGraph.js +436 -0
- package/dist/tools/getDependencyGraph.js.map +1 -0
- package/dist/tools/incrementalValidation.d.ts +71 -0
- package/dist/tools/incrementalValidation.d.ts.map +1 -0
- package/dist/tools/incrementalValidation.js +203 -0
- package/dist/tools/incrementalValidation.js.map +1 -0
- package/dist/tools/index.d.ts +24 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +106 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/validateCode.d.ts +17 -0
- package/dist/tools/validateCode.d.ts.map +1 -0
- package/dist/tools/validateCode.js +368 -0
- package/dist/tools/validateCode.js.map +1 -0
- package/dist/tools/validateCodeLite.d.ts +2 -0
- package/dist/tools/validateCodeLite.d.ts.map +1 -0
- package/dist/tools/validateCodeLite.js +2 -0
- package/dist/tools/validateCodeLite.js.map +1 -0
- package/dist/tools/validation/builtins.d.ts +92 -0
- package/dist/tools/validation/builtins.d.ts.map +1 -0
- package/dist/tools/validation/builtins.js +2184 -0
- package/dist/tools/validation/builtins.js.map +1 -0
- package/dist/tools/validation/contextualNaming.d.ts +99 -0
- package/dist/tools/validation/contextualNaming.d.ts.map +1 -0
- package/dist/tools/validation/contextualNaming.js +959 -0
- package/dist/tools/validation/contextualNaming.js.map +1 -0
- package/dist/tools/validation/deadCode.d.ts +115 -0
- package/dist/tools/validation/deadCode.d.ts.map +1 -0
- package/dist/tools/validation/deadCode.js +861 -0
- package/dist/tools/validation/deadCode.js.map +1 -0
- package/dist/tools/validation/extractors/index.d.ts +131 -0
- package/dist/tools/validation/extractors/index.d.ts.map +1 -0
- package/dist/tools/validation/extractors/index.js +233 -0
- package/dist/tools/validation/extractors/index.js.map +1 -0
- package/dist/tools/validation/extractors/javascript.d.ts +73 -0
- package/dist/tools/validation/extractors/javascript.d.ts.map +1 -0
- package/dist/tools/validation/extractors/javascript.js +1841 -0
- package/dist/tools/validation/extractors/javascript.js.map +1 -0
- package/dist/tools/validation/extractors/python.d.ts +93 -0
- package/dist/tools/validation/extractors/python.d.ts.map +1 -0
- package/dist/tools/validation/extractors/python.js +799 -0
- package/dist/tools/validation/extractors/python.js.map +1 -0
- package/dist/tools/validation/manifest.d.ts +45 -0
- package/dist/tools/validation/manifest.d.ts.map +1 -0
- package/dist/tools/validation/manifest.js +719 -0
- package/dist/tools/validation/manifest.js.map +1 -0
- package/dist/tools/validation/parser.d.ts +58 -0
- package/dist/tools/validation/parser.d.ts.map +1 -0
- package/dist/tools/validation/parser.js +232 -0
- package/dist/tools/validation/parser.js.map +1 -0
- package/dist/tools/validation/registry.d.ts +15 -0
- package/dist/tools/validation/registry.d.ts.map +1 -0
- package/dist/tools/validation/registry.js +169 -0
- package/dist/tools/validation/registry.js.map +1 -0
- package/dist/tools/validation/scoring.d.ts +54 -0
- package/dist/tools/validation/scoring.d.ts.map +1 -0
- package/dist/tools/validation/scoring.js +242 -0
- package/dist/tools/validation/scoring.js.map +1 -0
- package/dist/tools/validation/types.d.ts +120 -0
- package/dist/tools/validation/types.d.ts.map +1 -0
- package/dist/tools/validation/types.js +11 -0
- package/dist/tools/validation/types.js.map +1 -0
- package/dist/tools/validation/unusedLocals.d.ts +36 -0
- package/dist/tools/validation/unusedLocals.d.ts.map +1 -0
- package/dist/tools/validation/unusedLocals.js +333 -0
- package/dist/tools/validation/unusedLocals.js.map +1 -0
- package/dist/tools/validation/validation.d.ts +98 -0
- package/dist/tools/validation/validation.d.ts.map +1 -0
- package/dist/tools/validation/validation.js +1837 -0
- package/dist/tools/validation/validation.js.map +1 -0
- package/dist/types/codeGraph.d.ts +163 -0
- package/dist/types/codeGraph.d.ts.map +1 -0
- package/dist/types/codeGraph.js +9 -0
- package/dist/types/codeGraph.js.map +1 -0
- package/dist/types/symbolGraph.d.ts +68 -0
- package/dist/types/symbolGraph.d.ts.map +1 -0
- package/dist/types/symbolGraph.js +10 -0
- package/dist/types/symbolGraph.js.map +1 -0
- package/dist/types/tools.d.ts +43 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +7 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/fileFilter.d.ts +37 -0
- package/dist/utils/fileFilter.d.ts.map +1 -0
- package/dist/utils/fileFilter.js +91 -0
- package/dist/utils/fileFilter.js.map +1 -0
- package/dist/utils/gitUtils.d.ts +28 -0
- package/dist/utils/gitUtils.d.ts.map +1 -0
- package/dist/utils/gitUtils.js +81 -0
- package/dist/utils/gitUtils.js.map +1 -0
- package/dist/utils/logger.d.ts +15 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +38 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/serialization.d.ts +25 -0
- package/dist/utils/serialization.d.ts.map +1 -0
- package/dist/utils/serialization.js +53 -0
- package/dist/utils/serialization.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language Detector
|
|
3
|
+
*
|
|
4
|
+
* Automatically detects programming language from file path or code content
|
|
5
|
+
* Uses multiple strategies: extension, content analysis, shebang
|
|
6
|
+
*/
|
|
7
|
+
import { logger } from '../utils/logger.js';
|
|
8
|
+
import { getParser } from "../tools/validation/parser.js";
|
|
9
|
+
/**
|
|
10
|
+
* File extension to language mapping
|
|
11
|
+
*/
|
|
12
|
+
const EXTENSION_MAP = {
|
|
13
|
+
// JavaScript/TypeScript
|
|
14
|
+
'.js': 'javascript',
|
|
15
|
+
'.jsx': 'javascript',
|
|
16
|
+
'.mjs': 'javascript',
|
|
17
|
+
'.cjs': 'javascript',
|
|
18
|
+
'.ts': 'typescript',
|
|
19
|
+
'.tsx': 'typescript',
|
|
20
|
+
'.mts': 'typescript',
|
|
21
|
+
'.cts': 'typescript',
|
|
22
|
+
// Python
|
|
23
|
+
'.py': 'python',
|
|
24
|
+
'.pyw': 'python',
|
|
25
|
+
'.pyi': 'python',
|
|
26
|
+
// Go
|
|
27
|
+
'.go': 'go',
|
|
28
|
+
// Java
|
|
29
|
+
'.java': 'java',
|
|
30
|
+
// C/C++
|
|
31
|
+
'.c': 'c',
|
|
32
|
+
'.cpp': 'cpp',
|
|
33
|
+
'.cc': 'cpp',
|
|
34
|
+
'.cxx': 'cpp',
|
|
35
|
+
'.h': 'c',
|
|
36
|
+
'.hpp': 'cpp',
|
|
37
|
+
// Rust
|
|
38
|
+
'.rs': 'rust',
|
|
39
|
+
// Ruby
|
|
40
|
+
'.rb': 'ruby',
|
|
41
|
+
// PHP
|
|
42
|
+
'.php': 'php',
|
|
43
|
+
// Shell
|
|
44
|
+
'.sh': 'shell',
|
|
45
|
+
'.bash': 'shell',
|
|
46
|
+
'.zsh': 'shell',
|
|
47
|
+
// Other
|
|
48
|
+
'.json': 'json',
|
|
49
|
+
'.yaml': 'yaml',
|
|
50
|
+
'.yml': 'yaml',
|
|
51
|
+
'.xml': 'xml',
|
|
52
|
+
'.html': 'html',
|
|
53
|
+
'.css': 'css',
|
|
54
|
+
'.sql': 'sql',
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Language-specific keywords for content-based detection
|
|
58
|
+
*/
|
|
59
|
+
const LANGUAGE_KEYWORDS = {
|
|
60
|
+
javascript: [
|
|
61
|
+
'function', 'const', 'let', 'var', 'async', 'await', 'import', 'export',
|
|
62
|
+
'class', 'extends', 'constructor', 'this', 'new', 'typeof', 'instanceof',
|
|
63
|
+
'console.log', 'require', 'module.exports', '=>'
|
|
64
|
+
],
|
|
65
|
+
typescript: [
|
|
66
|
+
'interface', 'type', 'enum', 'namespace', 'declare', 'implements',
|
|
67
|
+
'public', 'private', 'protected', 'readonly', 'abstract', ': string',
|
|
68
|
+
': number', ': boolean', '<T>', 'as const'
|
|
69
|
+
],
|
|
70
|
+
python: [
|
|
71
|
+
'def', 'class', 'import', 'from', 'if __name__', 'self', 'None', 'True',
|
|
72
|
+
'False', 'elif', 'except', 'finally', 'with', 'as', 'lambda', 'yield',
|
|
73
|
+
'async def', 'await', '__init__', 'print('
|
|
74
|
+
],
|
|
75
|
+
go: [
|
|
76
|
+
'package', 'func', 'import', 'type', 'struct', 'interface', 'defer',
|
|
77
|
+
'go func', 'chan', 'select', 'case', 'range', 'make', 'new', ':='
|
|
78
|
+
],
|
|
79
|
+
java: [
|
|
80
|
+
'public class', 'private', 'protected', 'static', 'void', 'extends',
|
|
81
|
+
'implements', 'interface', 'abstract', 'final', 'synchronized',
|
|
82
|
+
'throws', 'try', 'catch', 'finally', 'new', 'this', 'super'
|
|
83
|
+
],
|
|
84
|
+
ruby: [
|
|
85
|
+
'def', 'end', 'class', 'module', 'require', 'include', 'attr_accessor',
|
|
86
|
+
'puts', 'gets', 'do', 'yield', 'lambda', 'proc', '@', '@@'
|
|
87
|
+
],
|
|
88
|
+
php: [
|
|
89
|
+
'<?php', 'function', 'class', 'namespace', 'use', 'public', 'private',
|
|
90
|
+
'protected', 'static', '$', '->', '=>', 'echo', 'print', 'require'
|
|
91
|
+
],
|
|
92
|
+
rust: [
|
|
93
|
+
'fn', 'let', 'mut', 'impl', 'trait', 'struct', 'enum', 'match',
|
|
94
|
+
'pub', 'use', 'mod', 'crate', '&', 'Box<', 'Vec<', 'Option<'
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Framework-specific patterns
|
|
99
|
+
*/
|
|
100
|
+
const FRAMEWORK_PATTERNS = {
|
|
101
|
+
react: { pattern: /import.*from\s+['"]react['"]|React\.|useState|useEffect/i, language: 'javascript' },
|
|
102
|
+
vue: { pattern: /import.*from\s+['"]vue['"]|Vue\.|<template>|<script>/i, language: 'javascript' },
|
|
103
|
+
angular: { pattern: /@Component|@Injectable|@NgModule|import.*from\s+['"]@angular/i, language: 'typescript' },
|
|
104
|
+
django: { pattern: /from\s+django\.|import\s+django|models\.Model|views\./i, language: 'python' },
|
|
105
|
+
flask: { pattern: /from\s+flask\s+import|@app\.route|Flask\(__name__\)/i, language: 'python' },
|
|
106
|
+
fastapi: { pattern: /from\s+fastapi\s+import|@app\.(get|post|put|delete)|FastAPI\(/i, language: 'python' },
|
|
107
|
+
express: { pattern: /require\(['"]express['"]\)|express\(\)|app\.(get|post|put|delete)/i, language: 'javascript' },
|
|
108
|
+
nextjs: { pattern: /from\s+['"]next\/|export\s+default\s+function.*\(\s*\)\s*\{|getServerSideProps|getStaticProps/i, language: 'javascript' },
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Detect language from file path
|
|
112
|
+
*/
|
|
113
|
+
export function detectFromPath(filePath) {
|
|
114
|
+
const extension = filePath.substring(filePath.lastIndexOf('.')).toLowerCase();
|
|
115
|
+
const language = EXTENSION_MAP[extension];
|
|
116
|
+
if (language) {
|
|
117
|
+
logger.debug(`Detected ${language} from extension ${extension}`);
|
|
118
|
+
return {
|
|
119
|
+
language,
|
|
120
|
+
confidence: 100,
|
|
121
|
+
method: 'extension',
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Detect language from shebang line
|
|
128
|
+
*/
|
|
129
|
+
export function detectFromShebang(code) {
|
|
130
|
+
const firstLine = code.split('\n')[0].trim();
|
|
131
|
+
if (firstLine.startsWith('#!')) {
|
|
132
|
+
if (firstLine.includes('python')) {
|
|
133
|
+
return { language: 'python', confidence: 95, method: 'shebang' };
|
|
134
|
+
}
|
|
135
|
+
if (firstLine.includes('node')) {
|
|
136
|
+
return { language: 'javascript', confidence: 95, method: 'shebang' };
|
|
137
|
+
}
|
|
138
|
+
if (firstLine.includes('bash') || firstLine.includes('sh')) {
|
|
139
|
+
return { language: 'shell', confidence: 95, method: 'shebang' };
|
|
140
|
+
}
|
|
141
|
+
if (firstLine.includes('ruby')) {
|
|
142
|
+
return { language: 'ruby', confidence: 95, method: 'shebang' };
|
|
143
|
+
}
|
|
144
|
+
if (firstLine.includes('php')) {
|
|
145
|
+
return { language: 'php', confidence: 95, method: 'shebang' };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Detect framework from code content
|
|
152
|
+
*/
|
|
153
|
+
export function detectFramework(code) {
|
|
154
|
+
for (const [framework, { pattern, language }] of Object.entries(FRAMEWORK_PATTERNS)) {
|
|
155
|
+
if (pattern.test(code)) {
|
|
156
|
+
logger.debug(`Detected ${framework} framework`);
|
|
157
|
+
return { framework, language };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Detect language from code content
|
|
164
|
+
*/
|
|
165
|
+
export function detectFromContent(code) {
|
|
166
|
+
// Prefer AST-based detection for languages we can parse accurately.
|
|
167
|
+
// This reduces false positives from regex keyword matches in comments/strings.
|
|
168
|
+
const astDetected = detectFromContentAST(code);
|
|
169
|
+
if (astDetected)
|
|
170
|
+
return astDetected;
|
|
171
|
+
const scores = {};
|
|
172
|
+
// Count keyword matches for each language
|
|
173
|
+
for (const [language, keywords] of Object.entries(LANGUAGE_KEYWORDS)) {
|
|
174
|
+
let score = 0;
|
|
175
|
+
for (const keyword of keywords) {
|
|
176
|
+
const regex = new RegExp(keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g');
|
|
177
|
+
const matches = code.match(regex);
|
|
178
|
+
if (matches) {
|
|
179
|
+
score += matches.length;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
scores[language] = score;
|
|
183
|
+
}
|
|
184
|
+
// Find language with highest score
|
|
185
|
+
let maxScore = 0;
|
|
186
|
+
let detectedLanguage = '';
|
|
187
|
+
for (const [language, score] of Object.entries(scores)) {
|
|
188
|
+
if (score > maxScore) {
|
|
189
|
+
maxScore = score;
|
|
190
|
+
detectedLanguage = language;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (maxScore > 0) {
|
|
194
|
+
// Calculate confidence based on score
|
|
195
|
+
const totalKeywords = Object.values(scores).reduce((sum, score) => sum + score, 0);
|
|
196
|
+
const confidence = Math.min(90, Math.round((maxScore / totalKeywords) * 100));
|
|
197
|
+
logger.debug(`Detected ${detectedLanguage} from content with confidence ${confidence}%`);
|
|
198
|
+
return {
|
|
199
|
+
language: detectedLanguage,
|
|
200
|
+
confidence,
|
|
201
|
+
method: 'content',
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Detect language from code content using Tree-sitter.
|
|
208
|
+
*
|
|
209
|
+
* Only runs for languages supported by the validation parser cache.
|
|
210
|
+
*/
|
|
211
|
+
function detectFromContentAST(code) {
|
|
212
|
+
const candidates = ["typescript", "javascript", "python"];
|
|
213
|
+
const results = candidates.map((language) => {
|
|
214
|
+
const r = scoreTreeSitterParse(code, language);
|
|
215
|
+
return { language, ...r };
|
|
216
|
+
});
|
|
217
|
+
// Choose the best by totalScore; break ties with fewer errors.
|
|
218
|
+
results.sort((a, b) => {
|
|
219
|
+
if (b.totalScore !== a.totalScore)
|
|
220
|
+
return b.totalScore - a.totalScore;
|
|
221
|
+
return a.errorCount - b.errorCount;
|
|
222
|
+
});
|
|
223
|
+
const best = results[0];
|
|
224
|
+
const second = results[1];
|
|
225
|
+
// If parsing was too error-heavy, don't trust the AST signal.
|
|
226
|
+
if (!best || best.totalScore <= 0)
|
|
227
|
+
return null;
|
|
228
|
+
// If JS and TS are close, prefer TS only when TS-specific nodes exist.
|
|
229
|
+
let detectedLanguage = best.language;
|
|
230
|
+
if ((best.language === "typescript" || best.language === "javascript") &&
|
|
231
|
+
second &&
|
|
232
|
+
(second.language === "typescript" || second.language === "javascript")) {
|
|
233
|
+
const ts = results.find((r) => r.language === "typescript");
|
|
234
|
+
const js = results.find((r) => r.language === "javascript");
|
|
235
|
+
if (ts && js) {
|
|
236
|
+
const close = Math.abs(ts.totalScore - js.totalScore) <= 5;
|
|
237
|
+
if (close) {
|
|
238
|
+
detectedLanguage = ts.tsSpecificCount > 0 ? "typescript" : "javascript";
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const margin = second ? best.totalScore - second.totalScore : best.totalScore;
|
|
243
|
+
const confidence = Math.max(60, Math.min(90, 60 + margin * 3));
|
|
244
|
+
logger.debug(`Detected ${detectedLanguage} from AST content scoring (score=${best.totalScore}, errors=${best.errorCount})`);
|
|
245
|
+
return {
|
|
246
|
+
language: detectedLanguage,
|
|
247
|
+
confidence,
|
|
248
|
+
method: "content",
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function scoreTreeSitterParse(code, language) {
|
|
252
|
+
const parser = getParser(language);
|
|
253
|
+
const tree = parser.parse(code);
|
|
254
|
+
// Node-type weights: boost syntax constructs that are strong signals.
|
|
255
|
+
const WEIGHTS = {
|
|
256
|
+
javascript: {
|
|
257
|
+
import_statement: 3,
|
|
258
|
+
export_statement: 3,
|
|
259
|
+
require: 2,
|
|
260
|
+
function_declaration: 4,
|
|
261
|
+
arrow_function: 4,
|
|
262
|
+
class_declaration: 4,
|
|
263
|
+
method_definition: 2,
|
|
264
|
+
jsx_element: 2,
|
|
265
|
+
jsx_self_closing_element: 2,
|
|
266
|
+
},
|
|
267
|
+
typescript: {
|
|
268
|
+
// Shared JS signals
|
|
269
|
+
import_statement: 3,
|
|
270
|
+
export_statement: 3,
|
|
271
|
+
function_declaration: 4,
|
|
272
|
+
arrow_function: 4,
|
|
273
|
+
class_declaration: 4,
|
|
274
|
+
method_definition: 2,
|
|
275
|
+
jsx_element: 2,
|
|
276
|
+
jsx_self_closing_element: 2,
|
|
277
|
+
// TS-strong signals
|
|
278
|
+
interface_declaration: 8,
|
|
279
|
+
type_alias_declaration: 7,
|
|
280
|
+
enum_declaration: 7,
|
|
281
|
+
type_annotation: 5,
|
|
282
|
+
return_type: 4,
|
|
283
|
+
implements_clause: 4,
|
|
284
|
+
extends_clause: 2,
|
|
285
|
+
generic_type: 2,
|
|
286
|
+
type_arguments: 2,
|
|
287
|
+
type_parameter: 2,
|
|
288
|
+
},
|
|
289
|
+
python: {
|
|
290
|
+
import_statement: 4,
|
|
291
|
+
import_from_statement: 4,
|
|
292
|
+
function_definition: 6,
|
|
293
|
+
class_definition: 6,
|
|
294
|
+
decorated_definition: 3,
|
|
295
|
+
decorator: 3,
|
|
296
|
+
with_statement: 2,
|
|
297
|
+
try_statement: 2,
|
|
298
|
+
except_clause: 2,
|
|
299
|
+
await: 2,
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
let errorCount = 0;
|
|
303
|
+
let featureScore = 0;
|
|
304
|
+
let tsSpecificCount = 0;
|
|
305
|
+
const weightMap = WEIGHTS[language];
|
|
306
|
+
const TS_SPECIFIC = new Set([
|
|
307
|
+
"interface_declaration",
|
|
308
|
+
"type_alias_declaration",
|
|
309
|
+
"enum_declaration",
|
|
310
|
+
"type_annotation",
|
|
311
|
+
"return_type",
|
|
312
|
+
"implements_clause",
|
|
313
|
+
"type_arguments",
|
|
314
|
+
"type_parameter",
|
|
315
|
+
]);
|
|
316
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
317
|
+
const visit = (node) => {
|
|
318
|
+
if (!node)
|
|
319
|
+
return;
|
|
320
|
+
if (node.type === "ERROR")
|
|
321
|
+
errorCount++;
|
|
322
|
+
const w = weightMap[node.type];
|
|
323
|
+
if (w) {
|
|
324
|
+
featureScore += w;
|
|
325
|
+
if (language === "typescript" && TS_SPECIFIC.has(node.type)) {
|
|
326
|
+
tsSpecificCount++;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
for (const child of node.children || []) {
|
|
330
|
+
visit(child);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
visit(tree.rootNode);
|
|
334
|
+
// Penalize parse errors heavily; favor high-signal nodes.
|
|
335
|
+
const totalScore = featureScore - errorCount * 5;
|
|
336
|
+
return { totalScore, errorCount, featureScore, tsSpecificCount };
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Detect language using all available strategies
|
|
340
|
+
*/
|
|
341
|
+
export function detectLanguage(code, filePath) {
|
|
342
|
+
// Strategy 1: Try file extension (highest confidence)
|
|
343
|
+
if (filePath) {
|
|
344
|
+
const fromPath = detectFromPath(filePath);
|
|
345
|
+
if (fromPath) {
|
|
346
|
+
// Check for framework
|
|
347
|
+
const framework = detectFramework(code);
|
|
348
|
+
if (framework) {
|
|
349
|
+
return {
|
|
350
|
+
...fromPath,
|
|
351
|
+
framework: framework.framework,
|
|
352
|
+
method: 'framework',
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
return fromPath;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// Strategy 2: Try shebang
|
|
359
|
+
const fromShebang = detectFromShebang(code);
|
|
360
|
+
if (fromShebang) {
|
|
361
|
+
return fromShebang;
|
|
362
|
+
}
|
|
363
|
+
// Strategy 3: Try framework detection
|
|
364
|
+
const framework = detectFramework(code);
|
|
365
|
+
if (framework) {
|
|
366
|
+
return {
|
|
367
|
+
language: framework.language,
|
|
368
|
+
confidence: 85,
|
|
369
|
+
method: 'framework',
|
|
370
|
+
framework: framework.framework,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
// Strategy 4: Try content analysis
|
|
374
|
+
const fromContent = detectFromContent(code);
|
|
375
|
+
if (fromContent) {
|
|
376
|
+
return fromContent;
|
|
377
|
+
}
|
|
378
|
+
// Default to JavaScript if nothing detected
|
|
379
|
+
logger.warn('Could not detect language, defaulting to javascript');
|
|
380
|
+
return {
|
|
381
|
+
language: 'javascript',
|
|
382
|
+
confidence: 50,
|
|
383
|
+
method: 'content',
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Get supported languages
|
|
388
|
+
*/
|
|
389
|
+
export function getSupportedLanguages() {
|
|
390
|
+
return Array.from(new Set(Object.values(EXTENSION_MAP)));
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Get supported file extensions
|
|
394
|
+
*/
|
|
395
|
+
export function getSupportedExtensions() {
|
|
396
|
+
return Object.keys(EXTENSION_MAP);
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Check if language is supported
|
|
400
|
+
*/
|
|
401
|
+
export function isLanguageSupported(language) {
|
|
402
|
+
return getSupportedLanguages().includes(language.toLowerCase());
|
|
403
|
+
}
|
|
404
|
+
//# sourceMappingURL=languageDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"languageDetector.js","sourceRoot":"","sources":["../../src/analyzers/languageDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental Parser with Change Detection
|
|
3
|
+
*
|
|
4
|
+
* Tracks file changes and re-parses only modified code.
|
|
5
|
+
* 10-50x faster for large codebases.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
*/
|
|
9
|
+
import { SemanticQuery } from "./semanticIndex.js";
|
|
10
|
+
import { CodeGraph, SemanticIndex } from "../../types/codeGraph.js";
|
|
11
|
+
export declare class IncrementalParser {
|
|
12
|
+
private cache;
|
|
13
|
+
private parser;
|
|
14
|
+
constructor();
|
|
15
|
+
/**
|
|
16
|
+
* Parse files with incremental updates
|
|
17
|
+
*/
|
|
18
|
+
parseFiles(files: string[], language: string): Promise<{
|
|
19
|
+
graph: CodeGraph;
|
|
20
|
+
index: SemanticIndex;
|
|
21
|
+
query: SemanticQuery;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Check if file has changed since last parse
|
|
25
|
+
*/
|
|
26
|
+
private hasFileChanged;
|
|
27
|
+
/**
|
|
28
|
+
* Get merged graph from cached files
|
|
29
|
+
*/
|
|
30
|
+
private getMergedCachedGraph;
|
|
31
|
+
/**
|
|
32
|
+
* Merge graphs
|
|
33
|
+
*/
|
|
34
|
+
private mergeGraph;
|
|
35
|
+
/**
|
|
36
|
+
* Update cache for file
|
|
37
|
+
*/
|
|
38
|
+
private updateCache;
|
|
39
|
+
/**
|
|
40
|
+
* Clear cache
|
|
41
|
+
*/
|
|
42
|
+
clearCache(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Get cache statistics
|
|
45
|
+
*/
|
|
46
|
+
getCacheStats(): {
|
|
47
|
+
size: number;
|
|
48
|
+
oldestEntry: number | null;
|
|
49
|
+
};
|
|
50
|
+
private createEmptyGraph;
|
|
51
|
+
private computeHash;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=incrementalParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"incrementalParser.d.ts","sourceRoot":"","sources":["../../../src/analyzers/parsers/incrementalParser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAwB,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAWpE,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,MAAM,CAAmB;;IASjC;;OAEG;IACG,UAAU,CACd,KAAK,EAAE,MAAM,EAAE,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,KAAK,EAAE,aAAa,CAAC;QAAC,KAAK,EAAE,aAAa,CAAA;KAAE,CAAC;IAwC5E;;OAEG;YACW,cAAc;IAgB5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;OAEG;IACH,OAAO,CAAC,UAAU;IAoDlB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;IAe7D,OAAO,CAAC,gBAAgB;IAuBxB,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental Parser with Change Detection
|
|
3
|
+
*
|
|
4
|
+
* Tracks file changes and re-parses only modified code.
|
|
5
|
+
* 10-50x faster for large codebases.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
*/
|
|
9
|
+
import { TreeSitterParser } from "./treeSitterParser.js";
|
|
10
|
+
import { SemanticIndexBuilder, SemanticQuery } from "./semanticIndex.js";
|
|
11
|
+
import { logger } from "../../utils/logger.js";
|
|
12
|
+
import * as crypto from "crypto";
|
|
13
|
+
import * as fs from "fs/promises";
|
|
14
|
+
export class IncrementalParser {
|
|
15
|
+
cache = new Map();
|
|
16
|
+
parser;
|
|
17
|
+
constructor() {
|
|
18
|
+
this.parser = new TreeSitterParser({
|
|
19
|
+
enableIncremental: true,
|
|
20
|
+
cacheResults: true,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Parse files with incremental updates
|
|
25
|
+
*/
|
|
26
|
+
async parseFiles(files, language) {
|
|
27
|
+
const changedFiles = [];
|
|
28
|
+
const unchangedFiles = [];
|
|
29
|
+
// Check which files changed
|
|
30
|
+
for (const file of files) {
|
|
31
|
+
const hasChanged = await this.hasFileChanged(file);
|
|
32
|
+
if (hasChanged) {
|
|
33
|
+
changedFiles.push(file);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
unchangedFiles.push(file);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
logger.debug(`Incremental parse: ${changedFiles.length} changed, ${unchangedFiles.length} cached`);
|
|
40
|
+
// Get cached graph or create new
|
|
41
|
+
const baseGraph = this.getMergedCachedGraph(unchangedFiles);
|
|
42
|
+
// Parse only changed files
|
|
43
|
+
for (const file of changedFiles) {
|
|
44
|
+
const content = await fs.readFile(file, "utf-8");
|
|
45
|
+
const result = await this.parser.parse(content, file, language);
|
|
46
|
+
// Merge into base graph
|
|
47
|
+
this.mergeGraph(baseGraph, result.graph);
|
|
48
|
+
// Update cache
|
|
49
|
+
this.updateCache(file, result.graph);
|
|
50
|
+
}
|
|
51
|
+
// Build/update index
|
|
52
|
+
const index = SemanticIndexBuilder.buildIndex(baseGraph);
|
|
53
|
+
const query = new SemanticQuery(index, baseGraph);
|
|
54
|
+
return { graph: baseGraph, index, query };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if file has changed since last parse
|
|
58
|
+
*/
|
|
59
|
+
async hasFileChanged(file) {
|
|
60
|
+
try {
|
|
61
|
+
const content = await fs.readFile(file, "utf-8");
|
|
62
|
+
const currentHash = this.computeHash(content);
|
|
63
|
+
const cached = this.cache.get(file);
|
|
64
|
+
if (!cached)
|
|
65
|
+
return true;
|
|
66
|
+
const cachedHash = cached.graph.fileHashes.get(file);
|
|
67
|
+
return currentHash !== cachedHash;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
logger.warn(`Error checking file change: ${file}`, error);
|
|
71
|
+
return true; // Re-parse on error
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get merged graph from cached files
|
|
76
|
+
*/
|
|
77
|
+
getMergedCachedGraph(files) {
|
|
78
|
+
if (files.length === 0) {
|
|
79
|
+
return this.createEmptyGraph();
|
|
80
|
+
}
|
|
81
|
+
const baseGraph = this.createEmptyGraph();
|
|
82
|
+
for (const file of files) {
|
|
83
|
+
const cached = this.cache.get(file);
|
|
84
|
+
if (cached) {
|
|
85
|
+
this.mergeGraph(baseGraph, cached.graph);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return baseGraph;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Merge graphs
|
|
92
|
+
*/
|
|
93
|
+
mergeGraph(target, source) {
|
|
94
|
+
// Merge symbols
|
|
95
|
+
for (const [name, symbol] of source.symbols) {
|
|
96
|
+
target.symbols.set(name, symbol);
|
|
97
|
+
}
|
|
98
|
+
// Merge references
|
|
99
|
+
for (const [name, refs] of source.references) {
|
|
100
|
+
const existing = target.references.get(name) || [];
|
|
101
|
+
target.references.set(name, [...existing, ...refs]);
|
|
102
|
+
}
|
|
103
|
+
// Merge imports
|
|
104
|
+
for (const [file, importNode] of source.imports) {
|
|
105
|
+
target.imports.set(file, importNode);
|
|
106
|
+
}
|
|
107
|
+
// Merge exports
|
|
108
|
+
for (const [file, exports] of source.exports) {
|
|
109
|
+
target.exports.set(file, exports);
|
|
110
|
+
}
|
|
111
|
+
// Merge call graph
|
|
112
|
+
for (const [func, calls] of source.callGraph) {
|
|
113
|
+
const existing = target.callGraph.get(func) || [];
|
|
114
|
+
target.callGraph.set(func, [...new Set([...existing, ...calls])]);
|
|
115
|
+
}
|
|
116
|
+
// Merge type graph
|
|
117
|
+
for (const [type, info] of source.typeGraph) {
|
|
118
|
+
target.typeGraph.set(type, info);
|
|
119
|
+
}
|
|
120
|
+
// Merge scopes
|
|
121
|
+
for (const [id, scope] of source.scopes) {
|
|
122
|
+
target.scopes.set(id, scope);
|
|
123
|
+
}
|
|
124
|
+
// Merge file symbols
|
|
125
|
+
for (const [file, symbols] of source.fileSymbols) {
|
|
126
|
+
target.fileSymbols.set(file, symbols);
|
|
127
|
+
}
|
|
128
|
+
// Merge file hashes
|
|
129
|
+
for (const [file, hash] of source.fileHashes) {
|
|
130
|
+
target.fileHashes.set(file, hash);
|
|
131
|
+
}
|
|
132
|
+
// Merge dependencies
|
|
133
|
+
target.dependencies.push(...source.dependencies);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Update cache for file
|
|
137
|
+
*/
|
|
138
|
+
updateCache(file, graph) {
|
|
139
|
+
this.cache.set(file, {
|
|
140
|
+
graph,
|
|
141
|
+
index: SemanticIndexBuilder.buildIndex(graph),
|
|
142
|
+
timestamp: Date.now(),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Clear cache
|
|
147
|
+
*/
|
|
148
|
+
clearCache() {
|
|
149
|
+
this.cache.clear();
|
|
150
|
+
logger.debug("Parse cache cleared");
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get cache statistics
|
|
154
|
+
*/
|
|
155
|
+
getCacheStats() {
|
|
156
|
+
let oldestTimestamp = null;
|
|
157
|
+
for (const cached of this.cache.values()) {
|
|
158
|
+
if (oldestTimestamp === null || cached.timestamp < oldestTimestamp) {
|
|
159
|
+
oldestTimestamp = cached.timestamp;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
size: this.cache.size,
|
|
164
|
+
oldestEntry: oldestTimestamp,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
createEmptyGraph() {
|
|
168
|
+
return {
|
|
169
|
+
symbols: new Map(),
|
|
170
|
+
references: new Map(),
|
|
171
|
+
imports: new Map(),
|
|
172
|
+
exports: new Map(),
|
|
173
|
+
callGraph: new Map(),
|
|
174
|
+
typeGraph: new Map(),
|
|
175
|
+
scopes: new Map(),
|
|
176
|
+
globalScope: {
|
|
177
|
+
name: "global",
|
|
178
|
+
type: "global",
|
|
179
|
+
symbols: new Map(),
|
|
180
|
+
children: [],
|
|
181
|
+
},
|
|
182
|
+
dependencies: [],
|
|
183
|
+
fileSymbols: new Map(),
|
|
184
|
+
fileHashes: new Map(),
|
|
185
|
+
lastUpdated: new Date(),
|
|
186
|
+
version: "1.0.0",
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
computeHash(content) {
|
|
190
|
+
return crypto.createHash("sha256").update(content).digest("hex");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=incrementalParser.js.map
|