@grafema/core 0.1.0-alpha.5 → 0.1.1-alpha
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 +0 -1
- package/dist/Orchestrator.d.ts +24 -2
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +197 -24
- package/dist/config/ConfigLoader.d.ts +72 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +187 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/core/ASTWorker.d.ts +11 -36
- package/dist/core/ASTWorker.d.ts.map +1 -1
- package/dist/core/ASTWorker.js +93 -99
- package/dist/core/CoverageAnalyzer.d.ts +65 -0
- package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
- package/dist/core/CoverageAnalyzer.js +198 -0
- package/dist/core/FileNodeManager.d.ts +40 -0
- package/dist/core/FileNodeManager.d.ts.map +1 -0
- package/dist/core/FileNodeManager.js +84 -0
- package/dist/core/GraphFreshnessChecker.d.ts +33 -0
- package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
- package/dist/core/GraphFreshnessChecker.js +101 -0
- package/dist/core/HashUtils.d.ts +24 -0
- package/dist/core/HashUtils.d.ts.map +1 -0
- package/dist/core/HashUtils.js +45 -0
- package/dist/core/IncrementalReanalyzer.d.ts +36 -0
- package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
- package/dist/core/IncrementalReanalyzer.js +132 -0
- package/dist/core/NodeFactory.d.ts +225 -17
- package/dist/core/NodeFactory.d.ts.map +1 -1
- package/dist/core/NodeFactory.js +208 -18
- package/dist/core/ScopeTracker.d.ts +84 -0
- package/dist/core/ScopeTracker.d.ts.map +1 -0
- package/dist/core/ScopeTracker.js +116 -0
- package/dist/core/SemanticId.d.ts +90 -0
- package/dist/core/SemanticId.d.ts.map +1 -0
- package/dist/core/SemanticId.js +115 -0
- package/dist/core/VersionManager.d.ts.map +1 -1
- package/dist/core/VersionManager.js +3 -2
- package/dist/core/nodes/ArgumentExpressionNode.d.ts +43 -0
- package/dist/core/nodes/ArgumentExpressionNode.d.ts.map +1 -0
- package/dist/core/nodes/ArgumentExpressionNode.js +60 -0
- package/dist/core/nodes/ArrayLiteralNode.d.ts +27 -0
- package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -0
- package/dist/core/nodes/ArrayLiteralNode.js +41 -0
- package/dist/core/nodes/CallSiteNode.d.ts +28 -0
- package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
- package/dist/core/nodes/CallSiteNode.js +46 -0
- package/dist/core/nodes/ClassNode.d.ts +33 -1
- package/dist/core/nodes/ClassNode.d.ts.map +1 -1
- package/dist/core/nodes/ClassNode.js +46 -2
- package/dist/core/nodes/DecoratorNode.d.ts +42 -0
- package/dist/core/nodes/DecoratorNode.d.ts.map +1 -0
- package/dist/core/nodes/DecoratorNode.js +62 -0
- package/dist/core/nodes/EnumNode.d.ts +42 -0
- package/dist/core/nodes/EnumNode.d.ts.map +1 -0
- package/dist/core/nodes/EnumNode.js +54 -0
- package/dist/core/nodes/ExportNode.d.ts +37 -1
- package/dist/core/nodes/ExportNode.d.ts.map +1 -1
- package/dist/core/nodes/ExportNode.js +48 -2
- package/dist/core/nodes/ExpressionNode.d.ts +97 -0
- package/dist/core/nodes/ExpressionNode.d.ts.map +1 -0
- package/dist/core/nodes/ExpressionNode.js +178 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts +28 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -0
- package/dist/core/nodes/ExternalModuleNode.js +41 -0
- package/dist/core/nodes/ExternalStdioNode.d.ts +13 -6
- package/dist/core/nodes/ExternalStdioNode.d.ts.map +1 -1
- package/dist/core/nodes/ExternalStdioNode.js +15 -8
- package/dist/core/nodes/FunctionNode.d.ts +36 -0
- package/dist/core/nodes/FunctionNode.d.ts.map +1 -1
- package/dist/core/nodes/FunctionNode.js +80 -1
- package/dist/core/nodes/ImportNode.d.ts +19 -5
- package/dist/core/nodes/ImportNode.d.ts.map +1 -1
- package/dist/core/nodes/ImportNode.js +23 -5
- package/dist/core/nodes/InterfaceNode.d.ts +46 -0
- package/dist/core/nodes/InterfaceNode.d.ts.map +1 -0
- package/dist/core/nodes/InterfaceNode.js +55 -0
- package/dist/core/nodes/IssueNode.d.ts +73 -0
- package/dist/core/nodes/IssueNode.d.ts.map +1 -0
- package/dist/core/nodes/IssueNode.js +129 -0
- package/dist/core/nodes/MethodCallNode.d.ts +30 -0
- package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodCallNode.js +49 -0
- package/dist/core/nodes/MethodNode.d.ts +32 -0
- package/dist/core/nodes/MethodNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodNode.js +48 -0
- package/dist/core/nodes/ModuleNode.d.ts +31 -0
- package/dist/core/nodes/ModuleNode.d.ts.map +1 -1
- package/dist/core/nodes/ModuleNode.js +37 -0
- package/dist/core/nodes/NetworkRequestNode.d.ts +54 -0
- package/dist/core/nodes/NetworkRequestNode.d.ts.map +1 -0
- package/dist/core/nodes/NetworkRequestNode.js +65 -0
- package/dist/core/nodes/ObjectLiteralNode.d.ts +27 -0
- package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -0
- package/dist/core/nodes/ObjectLiteralNode.js +41 -0
- package/dist/core/nodes/ScopeNode.d.ts +31 -0
- package/dist/core/nodes/ScopeNode.d.ts.map +1 -1
- package/dist/core/nodes/ScopeNode.js +49 -0
- package/dist/core/nodes/TypeNode.d.ts +36 -0
- package/dist/core/nodes/TypeNode.d.ts.map +1 -0
- package/dist/core/nodes/TypeNode.js +53 -0
- package/dist/core/nodes/VariableDeclarationNode.d.ts +27 -0
- package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
- package/dist/core/nodes/VariableDeclarationNode.js +40 -0
- package/dist/core/nodes/index.d.ts +12 -1
- package/dist/core/nodes/index.d.ts.map +1 -1
- package/dist/core/nodes/index.js +14 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts +98 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticCollector.js +129 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts +77 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.js +159 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticWriter.js +43 -0
- package/dist/diagnostics/index.d.ts +14 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +11 -0
- package/dist/errors/GrafemaError.d.ts +118 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -0
- package/dist/errors/GrafemaError.js +131 -0
- package/dist/index.d.ts +57 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -1
- package/dist/logging/Logger.d.ts +48 -0
- package/dist/logging/Logger.d.ts.map +1 -0
- package/dist/logging/Logger.js +134 -0
- package/dist/plugins/Plugin.d.ts +5 -1
- package/dist/plugins/Plugin.d.ts.map +1 -1
- package/dist/plugins/Plugin.js +33 -0
- package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.js +13 -6
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.js +27 -19
- package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js +21 -14
- package/dist/plugins/analysis/FetchAnalyzer.d.ts +1 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.js +34 -14
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts +6 -3
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -1
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +76 -80
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts +180 -17
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +1171 -471
- package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ReactAnalyzer.js +56 -57
- package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/RustAnalyzer.js +15 -10
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.js +9 -7
- package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ServiceLayerAnalyzer.js +21 -9
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SocketIOAnalyzer.js +27 -15
- package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SystemDbAnalyzer.js +15 -5
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts +34 -4
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +318 -298
- package/dist/plugins/analysis/ast/IdGenerator.d.ts +105 -0
- package/dist/plugins/analysis/ast/IdGenerator.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/IdGenerator.js +116 -0
- package/dist/plugins/analysis/ast/types.d.ts +176 -5
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts +33 -0
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/createParameterNodes.js +89 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts +6 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/index.js +5 -0
- package/dist/plugins/analysis/ast/utils/location.d.ts +87 -0
- package/dist/plugins/analysis/ast/utils/location.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/location.js +78 -0
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +9 -4
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +6 -5
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +99 -9
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +663 -125
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +4 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +72 -32
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +4 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +128 -63
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +11 -8
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +12 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +36 -14
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +4 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +17 -13
- package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/MonorepoServiceDiscovery.js +3 -2
- package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/SimpleProjectDiscovery.js +5 -1
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts +22 -0
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -0
- package/dist/plugins/discovery/WorkspaceDiscovery.js +136 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts +46 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts.map +1 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.js +86 -0
- package/dist/plugins/discovery/workspaces/detector.d.ts +21 -0
- package/dist/plugins/discovery/workspaces/detector.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/detector.js +49 -0
- package/dist/plugins/discovery/workspaces/globResolver.d.ts +35 -0
- package/dist/plugins/discovery/workspaces/globResolver.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/globResolver.js +184 -0
- package/dist/plugins/discovery/workspaces/index.d.ts +9 -0
- package/dist/plugins/discovery/workspaces/index.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/index.js +8 -0
- package/dist/plugins/discovery/workspaces/parsers.d.ts +38 -0
- package/dist/plugins/discovery/workspaces/parsers.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/parsers.js +80 -0
- package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
- package/dist/plugins/enrichment/AliasTracker.js +14 -8
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js +14 -7
- package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
- package/dist/plugins/enrichment/ImportExportLinker.js +23 -6
- package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MethodCallResolver.js +18 -12
- package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MountPointResolver.js +8 -3
- package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -1
- package/dist/plugins/enrichment/PrefixEvaluator.js +16 -7
- package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/RustFFIEnricher.js +6 -5
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +17 -0
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +129 -10
- package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/IncrementalModuleIndexer.js +23 -14
- package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/JSModuleIndexer.js +63 -31
- package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.js +5 -4
- package/dist/plugins/indexing/ServiceDetector.d.ts +10 -0
- package/dist/plugins/indexing/ServiceDetector.d.ts.map +1 -1
- package/dist/plugins/indexing/ServiceDetector.js +28 -15
- package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
- package/dist/plugins/validation/CallResolverValidator.js +8 -7
- package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
- package/dist/plugins/validation/DataFlowValidator.js +17 -12
- package/dist/plugins/validation/EvalBanValidator.d.ts.map +1 -1
- package/dist/plugins/validation/EvalBanValidator.js +17 -16
- package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
- package/dist/plugins/validation/GraphConnectivityValidator.js +19 -23
- package/dist/plugins/validation/NodeCreationValidator.d.ts +85 -0
- package/dist/plugins/validation/NodeCreationValidator.d.ts.map +1 -0
- package/dist/plugins/validation/NodeCreationValidator.js +415 -0
- package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
- package/dist/plugins/validation/SQLInjectionValidator.js +59 -16
- package/dist/plugins/validation/ShadowingDetector.d.ts.map +1 -1
- package/dist/plugins/validation/ShadowingDetector.js +6 -5
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -1
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +12 -11
- package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -1
- package/dist/plugins/vcs/GitPlugin.js +10 -12
- package/dist/plugins/vcs/VCSPlugin.d.ts +3 -2
- package/dist/plugins/vcs/VCSPlugin.d.ts.map +1 -1
- package/dist/plugins/vcs/VCSPlugin.js +5 -5
- package/dist/storage/backends/RFDBServerBackend.d.ts +10 -17
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +31 -10
- package/dist/validation/PathValidator.d.ts +1 -2
- package/dist/validation/PathValidator.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/Orchestrator.ts +237 -24
- package/src/config/ConfigLoader.ts +263 -0
- package/src/config/index.ts +5 -0
- package/src/core/ASTWorker.ts +143 -139
- package/src/core/CoverageAnalyzer.ts +243 -0
- package/src/core/FileNodeManager.ts +100 -0
- package/src/core/GraphFreshnessChecker.ts +143 -0
- package/src/core/HashUtils.ts +48 -0
- package/src/core/IncrementalReanalyzer.ts +192 -0
- package/src/core/NodeFactory.ts +401 -18
- package/src/core/ScopeTracker.ts +154 -0
- package/src/core/SemanticId.ts +192 -0
- package/src/core/VersionManager.ts +3 -2
- package/src/core/nodes/ArgumentExpressionNode.ts +89 -0
- package/src/core/nodes/ArrayLiteralNode.ts +65 -0
- package/src/core/nodes/CallSiteNode.ts +58 -0
- package/src/core/nodes/ClassNode.ts +63 -2
- package/src/core/nodes/DecoratorNode.ts +91 -0
- package/src/core/nodes/EnumNode.ts +86 -0
- package/src/core/nodes/ExportNode.ts +70 -2
- package/src/core/nodes/ExpressionNode.ts +231 -0
- package/src/core/nodes/ExternalModuleNode.ts +56 -0
- package/src/core/nodes/ExternalStdioNode.ts +17 -9
- package/src/core/nodes/FunctionNode.ts +101 -1
- package/src/core/nodes/ImportNode.ts +32 -10
- package/src/core/nodes/InterfaceNode.ts +91 -0
- package/src/core/nodes/IssueNode.ts +177 -0
- package/src/core/nodes/MethodCallNode.ts +64 -0
- package/src/core/nodes/MethodNode.ts +63 -0
- package/src/core/nodes/ModuleNode.ts +50 -0
- package/src/core/nodes/NetworkRequestNode.ts +77 -0
- package/src/core/nodes/ObjectLiteralNode.ts +65 -0
- package/src/core/nodes/ScopeNode.ts +65 -0
- package/src/core/nodes/TypeNode.ts +78 -0
- package/src/core/nodes/VariableDeclarationNode.ts +52 -0
- package/src/core/nodes/index.ts +18 -1
- package/src/diagnostics/DiagnosticCollector.ts +163 -0
- package/src/diagnostics/DiagnosticReporter.ts +204 -0
- package/src/diagnostics/DiagnosticWriter.ts +50 -0
- package/src/diagnostics/index.ts +16 -0
- package/src/errors/GrafemaError.ts +174 -0
- package/src/index.ts +148 -1
- package/src/logging/Logger.ts +152 -0
- package/src/plugins/Plugin.ts +42 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +14 -8
- package/src/plugins/analysis/ExpressAnalyzer.ts +29 -19
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +22 -21
- package/src/plugins/analysis/FetchAnalyzer.ts +39 -16
- package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +84 -101
- package/src/plugins/analysis/JSASTAnalyzer.ts +1483 -503
- package/src/plugins/analysis/ReactAnalyzer.ts +57 -57
- package/src/plugins/analysis/RustAnalyzer.ts +15 -10
- package/src/plugins/analysis/SQLiteAnalyzer.ts +10 -7
- package/src/plugins/analysis/ServiceLayerAnalyzer.ts +22 -16
- package/src/plugins/analysis/SocketIOAnalyzer.ts +31 -22
- package/src/plugins/analysis/SystemDbAnalyzer.ts +16 -11
- package/src/plugins/analysis/ast/GraphBuilder.ts +439 -327
- package/src/plugins/analysis/ast/IdGenerator.ts +177 -0
- package/src/plugins/analysis/ast/types.ts +209 -6
- package/src/plugins/analysis/ast/utils/createParameterNodes.ts +104 -0
- package/src/plugins/analysis/ast/utils/index.ts +12 -0
- package/src/plugins/analysis/ast/utils/location.ts +103 -0
- package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +11 -8
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +909 -83
- package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +97 -44
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +159 -93
- package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +12 -8
- package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +41 -14
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +37 -17
- package/src/plugins/discovery/MonorepoServiceDiscovery.ts +3 -2
- package/src/plugins/discovery/SimpleProjectDiscovery.ts +6 -1
- package/src/plugins/discovery/WorkspaceDiscovery.ts +177 -0
- package/src/plugins/discovery/resolveSourceEntrypoint.ts +103 -0
- package/src/plugins/discovery/workspaces/detector.ts +63 -0
- package/src/plugins/discovery/workspaces/globResolver.ts +229 -0
- package/src/plugins/discovery/workspaces/index.ts +23 -0
- package/src/plugins/discovery/workspaces/parsers.ts +99 -0
- package/src/plugins/enrichment/AliasTracker.ts +14 -8
- package/src/plugins/enrichment/HTTPConnectionEnricher.ts +14 -7
- package/src/plugins/enrichment/ImportExportLinker.ts +24 -6
- package/src/plugins/enrichment/MethodCallResolver.ts +18 -12
- package/src/plugins/enrichment/MountPointResolver.ts +8 -3
- package/src/plugins/enrichment/PrefixEvaluator.ts +16 -7
- package/src/plugins/enrichment/RustFFIEnricher.ts +6 -5
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +149 -12
- package/src/plugins/indexing/IncrementalModuleIndexer.ts +23 -14
- package/src/plugins/indexing/JSModuleIndexer.ts +74 -34
- package/src/plugins/indexing/RustModuleIndexer.ts +5 -4
- package/src/plugins/validation/CallResolverValidator.ts +8 -7
- package/src/plugins/validation/DataFlowValidator.ts +16 -12
- package/src/plugins/validation/EvalBanValidator.ts +17 -16
- package/src/plugins/validation/GraphConnectivityValidator.ts +19 -23
- package/src/plugins/validation/NodeCreationValidator.ts +554 -0
- package/src/plugins/validation/SQLInjectionValidator.ts +61 -15
- package/src/plugins/validation/ShadowingDetector.ts +6 -5
- package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +12 -11
- package/src/plugins/vcs/GitPlugin.ts +40 -12
- package/src/plugins/vcs/VCSPlugin.ts +7 -5
- package/src/storage/backends/RFDBServerBackend.ts +43 -29
- package/src/validation/PathValidator.ts +1 -1
- package/dist/core/AnalysisWorker.d.ts +0 -14
- package/dist/core/AnalysisWorker.d.ts.map +0 -1
- package/dist/core/AnalysisWorker.js +0 -307
- package/dist/core/ParallelAnalyzer.d.ts +0 -120
- package/dist/core/ParallelAnalyzer.d.ts.map +0 -1
- package/dist/core/ParallelAnalyzer.js +0 -331
- package/dist/core/QueueWorker.d.ts +0 -12
- package/dist/core/QueueWorker.d.ts.map +0 -1
- package/dist/core/QueueWorker.js +0 -567
- package/dist/core/RFDBClient.d.ts +0 -179
- package/dist/core/RFDBClient.d.ts.map +0 -1
- package/dist/core/RFDBClient.js +0 -429
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts +0 -19
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts.map +0 -1
- package/dist/plugins/discovery/ZonServiceDiscovery.js +0 -204
- package/src/core/AnalysisWorker.ts +0 -410
- package/src/core/ParallelAnalyzer.ts +0 -476
- package/src/core/QueueWorker.ts +0 -780
- package/src/plugins/indexing/ServiceDetector.ts +0 -230
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
* GraphBuilder - создание узлов и рёбер графа из собранных AST данных
|
|
3
3
|
* OPTIMIZED: Uses batched writes to reduce FFI overhead
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { basename } from 'path';
|
|
6
|
+
import { ImportNode } from '../../../core/nodes/ImportNode.js';
|
|
7
|
+
import { InterfaceNode } from '../../../core/nodes/InterfaceNode.js';
|
|
8
|
+
import { EnumNode } from '../../../core/nodes/EnumNode.js';
|
|
9
|
+
import { DecoratorNode } from '../../../core/nodes/DecoratorNode.js';
|
|
10
|
+
import { NetworkRequestNode } from '../../../core/nodes/NetworkRequestNode.js';
|
|
11
|
+
import { NodeFactory } from '../../../core/NodeFactory.js';
|
|
6
12
|
export class GraphBuilder {
|
|
7
13
|
// Track singleton nodes to avoid duplicates (net:stdio, net:request, etc.)
|
|
8
14
|
_createdSingletons = new Set();
|
|
@@ -53,7 +59,13 @@ export class GraphBuilder {
|
|
|
53
59
|
async build(module, graph, projectPath, data) {
|
|
54
60
|
const { functions, parameters = [], scopes, variableDeclarations, callSites, methodCalls = [], eventListeners = [], classInstantiations = [], classDeclarations = [], methodCallbacks = [], callArguments = [], imports = [], exports = [], httpRequests = [], literals = [], variableAssignments = [],
|
|
55
61
|
// TypeScript-specific collections
|
|
56
|
-
interfaces = [], typeAliases = [], enums = [], decorators = []
|
|
62
|
+
interfaces = [], typeAliases = [], enums = [], decorators = [],
|
|
63
|
+
// Array mutation tracking for FLOWS_INTO edges
|
|
64
|
+
arrayMutations = [],
|
|
65
|
+
// Object mutation tracking for FLOWS_INTO edges
|
|
66
|
+
objectMutations = [],
|
|
67
|
+
// Object/Array literal tracking
|
|
68
|
+
objectLiterals = [], arrayLiterals = [] } = data;
|
|
57
69
|
// Reset buffers for this build
|
|
58
70
|
this._nodeBuffer = [];
|
|
59
71
|
this._edgeBuffer = [];
|
|
@@ -133,14 +145,21 @@ export class GraphBuilder {
|
|
|
133
145
|
this.bufferDecoratorNodes(decorators);
|
|
134
146
|
// 25. Buffer IMPLEMENTS edges (CLASS -> INTERFACE)
|
|
135
147
|
this.bufferImplementsEdges(classDeclarations, interfaces);
|
|
148
|
+
// 26. Buffer FLOWS_INTO edges for array mutations (push, unshift, splice, indexed assignment)
|
|
149
|
+
this.bufferArrayMutationEdges(arrayMutations, variableDeclarations, parameters);
|
|
150
|
+
// 27. Buffer FLOWS_INTO edges for object mutations (property assignment, Object.assign)
|
|
151
|
+
// REG-152: Now includes classDeclarations for this.prop = value patterns
|
|
152
|
+
this.bufferObjectMutationEdges(objectMutations, variableDeclarations, parameters, functions, classDeclarations);
|
|
153
|
+
// 28. Buffer OBJECT_LITERAL nodes
|
|
154
|
+
this.bufferObjectLiteralNodes(objectLiterals);
|
|
155
|
+
// 29. Buffer ARRAY_LITERAL nodes
|
|
156
|
+
this.bufferArrayLiteralNodes(arrayLiterals);
|
|
136
157
|
// FLUSH: Write all nodes first, then edges in single batch calls
|
|
137
158
|
const nodesCreated = await this._flushNodes(graph);
|
|
138
159
|
const edgesCreated = await this._flushEdges(graph);
|
|
139
|
-
// Handle async operations that need graph queries (IMPORTS_FROM edges)
|
|
140
|
-
const importExportEdges = await this.createImportExportEdges(module, imports, exports, graph, projectPath);
|
|
141
160
|
// Handle async operations for ASSIGNED_FROM with CLASS lookups
|
|
142
161
|
const classAssignmentEdges = await this.createClassAssignmentEdges(variableAssignments, graph);
|
|
143
|
-
return { nodes: nodesCreated, edges: edgesCreated +
|
|
162
|
+
return { nodes: nodesCreated, edges: edgesCreated + classAssignmentEdges };
|
|
144
163
|
}
|
|
145
164
|
// ============= BUFFERED METHODS (synchronous, no awaits) =============
|
|
146
165
|
bufferFunctionEdges(module, functions) {
|
|
@@ -253,23 +272,18 @@ export class GraphBuilder {
|
|
|
253
272
|
bufferStdioNodes(methodCalls) {
|
|
254
273
|
const consoleIOMethods = methodCalls.filter(mc => (mc.object === 'console' && (mc.method === 'log' || mc.method === 'error')));
|
|
255
274
|
if (consoleIOMethods.length > 0) {
|
|
256
|
-
const
|
|
275
|
+
const stdioNode = NodeFactory.createExternalStdio();
|
|
257
276
|
// Buffer net:stdio node only once (singleton)
|
|
258
|
-
if (!this._createdSingletons.has(
|
|
259
|
-
this._bufferNode(
|
|
260
|
-
|
|
261
|
-
type: 'net:stdio',
|
|
262
|
-
name: '__stdio__',
|
|
263
|
-
description: 'Standard input/output stream'
|
|
264
|
-
});
|
|
265
|
-
this._createdSingletons.add(stdioId);
|
|
277
|
+
if (!this._createdSingletons.has(stdioNode.id)) {
|
|
278
|
+
this._bufferNode(stdioNode);
|
|
279
|
+
this._createdSingletons.add(stdioNode.id);
|
|
266
280
|
}
|
|
267
281
|
// Buffer WRITES_TO edges for console.log/error
|
|
268
282
|
for (const methodCall of consoleIOMethods) {
|
|
269
283
|
this._bufferEdge({
|
|
270
284
|
type: 'WRITES_TO',
|
|
271
285
|
src: methodCall.id,
|
|
272
|
-
dst:
|
|
286
|
+
dst: stdioNode.id
|
|
273
287
|
});
|
|
274
288
|
}
|
|
275
289
|
}
|
|
@@ -295,9 +309,12 @@ export class GraphBuilder {
|
|
|
295
309
|
dst: methodId
|
|
296
310
|
});
|
|
297
311
|
}
|
|
298
|
-
// If superClass, buffer DERIVES_FROM edge
|
|
312
|
+
// If superClass, buffer DERIVES_FROM edge with computed ID
|
|
299
313
|
if (superClass) {
|
|
300
|
-
|
|
314
|
+
// Compute superclass ID using same format as ClassNode (line 0 = unknown location)
|
|
315
|
+
// Assume superclass is in same file (most common case)
|
|
316
|
+
// When superclass is in different file, edge will be dangling until that file analyzed
|
|
317
|
+
const superClassId = `${file}:CLASS:${superClass}:0`;
|
|
301
318
|
this._bufferEdge({
|
|
302
319
|
type: 'DERIVES_FROM',
|
|
303
320
|
src: id,
|
|
@@ -318,16 +335,11 @@ export class GraphBuilder {
|
|
|
318
335
|
const { variableId, className, line } = instantiation;
|
|
319
336
|
let classId = declarationMap.get(className);
|
|
320
337
|
if (!classId) {
|
|
321
|
-
// External class -
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
name: className,
|
|
327
|
-
file: module.file,
|
|
328
|
-
line,
|
|
329
|
-
isInstantiationRef: true
|
|
330
|
-
});
|
|
338
|
+
// External class - compute ID using ClassNode format (line 0 = unknown location)
|
|
339
|
+
// Assume class is in same file (most common case)
|
|
340
|
+
// When class is in different file, edge will be dangling until that file analyzed
|
|
341
|
+
classId = `${module.file}:CLASS:${className}:0`;
|
|
342
|
+
// NO node creation - node will exist when class file analyzed
|
|
331
343
|
}
|
|
332
344
|
// Buffer INSTANCE_OF edge
|
|
333
345
|
this._bufferEdge({
|
|
@@ -352,42 +364,39 @@ export class GraphBuilder {
|
|
|
352
364
|
}
|
|
353
365
|
bufferImportNodes(module, imports) {
|
|
354
366
|
for (const imp of imports) {
|
|
355
|
-
const { source, specifiers, line } = imp;
|
|
367
|
+
const { source, specifiers, line, column } = imp;
|
|
356
368
|
for (const spec of specifiers) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
importType: importType,
|
|
369
|
+
// Use ImportNode factory for proper semantic IDs and field population
|
|
370
|
+
const importNode = ImportNode.create(spec.local, // name = local binding
|
|
371
|
+
module.file, // file
|
|
372
|
+
line, // line (stored as field, not in ID)
|
|
373
|
+
column || 0, // column
|
|
374
|
+
source, // source module
|
|
375
|
+
{
|
|
365
376
|
imported: spec.imported,
|
|
366
|
-
local: spec.local
|
|
367
|
-
|
|
368
|
-
line: line
|
|
377
|
+
local: spec.local
|
|
378
|
+
// importType is auto-detected from imported field
|
|
369
379
|
});
|
|
380
|
+
this._bufferNode(importNode);
|
|
370
381
|
// MODULE -> CONTAINS -> IMPORT
|
|
371
382
|
this._bufferEdge({
|
|
372
383
|
type: 'CONTAINS',
|
|
373
384
|
src: module.id,
|
|
374
|
-
dst:
|
|
385
|
+
dst: importNode.id
|
|
375
386
|
});
|
|
376
387
|
// Create EXTERNAL_MODULE node for external modules
|
|
377
388
|
const isRelative = source.startsWith('./') || source.startsWith('../');
|
|
378
389
|
if (!isRelative) {
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
line: line
|
|
386
|
-
});
|
|
390
|
+
const externalModule = NodeFactory.createExternalModule(source);
|
|
391
|
+
// Avoid duplicate EXTERNAL_MODULE nodes
|
|
392
|
+
if (!this._createdSingletons.has(externalModule.id)) {
|
|
393
|
+
this._bufferNode(externalModule);
|
|
394
|
+
this._createdSingletons.add(externalModule.id);
|
|
395
|
+
}
|
|
387
396
|
this._bufferEdge({
|
|
388
397
|
type: 'IMPORTS',
|
|
389
398
|
src: module.id,
|
|
390
|
-
dst:
|
|
399
|
+
dst: externalModule.id
|
|
391
400
|
});
|
|
392
401
|
}
|
|
393
402
|
}
|
|
@@ -397,74 +406,50 @@ export class GraphBuilder {
|
|
|
397
406
|
for (const exp of exports) {
|
|
398
407
|
const { type, line, name, specifiers, source } = exp;
|
|
399
408
|
if (type === 'default') {
|
|
400
|
-
const
|
|
401
|
-
this._bufferNode(
|
|
402
|
-
id: exportId,
|
|
403
|
-
type: 'EXPORT',
|
|
404
|
-
exportType: 'default',
|
|
405
|
-
name: 'default',
|
|
406
|
-
file: module.file,
|
|
407
|
-
line: line
|
|
408
|
-
});
|
|
409
|
+
const exportNode = NodeFactory.createExport('default', module.file, line, 0, { default: true, exportType: 'default' });
|
|
410
|
+
this._bufferNode(exportNode);
|
|
409
411
|
this._bufferEdge({
|
|
410
412
|
type: 'CONTAINS',
|
|
411
413
|
src: module.id,
|
|
412
|
-
dst:
|
|
414
|
+
dst: exportNode.id
|
|
413
415
|
});
|
|
414
416
|
}
|
|
415
417
|
else if (type === 'named') {
|
|
416
418
|
if (specifiers) {
|
|
417
419
|
for (const spec of specifiers) {
|
|
418
|
-
const
|
|
419
|
-
this._bufferNode({
|
|
420
|
-
id: exportId,
|
|
421
|
-
type: 'EXPORT',
|
|
422
|
-
exportType: 'named',
|
|
423
|
-
name: spec.exported,
|
|
420
|
+
const exportNode = NodeFactory.createExport(spec.exported, module.file, line, 0, {
|
|
424
421
|
local: spec.local,
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
source: source
|
|
422
|
+
source: source,
|
|
423
|
+
exportType: 'named'
|
|
428
424
|
});
|
|
425
|
+
this._bufferNode(exportNode);
|
|
429
426
|
this._bufferEdge({
|
|
430
427
|
type: 'CONTAINS',
|
|
431
428
|
src: module.id,
|
|
432
|
-
dst:
|
|
429
|
+
dst: exportNode.id
|
|
433
430
|
});
|
|
434
431
|
}
|
|
435
432
|
}
|
|
436
433
|
else if (name) {
|
|
437
|
-
const
|
|
438
|
-
this._bufferNode(
|
|
439
|
-
id: exportId,
|
|
440
|
-
type: 'EXPORT',
|
|
441
|
-
exportType: 'named',
|
|
442
|
-
name: name,
|
|
443
|
-
file: module.file,
|
|
444
|
-
line: line
|
|
445
|
-
});
|
|
434
|
+
const exportNode = NodeFactory.createExport(name, module.file, line, 0, { exportType: 'named' });
|
|
435
|
+
this._bufferNode(exportNode);
|
|
446
436
|
this._bufferEdge({
|
|
447
437
|
type: 'CONTAINS',
|
|
448
438
|
src: module.id,
|
|
449
|
-
dst:
|
|
439
|
+
dst: exportNode.id
|
|
450
440
|
});
|
|
451
441
|
}
|
|
452
442
|
}
|
|
453
443
|
else if (type === 'all') {
|
|
454
|
-
const
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
type: 'EXPORT',
|
|
458
|
-
exportType: 'all',
|
|
459
|
-
name: '*',
|
|
460
|
-
file: module.file,
|
|
461
|
-
line: line,
|
|
462
|
-
source: source
|
|
444
|
+
const exportNode = NodeFactory.createExport('*', module.file, line, 0, {
|
|
445
|
+
source: source,
|
|
446
|
+
exportType: 'all'
|
|
463
447
|
});
|
|
448
|
+
this._bufferNode(exportNode);
|
|
464
449
|
this._bufferEdge({
|
|
465
450
|
type: 'CONTAINS',
|
|
466
451
|
src: module.id,
|
|
467
|
-
dst:
|
|
452
|
+
dst: exportNode.id
|
|
468
453
|
});
|
|
469
454
|
}
|
|
470
455
|
}
|
|
@@ -493,14 +478,11 @@ export class GraphBuilder {
|
|
|
493
478
|
}
|
|
494
479
|
bufferHttpRequests(httpRequests, functions) {
|
|
495
480
|
if (httpRequests.length > 0) {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
name: '__network__'
|
|
502
|
-
});
|
|
503
|
-
this._createdSingletons.add(networkId);
|
|
481
|
+
// Create net:request singleton using factory
|
|
482
|
+
const networkNode = NetworkRequestNode.create();
|
|
483
|
+
if (!this._createdSingletons.has(networkNode.id)) {
|
|
484
|
+
this._bufferNode(networkNode);
|
|
485
|
+
this._createdSingletons.add(networkNode.id);
|
|
504
486
|
}
|
|
505
487
|
for (const request of httpRequests) {
|
|
506
488
|
const { parentScopeId, ...requestData } = request;
|
|
@@ -508,7 +490,7 @@ export class GraphBuilder {
|
|
|
508
490
|
this._bufferEdge({
|
|
509
491
|
type: 'CALLS',
|
|
510
492
|
src: request.id,
|
|
511
|
-
dst:
|
|
493
|
+
dst: networkNode.id
|
|
512
494
|
});
|
|
513
495
|
if (parentScopeId) {
|
|
514
496
|
const scopeParts = parentScopeId.split(':');
|
|
@@ -582,8 +564,10 @@ export class GraphBuilder {
|
|
|
582
564
|
}
|
|
583
565
|
// VARIABLE by name
|
|
584
566
|
else if (sourceType === 'VARIABLE' && sourceName) {
|
|
585
|
-
|
|
586
|
-
|
|
567
|
+
// Find the current variable's file by looking it up in variableDeclarations
|
|
568
|
+
// (semantic IDs don't have predictable file positions like old hash-based IDs)
|
|
569
|
+
const currentVar = variableDeclarations.find(v => v.id === variableId);
|
|
570
|
+
const varFile = currentVar?.file ?? null;
|
|
587
571
|
const sourceVariable = variableDeclarations.find(v => v.name === sourceName && v.file === varFile);
|
|
588
572
|
if (sourceVariable) {
|
|
589
573
|
this._bufferEdge({
|
|
@@ -614,35 +598,18 @@ export class GraphBuilder {
|
|
|
614
598
|
});
|
|
615
599
|
}
|
|
616
600
|
}
|
|
617
|
-
// EXPRESSION node creation
|
|
601
|
+
// EXPRESSION node creation using NodeFactory
|
|
618
602
|
else if (sourceType === 'EXPRESSION' && sourceId) {
|
|
619
|
-
const { expressionType, object, property, computed, computedPropertyVar, operator, objectSourceName, leftSourceName, rightSourceName, consequentSourceName, alternateSourceName, file: exprFile, line: exprLine } = assignment;
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
expressionNode.property = property;
|
|
630
|
-
expressionNode.computed = computed;
|
|
631
|
-
if (computedPropertyVar) {
|
|
632
|
-
expressionNode.computedPropertyVar = computedPropertyVar;
|
|
633
|
-
}
|
|
634
|
-
expressionNode.name = `${object}.${property}`;
|
|
635
|
-
}
|
|
636
|
-
else if (expressionType === 'BinaryExpression' || expressionType === 'LogicalExpression') {
|
|
637
|
-
expressionNode.operator = operator;
|
|
638
|
-
expressionNode.name = `<${expressionType}>`;
|
|
639
|
-
}
|
|
640
|
-
else if (expressionType === 'ConditionalExpression') {
|
|
641
|
-
expressionNode.name = '<ternary>';
|
|
642
|
-
}
|
|
643
|
-
else if (expressionType === 'TemplateLiteral') {
|
|
644
|
-
expressionNode.name = '<template>';
|
|
645
|
-
}
|
|
603
|
+
const { expressionType, object, property, computed, computedPropertyVar, operator, objectSourceName, leftSourceName, rightSourceName, consequentSourceName, alternateSourceName, file: exprFile, line: exprLine, column: exprColumn } = assignment;
|
|
604
|
+
// Create node from upstream metadata using factory
|
|
605
|
+
const expressionNode = NodeFactory.createExpressionFromMetadata(expressionType || 'Unknown', exprFile || '', exprLine || 0, exprColumn || 0, {
|
|
606
|
+
id: sourceId, // ID from JSASTAnalyzer
|
|
607
|
+
object,
|
|
608
|
+
property,
|
|
609
|
+
computed,
|
|
610
|
+
computedPropertyVar: computedPropertyVar ?? undefined,
|
|
611
|
+
operator
|
|
612
|
+
});
|
|
646
613
|
this._bufferNode(expressionNode);
|
|
647
614
|
this._bufferEdge({
|
|
648
615
|
type: 'ASSIGNED_FROM',
|
|
@@ -787,53 +754,50 @@ export class GraphBuilder {
|
|
|
787
754
|
// ============= TypeScript-specific buffer methods =============
|
|
788
755
|
/**
|
|
789
756
|
* Buffer INTERFACE nodes and EXTENDS edges
|
|
757
|
+
*
|
|
758
|
+
* Uses two-pass approach:
|
|
759
|
+
* 1. First pass: create all interface nodes, store in Map
|
|
760
|
+
* 2. Second pass: create EXTENDS edges using stored node IDs
|
|
790
761
|
*/
|
|
791
762
|
bufferInterfaceNodes(module, interfaces) {
|
|
763
|
+
// First pass: create all interface nodes and store them
|
|
764
|
+
const interfaceNodes = new Map();
|
|
792
765
|
for (const iface of interfaces) {
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
type: 'INTERFACE',
|
|
797
|
-
name: iface.name,
|
|
798
|
-
file: iface.file,
|
|
799
|
-
line: iface.line,
|
|
800
|
-
column: iface.column,
|
|
801
|
-
properties: iface.properties,
|
|
802
|
-
extends: iface.extends
|
|
766
|
+
const interfaceNode = InterfaceNode.create(iface.name, iface.file, iface.line, iface.column || 0, {
|
|
767
|
+
extends: iface.extends,
|
|
768
|
+
properties: iface.properties
|
|
803
769
|
});
|
|
770
|
+
interfaceNodes.set(iface.name, interfaceNode);
|
|
771
|
+
this._bufferNode(interfaceNode);
|
|
804
772
|
// MODULE -> CONTAINS -> INTERFACE
|
|
805
773
|
this._bufferEdge({
|
|
806
774
|
type: 'CONTAINS',
|
|
807
775
|
src: module.id,
|
|
808
|
-
dst:
|
|
776
|
+
dst: interfaceNode.id
|
|
809
777
|
});
|
|
810
|
-
|
|
778
|
+
}
|
|
779
|
+
// Second pass: create EXTENDS edges
|
|
780
|
+
for (const iface of interfaces) {
|
|
811
781
|
if (iface.extends && iface.extends.length > 0) {
|
|
782
|
+
const srcNode = interfaceNodes.get(iface.name);
|
|
812
783
|
for (const parentName of iface.extends) {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
784
|
+
const parentNode = interfaceNodes.get(parentName);
|
|
785
|
+
if (parentNode) {
|
|
786
|
+
// Same-file interface
|
|
816
787
|
this._bufferEdge({
|
|
817
788
|
type: 'EXTENDS',
|
|
818
|
-
src:
|
|
819
|
-
dst:
|
|
789
|
+
src: srcNode.id,
|
|
790
|
+
dst: parentNode.id
|
|
820
791
|
});
|
|
821
792
|
}
|
|
822
793
|
else {
|
|
823
794
|
// External interface - create a reference node
|
|
824
|
-
const
|
|
825
|
-
this._bufferNode(
|
|
826
|
-
id: externalId,
|
|
827
|
-
type: 'INTERFACE',
|
|
828
|
-
name: parentName,
|
|
829
|
-
file: iface.file,
|
|
830
|
-
line: iface.line,
|
|
831
|
-
isExternal: true
|
|
832
|
-
});
|
|
795
|
+
const externalInterface = NodeFactory.createInterface(parentName, iface.file, iface.line, 0, { isExternal: true });
|
|
796
|
+
this._bufferNode(externalInterface);
|
|
833
797
|
this._bufferEdge({
|
|
834
798
|
type: 'EXTENDS',
|
|
835
|
-
src:
|
|
836
|
-
dst:
|
|
799
|
+
src: srcNode.id,
|
|
800
|
+
dst: externalInterface.id
|
|
837
801
|
});
|
|
838
802
|
}
|
|
839
803
|
}
|
|
@@ -845,45 +809,35 @@ export class GraphBuilder {
|
|
|
845
809
|
*/
|
|
846
810
|
bufferTypeAliasNodes(module, typeAliases) {
|
|
847
811
|
for (const typeAlias of typeAliases) {
|
|
848
|
-
//
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
type: 'TYPE',
|
|
852
|
-
name: typeAlias.name,
|
|
853
|
-
file: typeAlias.file,
|
|
854
|
-
line: typeAlias.line,
|
|
855
|
-
column: typeAlias.column,
|
|
856
|
-
aliasOf: typeAlias.aliasOf
|
|
857
|
-
});
|
|
812
|
+
// Create TYPE node using factory
|
|
813
|
+
const typeNode = NodeFactory.createType(typeAlias.name, typeAlias.file, typeAlias.line, typeAlias.column || 0, { aliasOf: typeAlias.aliasOf });
|
|
814
|
+
this._bufferNode(typeNode);
|
|
858
815
|
// MODULE -> CONTAINS -> TYPE
|
|
859
816
|
this._bufferEdge({
|
|
860
817
|
type: 'CONTAINS',
|
|
861
818
|
src: module.id,
|
|
862
|
-
dst:
|
|
819
|
+
dst: typeNode.id
|
|
863
820
|
});
|
|
864
821
|
}
|
|
865
822
|
}
|
|
866
823
|
/**
|
|
867
824
|
* Buffer ENUM nodes
|
|
825
|
+
* Uses EnumNode.create() to ensure consistent ID format (colon separator)
|
|
868
826
|
*/
|
|
869
827
|
bufferEnumNodes(module, enums) {
|
|
870
828
|
for (const enumDecl of enums) {
|
|
871
|
-
//
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
file: enumDecl.file,
|
|
877
|
-
line: enumDecl.line,
|
|
878
|
-
column: enumDecl.column,
|
|
879
|
-
isConst: enumDecl.isConst,
|
|
880
|
-
members: enumDecl.members
|
|
829
|
+
// Use EnumNode.create() to generate proper ID (colon format)
|
|
830
|
+
// Do NOT use enumDecl.id which has legacy # format from TypeScriptVisitor
|
|
831
|
+
const enumNode = EnumNode.create(enumDecl.name, enumDecl.file, enumDecl.line, enumDecl.column || 0, {
|
|
832
|
+
isConst: enumDecl.isConst || false,
|
|
833
|
+
members: enumDecl.members || []
|
|
881
834
|
});
|
|
835
|
+
this._bufferNode(enumNode);
|
|
882
836
|
// MODULE -> CONTAINS -> ENUM
|
|
883
837
|
this._bufferEdge({
|
|
884
838
|
type: 'CONTAINS',
|
|
885
839
|
src: module.id,
|
|
886
|
-
dst:
|
|
840
|
+
dst: enumNode.id // Use factory-generated ID (colon format)
|
|
887
841
|
});
|
|
888
842
|
}
|
|
889
843
|
}
|
|
@@ -892,22 +846,15 @@ export class GraphBuilder {
|
|
|
892
846
|
*/
|
|
893
847
|
bufferDecoratorNodes(decorators) {
|
|
894
848
|
for (const decorator of decorators) {
|
|
895
|
-
//
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
name: decorator.name,
|
|
900
|
-
file: decorator.file,
|
|
901
|
-
line: decorator.line,
|
|
902
|
-
column: decorator.column,
|
|
903
|
-
arguments: decorator.arguments,
|
|
904
|
-
targetType: decorator.targetType
|
|
905
|
-
});
|
|
849
|
+
// Create DECORATOR node using factory (generates colon-format ID)
|
|
850
|
+
const decoratorNode = DecoratorNode.create(decorator.name, decorator.file, decorator.line, decorator.column || 0, decorator.targetId, // Now included in the node!
|
|
851
|
+
decorator.targetType, { arguments: decorator.arguments });
|
|
852
|
+
this._bufferNode(decoratorNode);
|
|
906
853
|
// TARGET -> DECORATED_BY -> DECORATOR
|
|
907
854
|
this._bufferEdge({
|
|
908
855
|
type: 'DECORATED_BY',
|
|
909
856
|
src: decorator.targetId,
|
|
910
|
-
dst:
|
|
857
|
+
dst: decoratorNode.id // Use factory-generated ID (colon format)
|
|
911
858
|
});
|
|
912
859
|
}
|
|
913
860
|
}
|
|
@@ -921,33 +868,203 @@ export class GraphBuilder {
|
|
|
921
868
|
// Try to find the interface in the same file
|
|
922
869
|
const iface = interfaces.find(i => i.name === ifaceName);
|
|
923
870
|
if (iface) {
|
|
871
|
+
// Compute interface ID using same formula as InterfaceNode.create()
|
|
872
|
+
// Format: {file}:INTERFACE:{name}:{line}
|
|
873
|
+
const interfaceId = `${iface.file}:INTERFACE:${iface.name}:${iface.line}`;
|
|
924
874
|
this._bufferEdge({
|
|
925
875
|
type: 'IMPLEMENTS',
|
|
926
876
|
src: classDecl.id,
|
|
927
|
-
dst:
|
|
877
|
+
dst: interfaceId
|
|
928
878
|
});
|
|
929
879
|
}
|
|
930
880
|
else {
|
|
931
881
|
// External interface - create a reference node
|
|
932
|
-
const
|
|
933
|
-
this._bufferNode(
|
|
934
|
-
id: externalId,
|
|
935
|
-
type: 'INTERFACE',
|
|
936
|
-
name: ifaceName,
|
|
937
|
-
file: classDecl.file,
|
|
938
|
-
line: classDecl.line,
|
|
939
|
-
isExternal: true
|
|
940
|
-
});
|
|
882
|
+
const externalInterface = NodeFactory.createInterface(ifaceName, classDecl.file, classDecl.line, 0, { isExternal: true });
|
|
883
|
+
this._bufferNode(externalInterface);
|
|
941
884
|
this._bufferEdge({
|
|
942
885
|
type: 'IMPLEMENTS',
|
|
943
886
|
src: classDecl.id,
|
|
944
|
-
dst:
|
|
887
|
+
dst: externalInterface.id
|
|
945
888
|
});
|
|
946
889
|
}
|
|
947
890
|
}
|
|
948
891
|
}
|
|
949
892
|
}
|
|
950
893
|
}
|
|
894
|
+
/**
|
|
895
|
+
* Buffer FLOWS_INTO edges for array mutations (push, unshift, splice, indexed assignment)
|
|
896
|
+
* Creates edges from inserted values to the array variable
|
|
897
|
+
*
|
|
898
|
+
* REG-117: Now handles nested mutations like obj.arr.push(item):
|
|
899
|
+
* - For nested mutations, falls back to base object if array property not found
|
|
900
|
+
* - Adds nestedProperty metadata for tracking
|
|
901
|
+
*
|
|
902
|
+
* OPTIMIZED: Uses Map-based lookup cache for O(1) variable lookups instead of O(n) find()
|
|
903
|
+
*/
|
|
904
|
+
bufferArrayMutationEdges(arrayMutations, variableDeclarations, parameters) {
|
|
905
|
+
// Build lookup cache once: O(n) instead of O(n*m) with find() per mutation
|
|
906
|
+
const varLookup = new Map();
|
|
907
|
+
for (const v of variableDeclarations) {
|
|
908
|
+
varLookup.set(`${v.file}:${v.name}`, v);
|
|
909
|
+
}
|
|
910
|
+
// Build parameter lookup cache for function-level mutations
|
|
911
|
+
const paramLookup = new Map();
|
|
912
|
+
for (const p of parameters) {
|
|
913
|
+
paramLookup.set(`${p.file}:${p.name}`, p);
|
|
914
|
+
}
|
|
915
|
+
for (const mutation of arrayMutations) {
|
|
916
|
+
const { arrayName, mutationMethod, insertedValues, file, isNested, baseObjectName, propertyName } = mutation;
|
|
917
|
+
// REG-117: For nested mutations (obj.arr.push), resolve target node
|
|
918
|
+
// First try direct lookup, then fallback to base object
|
|
919
|
+
let targetNodeId = null;
|
|
920
|
+
let nestedProperty;
|
|
921
|
+
if (isNested && baseObjectName) {
|
|
922
|
+
// Skip 'this.items.push' - 'this' is not a variable node
|
|
923
|
+
if (baseObjectName === 'this')
|
|
924
|
+
continue;
|
|
925
|
+
// Nested mutation: try base object lookup
|
|
926
|
+
const baseVar = varLookup.get(`${file}:${baseObjectName}`);
|
|
927
|
+
const baseParam = !baseVar ? paramLookup.get(`${file}:${baseObjectName}`) : null;
|
|
928
|
+
targetNodeId = baseVar?.id ?? baseParam?.id ?? null;
|
|
929
|
+
nestedProperty = propertyName;
|
|
930
|
+
}
|
|
931
|
+
else {
|
|
932
|
+
// Direct mutation: arr.push()
|
|
933
|
+
const arrayVar = varLookup.get(`${file}:${arrayName}`);
|
|
934
|
+
const arrayParam = !arrayVar ? paramLookup.get(`${file}:${arrayName}`) : null;
|
|
935
|
+
targetNodeId = arrayVar?.id ?? arrayParam?.id ?? null;
|
|
936
|
+
}
|
|
937
|
+
if (!targetNodeId)
|
|
938
|
+
continue;
|
|
939
|
+
// Create FLOWS_INTO edges for each inserted value
|
|
940
|
+
for (const arg of insertedValues) {
|
|
941
|
+
if (arg.valueType === 'VARIABLE' && arg.valueName) {
|
|
942
|
+
// O(1) lookup instead of O(n) find
|
|
943
|
+
const sourceVar = varLookup.get(`${file}:${arg.valueName}`);
|
|
944
|
+
const sourceParam = !sourceVar ? paramLookup.get(`${file}:${arg.valueName}`) : null;
|
|
945
|
+
const sourceNodeId = sourceVar?.id ?? sourceParam?.id;
|
|
946
|
+
if (sourceNodeId) {
|
|
947
|
+
const edgeData = {
|
|
948
|
+
type: 'FLOWS_INTO',
|
|
949
|
+
src: sourceNodeId,
|
|
950
|
+
dst: targetNodeId,
|
|
951
|
+
mutationMethod,
|
|
952
|
+
argIndex: arg.argIndex
|
|
953
|
+
};
|
|
954
|
+
if (arg.isSpread) {
|
|
955
|
+
edgeData.isSpread = true;
|
|
956
|
+
}
|
|
957
|
+
// REG-117: Add nested property metadata
|
|
958
|
+
if (nestedProperty) {
|
|
959
|
+
edgeData.nestedProperty = nestedProperty;
|
|
960
|
+
}
|
|
961
|
+
this._bufferEdge(edgeData);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
// For literals, object literals, etc. - we could create edges from LITERAL nodes
|
|
965
|
+
// but for now we just track variable -> array flows
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Buffer FLOWS_INTO edges for object mutations (property assignment, Object.assign)
|
|
971
|
+
* Creates edges from source values to the object variable being mutated.
|
|
972
|
+
*
|
|
973
|
+
* REG-152: For 'this.prop = value' patterns inside classes, creates edges
|
|
974
|
+
* to the CLASS node with mutationType: 'this_property'.
|
|
975
|
+
*/
|
|
976
|
+
bufferObjectMutationEdges(objectMutations, variableDeclarations, parameters, functions, classDeclarations) {
|
|
977
|
+
for (const mutation of objectMutations) {
|
|
978
|
+
const { objectName, propertyName, mutationType, computedPropertyVar, value, file, enclosingClassName } = mutation;
|
|
979
|
+
// Find the target node (object variable, parameter, or class for 'this')
|
|
980
|
+
let objectNodeId = null;
|
|
981
|
+
let effectiveMutationType = mutationType;
|
|
982
|
+
if (objectName !== 'this') {
|
|
983
|
+
// Regular object - find variable or parameter
|
|
984
|
+
const objectVar = variableDeclarations.find(v => v.name === objectName && v.file === file);
|
|
985
|
+
const objectParam = !objectVar ? parameters.find(p => p.name === objectName && p.file === file) : null;
|
|
986
|
+
objectNodeId = objectVar?.id ?? objectParam?.id ?? null;
|
|
987
|
+
if (!objectNodeId)
|
|
988
|
+
continue;
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
// REG-152: 'this' mutations - find the CLASS node
|
|
992
|
+
if (!enclosingClassName)
|
|
993
|
+
continue; // Skip if no class context (e.g., standalone function)
|
|
994
|
+
// Compare using basename since classes use scopeTracker.file (basename)
|
|
995
|
+
// but mutations use module.file (full path)
|
|
996
|
+
const fileBasename = basename(file);
|
|
997
|
+
const classDecl = classDeclarations.find(c => c.name === enclosingClassName && c.file === fileBasename);
|
|
998
|
+
objectNodeId = classDecl?.id ?? null;
|
|
999
|
+
if (!objectNodeId)
|
|
1000
|
+
continue; // Skip if class not found
|
|
1001
|
+
// Use special mutation type to distinguish from regular property mutations
|
|
1002
|
+
effectiveMutationType = 'this_property';
|
|
1003
|
+
}
|
|
1004
|
+
// Create FLOWS_INTO edge for VARIABLE value type
|
|
1005
|
+
if (value.valueType === 'VARIABLE' && value.valueName) {
|
|
1006
|
+
// Find the source: can be variable, parameter, or function (arrow functions assigned to const)
|
|
1007
|
+
const sourceVar = variableDeclarations.find(v => v.name === value.valueName && v.file === file);
|
|
1008
|
+
const sourceParam = !sourceVar ? parameters.find(p => p.name === value.valueName && p.file === file) : null;
|
|
1009
|
+
const sourceFunc = !sourceVar && !sourceParam ? functions.find(f => f.name === value.valueName && f.file === file) : null;
|
|
1010
|
+
const sourceNodeId = sourceVar?.id ?? sourceParam?.id ?? sourceFunc?.id;
|
|
1011
|
+
if (sourceNodeId && objectNodeId) {
|
|
1012
|
+
const edgeData = {
|
|
1013
|
+
type: 'FLOWS_INTO',
|
|
1014
|
+
src: sourceNodeId,
|
|
1015
|
+
dst: objectNodeId,
|
|
1016
|
+
mutationType: effectiveMutationType,
|
|
1017
|
+
propertyName,
|
|
1018
|
+
computedPropertyVar // For enrichment phase resolution
|
|
1019
|
+
};
|
|
1020
|
+
if (value.argIndex !== undefined) {
|
|
1021
|
+
edgeData.argIndex = value.argIndex;
|
|
1022
|
+
}
|
|
1023
|
+
if (value.isSpread) {
|
|
1024
|
+
edgeData.isSpread = true;
|
|
1025
|
+
}
|
|
1026
|
+
this._bufferEdge(edgeData);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
// For literals, object literals, etc. - we just track variable -> object flows for now
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Buffer OBJECT_LITERAL nodes to the graph.
|
|
1034
|
+
* These are object literals passed as function arguments or nested in other literals.
|
|
1035
|
+
*/
|
|
1036
|
+
bufferObjectLiteralNodes(objectLiterals) {
|
|
1037
|
+
for (const obj of objectLiterals) {
|
|
1038
|
+
this._bufferNode({
|
|
1039
|
+
id: obj.id,
|
|
1040
|
+
type: obj.type,
|
|
1041
|
+
name: '<object>',
|
|
1042
|
+
file: obj.file,
|
|
1043
|
+
line: obj.line,
|
|
1044
|
+
column: obj.column,
|
|
1045
|
+
parentCallId: obj.parentCallId,
|
|
1046
|
+
argIndex: obj.argIndex
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Buffer ARRAY_LITERAL nodes to the graph.
|
|
1052
|
+
* These are array literals passed as function arguments or nested in other literals.
|
|
1053
|
+
*/
|
|
1054
|
+
bufferArrayLiteralNodes(arrayLiterals) {
|
|
1055
|
+
for (const arr of arrayLiterals) {
|
|
1056
|
+
this._bufferNode({
|
|
1057
|
+
id: arr.id,
|
|
1058
|
+
type: arr.type,
|
|
1059
|
+
name: '<array>',
|
|
1060
|
+
file: arr.file,
|
|
1061
|
+
line: arr.line,
|
|
1062
|
+
column: arr.column,
|
|
1063
|
+
parentCallId: arr.parentCallId,
|
|
1064
|
+
argIndex: arr.argIndex
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
951
1068
|
/**
|
|
952
1069
|
* Handle CLASS ASSIGNED_FROM edges asynchronously (needs graph queries)
|
|
953
1070
|
*/
|
|
@@ -977,101 +1094,4 @@ export class GraphBuilder {
|
|
|
977
1094
|
}
|
|
978
1095
|
return edgesCreated;
|
|
979
1096
|
}
|
|
980
|
-
/**
|
|
981
|
-
* Create IMPORTS_FROM edges linking imports to their target exports
|
|
982
|
-
*/
|
|
983
|
-
async createImportExportEdges(module, imports, _exports, graph, _projectPath) {
|
|
984
|
-
let edgesCreated = 0;
|
|
985
|
-
for (const imp of imports) {
|
|
986
|
-
const { source, specifiers, line } = imp;
|
|
987
|
-
// Только для относительных импортов
|
|
988
|
-
const isRelative = source.startsWith('./') || source.startsWith('../');
|
|
989
|
-
if (!isRelative) {
|
|
990
|
-
continue;
|
|
991
|
-
}
|
|
992
|
-
// Резолвим целевой модуль
|
|
993
|
-
const currentDir = dirname(module.file);
|
|
994
|
-
let targetPath = resolve(currentDir, source);
|
|
995
|
-
// Пытаемся найти файл с расширениями .js, .ts, .jsx, .tsx
|
|
996
|
-
const extensions = ['', '.js', '.ts', '.jsx', '.tsx', '/index.js', '/index.ts'];
|
|
997
|
-
let targetModule = null;
|
|
998
|
-
// Ищем MODULE ноду по file атрибуту (не по ID, т.к. формат ID изменился)
|
|
999
|
-
for (const ext of extensions) {
|
|
1000
|
-
const testPath = targetPath + ext;
|
|
1001
|
-
// Ищем MODULE с этим file path
|
|
1002
|
-
for await (const node of graph.queryNodes({ type: 'MODULE' })) {
|
|
1003
|
-
if (node.file === testPath) {
|
|
1004
|
-
targetModule = node;
|
|
1005
|
-
targetPath = testPath;
|
|
1006
|
-
break;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
if (targetModule)
|
|
1010
|
-
break;
|
|
1011
|
-
}
|
|
1012
|
-
if (!targetModule) {
|
|
1013
|
-
// Целевой модуль не найден в графе
|
|
1014
|
-
continue;
|
|
1015
|
-
}
|
|
1016
|
-
// Создаём IMPORTS edge от MODULE к MODULE (для совместимости с тестами)
|
|
1017
|
-
await graph.addEdge({
|
|
1018
|
-
type: 'IMPORTS',
|
|
1019
|
-
src: module.id,
|
|
1020
|
-
dst: targetModule.id
|
|
1021
|
-
});
|
|
1022
|
-
edgesCreated++;
|
|
1023
|
-
// Для каждого импортированного идентификатора создаём ребро к соответствующему EXPORT
|
|
1024
|
-
for (const spec of specifiers) {
|
|
1025
|
-
const importId = `${module.file}:IMPORT:${source}:${spec.local}:${line}`;
|
|
1026
|
-
const importType = spec.imported === 'default' ? 'default' :
|
|
1027
|
-
spec.imported === '*' ? 'namespace' : 'named';
|
|
1028
|
-
if (importType === 'namespace') {
|
|
1029
|
-
// import * as foo - связываем со всем модулем
|
|
1030
|
-
await graph.addEdge({
|
|
1031
|
-
type: 'IMPORTS_FROM',
|
|
1032
|
-
src: importId,
|
|
1033
|
-
dst: targetModule.id
|
|
1034
|
-
});
|
|
1035
|
-
edgesCreated++;
|
|
1036
|
-
}
|
|
1037
|
-
else if (importType === 'default') {
|
|
1038
|
-
// Находим EXPORT default в целевом модуле
|
|
1039
|
-
const targetExports = [];
|
|
1040
|
-
for await (const node of graph.queryNodes({ type: 'EXPORT' })) {
|
|
1041
|
-
const exportNode = node;
|
|
1042
|
-
if (exportNode.file === targetPath && exportNode.exportType === 'default') {
|
|
1043
|
-
targetExports.push(exportNode);
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
if (targetExports.length > 0) {
|
|
1047
|
-
await graph.addEdge({
|
|
1048
|
-
type: 'IMPORTS_FROM',
|
|
1049
|
-
src: importId,
|
|
1050
|
-
dst: targetExports[0].id
|
|
1051
|
-
});
|
|
1052
|
-
edgesCreated++;
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
else {
|
|
1056
|
-
// Named import - находим соответствующий named export
|
|
1057
|
-
const targetExports = [];
|
|
1058
|
-
for await (const node of graph.queryNodes({ type: 'EXPORT' })) {
|
|
1059
|
-
const exportNode = node;
|
|
1060
|
-
if (exportNode.file === targetPath && exportNode.exportType === 'named' && exportNode.name === spec.imported) {
|
|
1061
|
-
targetExports.push(exportNode);
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
if (targetExports.length > 0) {
|
|
1065
|
-
await graph.addEdge({
|
|
1066
|
-
type: 'IMPORTS_FROM',
|
|
1067
|
-
src: importId,
|
|
1068
|
-
dst: targetExports[0].id
|
|
1069
|
-
});
|
|
1070
|
-
edgesCreated++;
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
return edgesCreated;
|
|
1076
|
-
}
|
|
1077
1097
|
}
|