@grafema/core 0.2.4-beta → 0.2.6-beta
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 +61 -23
- package/dist/DiscoveryManager.d.ts +59 -0
- package/dist/DiscoveryManager.d.ts.map +1 -0
- package/dist/DiscoveryManager.js +249 -0
- package/dist/DiscoveryManager.js.map +1 -0
- package/dist/GraphInitializer.d.ts +44 -0
- package/dist/GraphInitializer.d.ts.map +1 -0
- package/dist/GraphInitializer.js +121 -0
- package/dist/GraphInitializer.js.map +1 -0
- package/dist/GuaranteeChecker.d.ts +35 -0
- package/dist/GuaranteeChecker.d.ts.map +1 -0
- package/dist/GuaranteeChecker.js +81 -0
- package/dist/GuaranteeChecker.js.map +1 -0
- package/dist/Orchestrator.d.ts +42 -122
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +228 -513
- package/dist/Orchestrator.js.map +1 -0
- package/dist/OrchestratorTypes.d.ts +115 -0
- package/dist/OrchestratorTypes.d.ts.map +1 -0
- package/dist/OrchestratorTypes.js +6 -0
- package/dist/OrchestratorTypes.js.map +1 -0
- package/dist/ParallelAnalysisRunner.d.ts +43 -0
- package/dist/ParallelAnalysisRunner.d.ts.map +1 -0
- package/dist/ParallelAnalysisRunner.js +161 -0
- package/dist/ParallelAnalysisRunner.js.map +1 -0
- package/dist/PhaseRunner.d.ts +92 -0
- package/dist/PhaseRunner.d.ts.map +1 -0
- package/dist/PhaseRunner.js +332 -0
- package/dist/PhaseRunner.js.map +1 -0
- package/dist/api/GraphAPI.d.ts +1 -1
- package/dist/api/GraphAPI.d.ts.map +1 -1
- package/dist/api/GraphAPI.js +3 -1
- package/dist/api/GraphAPI.js.map +1 -0
- package/dist/api/GuaranteeAPI.d.ts.map +1 -1
- package/dist/api/GuaranteeAPI.js +4 -2
- package/dist/api/GuaranteeAPI.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +117 -1
- package/dist/config/ConfigLoader.d.ts.map +1 -1
- package/dist/config/ConfigLoader.js +198 -4
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -1
- package/dist/config/index.js.map +1 -0
- package/dist/core/ASTWorker.d.ts +2 -0
- package/dist/core/ASTWorker.d.ts.map +1 -1
- package/dist/core/ASTWorker.js +12 -6
- package/dist/core/ASTWorker.js.map +1 -0
- package/dist/core/ASTWorkerPool.js +2 -1
- package/dist/core/ASTWorkerPool.js.map +1 -0
- package/dist/core/AnalysisQueue.js +1 -0
- package/dist/core/AnalysisQueue.js.map +1 -0
- package/dist/core/CoverageAnalyzer.d.ts.map +1 -1
- package/dist/core/CoverageAnalyzer.js +1 -0
- package/dist/core/CoverageAnalyzer.js.map +1 -0
- package/dist/core/FileExplainer.js +1 -0
- package/dist/core/FileExplainer.js.map +1 -0
- package/dist/core/FileNodeManager.d.ts.map +1 -1
- package/dist/core/FileNodeManager.js +4 -2
- package/dist/core/FileNodeManager.js.map +1 -0
- package/dist/core/FileOverview.d.ts +124 -0
- package/dist/core/FileOverview.d.ts.map +1 -0
- package/dist/core/FileOverview.js +257 -0
- package/dist/core/FileOverview.js.map +1 -0
- package/dist/core/GraphBackend.js +1 -0
- package/dist/core/GraphBackend.js.map +1 -0
- package/dist/core/GraphFreshnessChecker.d.ts +1 -1
- package/dist/core/GraphFreshnessChecker.d.ts.map +1 -1
- package/dist/core/GraphFreshnessChecker.js +8 -5
- package/dist/core/GraphFreshnessChecker.js.map +1 -0
- package/dist/core/GuaranteeManager.d.ts +13 -0
- package/dist/core/GuaranteeManager.d.ts.map +1 -1
- package/dist/core/GuaranteeManager.js +65 -3
- package/dist/core/GuaranteeManager.js.map +1 -0
- package/dist/core/HashUtils.js +1 -0
- package/dist/core/HashUtils.js.map +1 -0
- package/dist/core/IncrementalReanalyzer.d.ts.map +1 -1
- package/dist/core/IncrementalReanalyzer.js +13 -6
- package/dist/core/IncrementalReanalyzer.js.map +1 -0
- package/dist/core/ManifestStore.js +1 -0
- package/dist/core/ManifestStore.js.map +1 -0
- package/dist/core/NodeFactory.d.ts +82 -396
- package/dist/core/NodeFactory.d.ts.map +1 -1
- package/dist/core/NodeFactory.js +144 -322
- package/dist/core/NodeFactory.js.map +1 -0
- package/dist/core/NodeId.js +1 -0
- package/dist/core/NodeId.js.map +1 -0
- package/dist/core/PriorityQueue.js +1 -0
- package/dist/core/PriorityQueue.js.map +1 -0
- package/dist/core/Profiler.js +1 -0
- package/dist/core/Profiler.js.map +1 -0
- package/dist/core/ResourceRegistry.d.ts +17 -0
- package/dist/core/ResourceRegistry.d.ts.map +1 -0
- package/dist/core/ResourceRegistry.js +32 -0
- package/dist/core/ResourceRegistry.js.map +1 -0
- package/dist/core/ScopeTracker.d.ts +12 -0
- package/dist/core/ScopeTracker.d.ts.map +1 -1
- package/dist/core/ScopeTracker.js +25 -0
- package/dist/core/ScopeTracker.js.map +1 -0
- package/dist/core/SemanticId.d.ts +69 -0
- package/dist/core/SemanticId.d.ts.map +1 -1
- package/dist/core/SemanticId.js +135 -0
- package/dist/core/SemanticId.js.map +1 -0
- package/dist/core/Task.js +1 -0
- package/dist/core/Task.js.map +1 -0
- package/dist/core/TaskTypes.js +1 -0
- package/dist/core/TaskTypes.js.map +1 -0
- package/dist/core/VersionManager.js +1 -0
- package/dist/core/VersionManager.js.map +1 -0
- package/dist/core/WorkerPool.d.ts.map +1 -1
- package/dist/core/WorkerPool.js +3 -1
- package/dist/core/WorkerPool.js.map +1 -0
- package/dist/core/brandNodeInternal.d.ts +14 -0
- package/dist/core/brandNodeInternal.d.ts.map +1 -0
- package/dist/core/brandNodeInternal.js +4 -0
- package/dist/core/brandNodeInternal.js.map +1 -0
- package/dist/core/buildDependencyGraph.d.ts +36 -0
- package/dist/core/buildDependencyGraph.d.ts.map +1 -0
- package/dist/core/buildDependencyGraph.js +78 -0
- package/dist/core/buildDependencyGraph.js.map +1 -0
- package/dist/core/factories/CoreFactory.d.ts +223 -0
- package/dist/core/factories/CoreFactory.d.ts.map +1 -0
- package/dist/core/factories/CoreFactory.js +127 -0
- package/dist/core/factories/CoreFactory.js.map +1 -0
- package/dist/core/factories/DatabaseFactory.d.ts +29 -0
- package/dist/core/factories/DatabaseFactory.d.ts.map +1 -0
- package/dist/core/factories/DatabaseFactory.js +25 -0
- package/dist/core/factories/DatabaseFactory.js.map +1 -0
- package/dist/core/factories/ExternalFactory.d.ts +11 -0
- package/dist/core/factories/ExternalFactory.d.ts.map +1 -0
- package/dist/core/factories/ExternalFactory.js +16 -0
- package/dist/core/factories/ExternalFactory.js.map +1 -0
- package/dist/core/factories/HttpFactory.d.ts +22 -0
- package/dist/core/factories/HttpFactory.d.ts.map +1 -0
- package/dist/core/factories/HttpFactory.js +32 -0
- package/dist/core/factories/HttpFactory.js.map +1 -0
- package/dist/core/factories/ReactFactory.d.ts +14 -0
- package/dist/core/factories/ReactFactory.d.ts.map +1 -0
- package/dist/core/factories/ReactFactory.js +13 -0
- package/dist/core/factories/ReactFactory.js.map +1 -0
- package/dist/core/factories/RustFactory.d.ts +62 -0
- package/dist/core/factories/RustFactory.d.ts.map +1 -0
- package/dist/core/factories/RustFactory.js +32 -0
- package/dist/core/factories/RustFactory.js.map +1 -0
- package/dist/core/factories/ServiceFactory.d.ts +12 -0
- package/dist/core/factories/ServiceFactory.d.ts.map +1 -0
- package/dist/core/factories/ServiceFactory.js +22 -0
- package/dist/core/factories/ServiceFactory.js.map +1 -0
- package/dist/core/factories/SocketFactory.d.ts +31 -0
- package/dist/core/factories/SocketFactory.d.ts.map +1 -0
- package/dist/core/factories/SocketFactory.js +35 -0
- package/dist/core/factories/SocketFactory.js.map +1 -0
- package/dist/core/nodes/ArgumentExpressionNode.js +1 -0
- package/dist/core/nodes/ArgumentExpressionNode.js.map +1 -0
- package/dist/core/nodes/ArrayLiteralNode.js +1 -0
- package/dist/core/nodes/ArrayLiteralNode.js.map +1 -0
- package/dist/core/nodes/BranchNode.js +1 -0
- package/dist/core/nodes/BranchNode.js.map +1 -0
- package/dist/core/nodes/CallSiteNode.js +1 -0
- package/dist/core/nodes/CallSiteNode.js.map +1 -0
- package/dist/core/nodes/CaseNode.js +1 -0
- package/dist/core/nodes/CaseNode.js.map +1 -0
- package/dist/core/nodes/ClassNode.js +1 -0
- package/dist/core/nodes/ClassNode.js.map +1 -0
- package/dist/core/nodes/ConstantNode.js +1 -0
- package/dist/core/nodes/ConstantNode.js.map +1 -0
- package/dist/core/nodes/ConstructorCallNode.js +1 -0
- package/dist/core/nodes/ConstructorCallNode.js.map +1 -0
- package/dist/core/nodes/DatabaseNode.d.ts +85 -0
- package/dist/core/nodes/DatabaseNode.d.ts.map +1 -0
- package/dist/core/nodes/DatabaseNode.js +118 -0
- package/dist/core/nodes/DatabaseNode.js.map +1 -0
- package/dist/core/nodes/DatabaseQueryNode.js +1 -0
- package/dist/core/nodes/DatabaseQueryNode.js.map +1 -0
- package/dist/core/nodes/DecoratorNode.js +1 -0
- package/dist/core/nodes/DecoratorNode.js.map +1 -0
- package/dist/core/nodes/EntrypointNode.js +1 -0
- package/dist/core/nodes/EntrypointNode.js.map +1 -0
- package/dist/core/nodes/EnumNode.js +1 -0
- package/dist/core/nodes/EnumNode.js.map +1 -0
- package/dist/core/nodes/EventListenerNode.js +1 -0
- package/dist/core/nodes/EventListenerNode.js.map +1 -0
- package/dist/core/nodes/ExportNode.js +1 -0
- package/dist/core/nodes/ExportNode.js.map +1 -0
- package/dist/core/nodes/ExpressMiddlewareNode.d.ts +47 -0
- package/dist/core/nodes/ExpressMiddlewareNode.d.ts.map +1 -0
- package/dist/core/nodes/ExpressMiddlewareNode.js +63 -0
- package/dist/core/nodes/ExpressMiddlewareNode.js.map +1 -0
- package/dist/core/nodes/ExpressMountNode.d.ts +44 -0
- package/dist/core/nodes/ExpressMountNode.d.ts.map +1 -0
- package/dist/core/nodes/ExpressMountNode.js +61 -0
- package/dist/core/nodes/ExpressMountNode.js.map +1 -0
- package/dist/core/nodes/ExpressionNode.js +1 -0
- package/dist/core/nodes/ExpressionNode.js.map +1 -0
- package/dist/core/nodes/ExternalApiNode.d.ts +29 -0
- package/dist/core/nodes/ExternalApiNode.d.ts.map +1 -0
- package/dist/core/nodes/ExternalApiNode.js +41 -0
- package/dist/core/nodes/ExternalApiNode.js.map +1 -0
- package/dist/core/nodes/ExternalFunctionNode.d.ts +40 -0
- package/dist/core/nodes/ExternalFunctionNode.d.ts.map +1 -0
- package/dist/core/nodes/ExternalFunctionNode.js +54 -0
- package/dist/core/nodes/ExternalFunctionNode.js.map +1 -0
- package/dist/core/nodes/ExternalModuleNode.js +1 -0
- package/dist/core/nodes/ExternalModuleNode.js.map +1 -0
- package/dist/core/nodes/ExternalStdioNode.js +1 -0
- package/dist/core/nodes/ExternalStdioNode.js.map +1 -0
- package/dist/core/nodes/FetchRequestNode.d.ts +54 -0
- package/dist/core/nodes/FetchRequestNode.d.ts.map +1 -0
- package/dist/core/nodes/FetchRequestNode.js +67 -0
- package/dist/core/nodes/FetchRequestNode.js.map +1 -0
- package/dist/core/nodes/FunctionNode.js +1 -0
- package/dist/core/nodes/FunctionNode.js.map +1 -0
- package/dist/core/nodes/GuaranteeNode.js +1 -0
- package/dist/core/nodes/GuaranteeNode.js.map +1 -0
- package/dist/core/nodes/HttpRequestNode.js +1 -0
- package/dist/core/nodes/HttpRequestNode.js.map +1 -0
- package/dist/core/nodes/HttpRouteNode.d.ts +58 -0
- package/dist/core/nodes/HttpRouteNode.d.ts.map +1 -0
- package/dist/core/nodes/HttpRouteNode.js +72 -0
- package/dist/core/nodes/HttpRouteNode.js.map +1 -0
- package/dist/core/nodes/ImportNode.js +1 -0
- package/dist/core/nodes/ImportNode.js.map +1 -0
- package/dist/core/nodes/InterfaceNode.js +1 -0
- package/dist/core/nodes/InterfaceNode.js.map +1 -0
- package/dist/core/nodes/IssueNode.js +1 -0
- package/dist/core/nodes/IssueNode.js.map +1 -0
- package/dist/core/nodes/LiteralNode.js +1 -0
- package/dist/core/nodes/LiteralNode.js.map +1 -0
- package/dist/core/nodes/MethodCallNode.js +1 -0
- package/dist/core/nodes/MethodCallNode.js.map +1 -0
- package/dist/core/nodes/MethodNode.js +1 -0
- package/dist/core/nodes/MethodNode.js.map +1 -0
- package/dist/core/nodes/ModuleNode.js +1 -0
- package/dist/core/nodes/ModuleNode.js.map +1 -0
- package/dist/core/nodes/NetworkRequestNode.js +1 -0
- package/dist/core/nodes/NetworkRequestNode.js.map +1 -0
- package/dist/core/nodes/NodeKind.d.ts +6 -0
- package/dist/core/nodes/NodeKind.d.ts.map +1 -1
- package/dist/core/nodes/NodeKind.js +12 -0
- package/dist/core/nodes/NodeKind.js.map +1 -0
- package/dist/core/nodes/ObjectLiteralNode.js +1 -0
- package/dist/core/nodes/ObjectLiteralNode.js.map +1 -0
- package/dist/core/nodes/ParameterNode.js +1 -0
- package/dist/core/nodes/ParameterNode.js.map +1 -0
- package/dist/core/nodes/PluginNode.d.ts +69 -0
- package/dist/core/nodes/PluginNode.d.ts.map +1 -0
- package/dist/core/nodes/PluginNode.js +106 -0
- package/dist/core/nodes/PluginNode.js.map +1 -0
- package/dist/core/nodes/ReactNode.d.ts +53 -0
- package/dist/core/nodes/ReactNode.d.ts.map +1 -0
- package/dist/core/nodes/ReactNode.js +70 -0
- package/dist/core/nodes/ReactNode.js.map +1 -0
- package/dist/core/nodes/RustCallNode.d.ts +46 -0
- package/dist/core/nodes/RustCallNode.d.ts.map +1 -0
- package/dist/core/nodes/RustCallNode.js +62 -0
- package/dist/core/nodes/RustCallNode.js.map +1 -0
- package/dist/core/nodes/RustFunctionNode.d.ts +58 -0
- package/dist/core/nodes/RustFunctionNode.d.ts.map +1 -0
- package/dist/core/nodes/RustFunctionNode.js +67 -0
- package/dist/core/nodes/RustFunctionNode.js.map +1 -0
- package/dist/core/nodes/RustImplNode.d.ts +35 -0
- package/dist/core/nodes/RustImplNode.d.ts.map +1 -0
- package/dist/core/nodes/RustImplNode.js +55 -0
- package/dist/core/nodes/RustImplNode.js.map +1 -0
- package/dist/core/nodes/RustMethodNode.d.ts +64 -0
- package/dist/core/nodes/RustMethodNode.d.ts.map +1 -0
- package/dist/core/nodes/RustMethodNode.js +76 -0
- package/dist/core/nodes/RustMethodNode.js.map +1 -0
- package/dist/core/nodes/RustModuleNode.d.ts +40 -0
- package/dist/core/nodes/RustModuleNode.d.ts.map +1 -0
- package/dist/core/nodes/RustModuleNode.js +57 -0
- package/dist/core/nodes/RustModuleNode.js.map +1 -0
- package/dist/core/nodes/RustStructNode.d.ts +38 -0
- package/dist/core/nodes/RustStructNode.d.ts.map +1 -0
- package/dist/core/nodes/RustStructNode.js +54 -0
- package/dist/core/nodes/RustStructNode.js.map +1 -0
- package/dist/core/nodes/RustTraitNode.d.ts +40 -0
- package/dist/core/nodes/RustTraitNode.d.ts.map +1 -0
- package/dist/core/nodes/RustTraitNode.js +52 -0
- package/dist/core/nodes/RustTraitNode.js.map +1 -0
- package/dist/core/nodes/ScopeNode.js +1 -0
- package/dist/core/nodes/ScopeNode.js.map +1 -0
- package/dist/core/nodes/ServiceLayerNode.d.ts +85 -0
- package/dist/core/nodes/ServiceLayerNode.d.ts.map +1 -0
- package/dist/core/nodes/ServiceLayerNode.js +122 -0
- package/dist/core/nodes/ServiceLayerNode.js.map +1 -0
- package/dist/core/nodes/ServiceNode.js +1 -0
- package/dist/core/nodes/ServiceNode.js.map +1 -0
- package/dist/core/nodes/SocketIONode.d.ts +71 -0
- package/dist/core/nodes/SocketIONode.d.ts.map +1 -0
- package/dist/core/nodes/SocketIONode.js +111 -0
- package/dist/core/nodes/SocketIONode.js.map +1 -0
- package/dist/core/nodes/SocketNode.d.ts +87 -0
- package/dist/core/nodes/SocketNode.d.ts.map +1 -0
- package/dist/core/nodes/SocketNode.js +124 -0
- package/dist/core/nodes/SocketNode.js.map +1 -0
- package/dist/core/nodes/TypeNode.d.ts +26 -1
- package/dist/core/nodes/TypeNode.d.ts.map +1 -1
- package/dist/core/nodes/TypeNode.js +23 -4
- package/dist/core/nodes/TypeNode.js.map +1 -0
- package/dist/core/nodes/TypeParameterNode.d.ts +44 -0
- package/dist/core/nodes/TypeParameterNode.d.ts.map +1 -0
- package/dist/core/nodes/TypeParameterNode.js +64 -0
- package/dist/core/nodes/TypeParameterNode.js.map +1 -0
- package/dist/core/nodes/VariableDeclarationNode.js +1 -0
- package/dist/core/nodes/VariableDeclarationNode.js.map +1 -0
- package/dist/core/nodes/index.d.ts +21 -1
- package/dist/core/nodes/index.d.ts.map +1 -1
- package/dist/core/nodes/index.js +30 -1
- package/dist/core/nodes/index.js.map +1 -0
- package/dist/core/toposort.d.ts +38 -0
- package/dist/core/toposort.d.ts.map +1 -0
- package/dist/core/toposort.js +129 -0
- package/dist/core/toposort.js.map +1 -0
- package/dist/data/builtins/BuiltinRegistry.js +1 -0
- package/dist/data/builtins/BuiltinRegistry.js.map +1 -0
- package/dist/data/builtins/definitions.js +1 -0
- package/dist/data/builtins/definitions.js.map +1 -0
- package/dist/data/builtins/index.js +1 -0
- package/dist/data/builtins/index.js.map +1 -0
- package/dist/data/builtins/jsGlobals.js +1 -0
- package/dist/data/builtins/jsGlobals.js.map +1 -0
- package/dist/data/builtins/types.js +1 -0
- package/dist/data/builtins/types.js.map +1 -0
- package/dist/data/globals/definitions.js +1 -0
- package/dist/data/globals/definitions.js.map +1 -0
- package/dist/data/globals/index.js +1 -0
- package/dist/data/globals/index.js.map +1 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts +5 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -1
- package/dist/diagnostics/DiagnosticCollector.js +4 -0
- package/dist/diagnostics/DiagnosticCollector.js.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts +23 -1
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -1
- package/dist/diagnostics/DiagnosticReporter.js +68 -15
- package/dist/diagnostics/DiagnosticReporter.js.map +1 -0
- package/dist/diagnostics/DiagnosticWriter.js +1 -0
- package/dist/diagnostics/DiagnosticWriter.js.map +1 -0
- package/dist/diagnostics/categories.d.ts +57 -0
- package/dist/diagnostics/categories.d.ts.map +1 -0
- package/dist/diagnostics/categories.js +71 -0
- package/dist/diagnostics/categories.js.map +1 -0
- package/dist/diagnostics/index.d.ts +3 -0
- package/dist/diagnostics/index.d.ts.map +1 -1
- package/dist/diagnostics/index.js +4 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/errors/GrafemaError.d.ts +39 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -1
- package/dist/errors/GrafemaError.js +28 -0
- package/dist/errors/GrafemaError.js.map +1 -0
- package/dist/index.d.ts +53 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -9
- package/dist/index.js.map +1 -0
- package/dist/instructions/index.d.ts +8 -0
- package/dist/instructions/index.d.ts.map +1 -0
- package/dist/instructions/index.js +20 -0
- package/dist/instructions/index.js.map +1 -0
- package/dist/instructions/onboarding.md +121 -0
- package/dist/logging/Logger.d.ts +53 -3
- package/dist/logging/Logger.d.ts.map +1 -1
- package/dist/logging/Logger.js +144 -4
- package/dist/logging/Logger.js.map +1 -0
- package/dist/plugins/InfraAnalyzer.d.ts +110 -0
- package/dist/plugins/InfraAnalyzer.d.ts.map +1 -0
- package/dist/plugins/InfraAnalyzer.js +170 -0
- package/dist/plugins/InfraAnalyzer.js.map +1 -0
- package/dist/plugins/Plugin.js +1 -0
- package/dist/plugins/Plugin.js.map +1 -0
- package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.js +35 -26
- package/dist/plugins/analysis/DatabaseAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.js +44 -36
- package/dist/plugins/analysis/ExpressAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts +2 -1
- package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressResponseAnalyzer.js +56 -77
- package/dist/plugins/analysis/ExpressResponseAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js +69 -62
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts +8 -14
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.js +162 -131
- package/dist/plugins/analysis/FetchAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -1
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +6 -7
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.js.map +1 -0
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts +77 -82
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +811 -1843
- package/dist/plugins/analysis/JSASTAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/NestJSRouteAnalyzer.d.ts +28 -0
- package/dist/plugins/analysis/NestJSRouteAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/NestJSRouteAnalyzer.js +196 -0
- package/dist/plugins/analysis/NestJSRouteAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/ReactAnalyzer.d.ts +1 -61
- package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ReactAnalyzer.js +41 -927
- package/dist/plugins/analysis/ReactAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/RustAnalyzer.js +62 -84
- package/dist/plugins/analysis/RustAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.js +26 -12
- package/dist/plugins/analysis/SQLiteAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ServiceLayerAnalyzer.js +39 -31
- package/dist/plugins/analysis/ServiceLayerAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/SocketAnalyzer.d.ts +81 -0
- package/dist/plugins/analysis/SocketAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/SocketAnalyzer.js +475 -0
- package/dist/plugins/analysis/SocketAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SocketIOAnalyzer.js +33 -28
- package/dist/plugins/analysis/SocketIOAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SystemDbAnalyzer.js +25 -14
- package/dist/plugins/analysis/SystemDbAnalyzer.js.map +1 -0
- package/dist/plugins/analysis/ast/CollisionResolver.d.ts +65 -0
- package/dist/plugins/analysis/ast/CollisionResolver.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/CollisionResolver.js +106 -0
- package/dist/plugins/analysis/ast/CollisionResolver.js.map +1 -0
- package/dist/plugins/analysis/ast/ConditionParser.js +1 -0
- package/dist/plugins/analysis/ast/ConditionParser.js.map +1 -0
- package/dist/plugins/analysis/ast/ExpressionEvaluator.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/ExpressionEvaluator.js +1 -0
- package/dist/plugins/analysis/ast/ExpressionEvaluator.js.map +1 -0
- package/dist/plugins/analysis/ast/FunctionBodyContext.d.ts +124 -0
- package/dist/plugins/analysis/ast/FunctionBodyContext.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/FunctionBodyContext.js +151 -0
- package/dist/plugins/analysis/ast/FunctionBodyContext.js.map +1 -0
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts +26 -209
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +164 -2023
- package/dist/plugins/analysis/ast/GraphBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/IdGenerator.d.ts +42 -0
- package/dist/plugins/analysis/ast/IdGenerator.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/IdGenerator.js +62 -1
- package/dist/plugins/analysis/ast/IdGenerator.js.map +1 -0
- package/dist/plugins/analysis/ast/OxcAdapter.js +1 -0
- package/dist/plugins/analysis/ast/OxcAdapter.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/AssignmentBuilder.d.ts +15 -0
- package/dist/plugins/analysis/ast/builders/AssignmentBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/AssignmentBuilder.js +274 -0
- package/dist/plugins/analysis/ast/builders/AssignmentBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/CallFlowBuilder.d.ts +22 -0
- package/dist/plugins/analysis/ast/builders/CallFlowBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/CallFlowBuilder.js +178 -0
- package/dist/plugins/analysis/ast/builders/CallFlowBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/ControlFlowBuilder.d.ts +76 -0
- package/dist/plugins/analysis/ast/builders/ControlFlowBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/ControlFlowBuilder.js +387 -0
- package/dist/plugins/analysis/ast/builders/ControlFlowBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/CoreBuilder.d.ts +38 -0
- package/dist/plugins/analysis/ast/builders/CoreBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/CoreBuilder.js +240 -0
- package/dist/plugins/analysis/ast/builders/CoreBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.d.ts +53 -0
- package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.js +355 -0
- package/dist/plugins/analysis/ast/builders/ModuleRuntimeBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/MutationBuilder.d.ts +46 -0
- package/dist/plugins/analysis/ast/builders/MutationBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/MutationBuilder.js +264 -0
- package/dist/plugins/analysis/ast/builders/MutationBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/ReturnBuilder.d.ts +23 -0
- package/dist/plugins/analysis/ast/builders/ReturnBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/ReturnBuilder.js +206 -0
- package/dist/plugins/analysis/ast/builders/ReturnBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/TypeSystemBuilder.d.ts +64 -0
- package/dist/plugins/analysis/ast/builders/TypeSystemBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/TypeSystemBuilder.js +370 -0
- package/dist/plugins/analysis/ast/builders/TypeSystemBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/UpdateExpressionBuilder.d.ts +46 -0
- package/dist/plugins/analysis/ast/builders/UpdateExpressionBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/UpdateExpressionBuilder.js +191 -0
- package/dist/plugins/analysis/ast/builders/UpdateExpressionBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/YieldBuilder.d.ts +30 -0
- package/dist/plugins/analysis/ast/builders/YieldBuilder.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/YieldBuilder.js +214 -0
- package/dist/plugins/analysis/ast/builders/YieldBuilder.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/index.d.ts +12 -0
- package/dist/plugins/analysis/ast/builders/index.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/index.js +11 -0
- package/dist/plugins/analysis/ast/builders/index.js.map +1 -0
- package/dist/plugins/analysis/ast/builders/types.d.ts +30 -0
- package/dist/plugins/analysis/ast/builders/types.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/builders/types.js +8 -0
- package/dist/plugins/analysis/ast/builders/types.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/AnalyzerDelegate.d.ts +50 -0
- package/dist/plugins/analysis/ast/handlers/AnalyzerDelegate.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/AnalyzerDelegate.js +2 -0
- package/dist/plugins/analysis/ast/handlers/AnalyzerDelegate.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/BranchHandler.d.ts +18 -0
- package/dist/plugins/analysis/ast/handlers/BranchHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/BranchHandler.js +244 -0
- package/dist/plugins/analysis/ast/handlers/BranchHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/CallExpressionHandler.d.ts +7 -0
- package/dist/plugins/analysis/ast/handlers/CallExpressionHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/CallExpressionHandler.js +295 -0
- package/dist/plugins/analysis/ast/handlers/CallExpressionHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/FunctionBodyHandler.d.ts +22 -0
- package/dist/plugins/analysis/ast/handlers/FunctionBodyHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/FunctionBodyHandler.js +9 -0
- package/dist/plugins/analysis/ast/handlers/FunctionBodyHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/LoopHandler.d.ts +13 -0
- package/dist/plugins/analysis/ast/handlers/LoopHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/LoopHandler.js +207 -0
- package/dist/plugins/analysis/ast/handlers/LoopHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/NestedFunctionHandler.d.ts +13 -0
- package/dist/plugins/analysis/ast/handlers/NestedFunctionHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/NestedFunctionHandler.js +174 -0
- package/dist/plugins/analysis/ast/handlers/NestedFunctionHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.d.ts +12 -0
- package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.js +135 -0
- package/dist/plugins/analysis/ast/handlers/NewExpressionHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/PropertyAccessHandler.d.ts +13 -0
- package/dist/plugins/analysis/ast/handlers/PropertyAccessHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/PropertyAccessHandler.js +71 -0
- package/dist/plugins/analysis/ast/handlers/PropertyAccessHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/ReturnYieldHandler.d.ts +12 -0
- package/dist/plugins/analysis/ast/handlers/ReturnYieldHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/ReturnYieldHandler.js +135 -0
- package/dist/plugins/analysis/ast/handlers/ReturnYieldHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/ThrowHandler.d.ts +12 -0
- package/dist/plugins/analysis/ast/handlers/ThrowHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/ThrowHandler.js +82 -0
- package/dist/plugins/analysis/ast/handlers/ThrowHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/TryCatchHandler.d.ts +14 -0
- package/dist/plugins/analysis/ast/handlers/TryCatchHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/TryCatchHandler.js +220 -0
- package/dist/plugins/analysis/ast/handlers/TryCatchHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/VariableHandler.d.ts +12 -0
- package/dist/plugins/analysis/ast/handlers/VariableHandler.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/VariableHandler.js +57 -0
- package/dist/plugins/analysis/ast/handlers/VariableHandler.js.map +1 -0
- package/dist/plugins/analysis/ast/handlers/index.d.ts +13 -0
- package/dist/plugins/analysis/ast/handlers/index.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/handlers/index.js +12 -0
- package/dist/plugins/analysis/ast/handlers/index.js.map +1 -0
- package/dist/plugins/analysis/ast/types.d.ts +203 -1
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/types.js +1 -0
- package/dist/plugins/analysis/ast/types.js.map +1 -0
- package/dist/plugins/analysis/ast/utils/babelTraverse.d.ts +27 -0
- package/dist/plugins/analysis/ast/utils/babelTraverse.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/babelTraverse.js +45 -0
- package/dist/plugins/analysis/ast/utils/babelTraverse.js.map +1 -0
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts +6 -5
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/utils/createParameterNodes.js +95 -13
- package/dist/plugins/analysis/ast/utils/createParameterNodes.js.map +1 -0
- package/dist/plugins/analysis/ast/utils/extractNamesFromPattern.d.ts +81 -0
- package/dist/plugins/analysis/ast/utils/extractNamesFromPattern.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/extractNamesFromPattern.js +140 -0
- package/dist/plugins/analysis/ast/utils/extractNamesFromPattern.js.map +1 -0
- package/dist/plugins/analysis/ast/utils/getExpressionValue.d.ts +22 -0
- package/dist/plugins/analysis/ast/utils/getExpressionValue.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/getExpressionValue.js +35 -0
- package/dist/plugins/analysis/ast/utils/getExpressionValue.js.map +1 -0
- package/dist/plugins/analysis/ast/utils/getMemberExpressionName.d.ts +25 -0
- package/dist/plugins/analysis/ast/utils/getMemberExpressionName.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/getMemberExpressionName.js +21 -0
- package/dist/plugins/analysis/ast/utils/getMemberExpressionName.js.map +1 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts +2 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/utils/index.js +3 -0
- package/dist/plugins/analysis/ast/utils/index.js.map +1 -0
- package/dist/plugins/analysis/ast/utils/location.js +1 -0
- package/dist/plugins/analysis/ast/utils/location.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +3 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +1 -0
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ArgumentExtractor.d.ts +23 -0
- package/dist/plugins/analysis/ast/visitors/ArgumentExtractor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ArgumentExtractor.js +241 -0
- package/dist/plugins/analysis/ast/visitors/ArgumentExtractor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ArrayElementExtractor.d.ts +20 -0
- package/dist/plugins/analysis/ast/visitors/ArrayElementExtractor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ArrayElementExtractor.js +110 -0
- package/dist/plugins/analysis/ast/visitors/ArrayElementExtractor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +20 -140
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +335 -837
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +1 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +218 -5
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +4 -3
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +26 -8
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +1 -0
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/MutationDetector.d.ts +25 -0
- package/dist/plugins/analysis/ast/visitors/MutationDetector.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/MutationDetector.js +181 -0
- package/dist/plugins/analysis/ast/visitors/MutationDetector.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ObjectPropertyExtractor.d.ts +20 -0
- package/dist/plugins/analysis/ast/visitors/ObjectPropertyExtractor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/ObjectPropertyExtractor.js +155 -0
- package/dist/plugins/analysis/ast/visitors/ObjectPropertyExtractor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/PropertyAccessVisitor.d.ts +91 -0
- package/dist/plugins/analysis/ast/visitors/PropertyAccessVisitor.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/PropertyAccessVisitor.js +306 -0
- package/dist/plugins/analysis/ast/visitors/PropertyAccessVisitor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +21 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +189 -12
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +7 -4
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/call-expression-helpers.d.ts +19 -0
- package/dist/plugins/analysis/ast/visitors/call-expression-helpers.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/call-expression-helpers.js +57 -0
- package/dist/plugins/analysis/ast/visitors/call-expression-helpers.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/call-expression-types.d.ts +168 -0
- package/dist/plugins/analysis/ast/visitors/call-expression-types.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/visitors/call-expression-types.js +7 -0
- package/dist/plugins/analysis/ast/visitors/call-expression-types.js.map +1 -0
- package/dist/plugins/analysis/ast/visitors/index.d.ts +1 -0
- package/dist/plugins/analysis/ast/visitors/index.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/index.js +2 -0
- package/dist/plugins/analysis/ast/visitors/index.js.map +1 -0
- package/dist/plugins/analysis/react-internal/browser-api.d.ts +20 -0
- package/dist/plugins/analysis/react-internal/browser-api.d.ts.map +1 -0
- package/dist/plugins/analysis/react-internal/browser-api.js +140 -0
- package/dist/plugins/analysis/react-internal/browser-api.js.map +1 -0
- package/dist/plugins/analysis/react-internal/hooks.d.ts +31 -0
- package/dist/plugins/analysis/react-internal/hooks.d.ts.map +1 -0
- package/dist/plugins/analysis/react-internal/hooks.js +465 -0
- package/dist/plugins/analysis/react-internal/hooks.js.map +1 -0
- package/dist/plugins/analysis/react-internal/jsx.d.ts +43 -0
- package/dist/plugins/analysis/react-internal/jsx.d.ts.map +1 -0
- package/dist/plugins/analysis/react-internal/jsx.js +231 -0
- package/dist/plugins/analysis/react-internal/jsx.js.map +1 -0
- package/dist/plugins/analysis/react-internal/types.d.ts +116 -0
- package/dist/plugins/analysis/react-internal/types.d.ts.map +1 -0
- package/dist/plugins/analysis/react-internal/types.js +83 -0
- package/dist/plugins/analysis/react-internal/types.js.map +1 -0
- package/dist/plugins/discovery/DiscoveryPlugin.d.ts +42 -10
- package/dist/plugins/discovery/DiscoveryPlugin.d.ts.map +1 -1
- package/dist/plugins/discovery/DiscoveryPlugin.js +17 -1
- package/dist/plugins/discovery/DiscoveryPlugin.js.map +1 -0
- package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/MonorepoServiceDiscovery.js +9 -15
- package/dist/plugins/discovery/MonorepoServiceDiscovery.js.map +1 -0
- package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/SimpleProjectDiscovery.js +3 -2
- package/dist/plugins/discovery/SimpleProjectDiscovery.js.map +1 -0
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/WorkspaceDiscovery.js +3 -2
- package/dist/plugins/discovery/WorkspaceDiscovery.js.map +1 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.js +1 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.js.map +1 -0
- package/dist/plugins/discovery/workspaces/detector.js +1 -0
- package/dist/plugins/discovery/workspaces/detector.js.map +1 -0
- package/dist/plugins/discovery/workspaces/globResolver.js +1 -0
- package/dist/plugins/discovery/workspaces/globResolver.js.map +1 -0
- package/dist/plugins/discovery/workspaces/index.js +1 -0
- package/dist/plugins/discovery/workspaces/index.js.map +1 -0
- package/dist/plugins/discovery/workspaces/parsers.js +1 -0
- package/dist/plugins/discovery/workspaces/parsers.js.map +1 -0
- package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
- package/dist/plugins/enrichment/AliasTracker.js +5 -2
- package/dist/plugins/enrichment/AliasTracker.js.map +1 -0
- package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts.map +1 -1
- package/dist/plugins/enrichment/ArgumentParameterLinker.js +4 -2
- package/dist/plugins/enrichment/ArgumentParameterLinker.js.map +1 -0
- package/dist/plugins/enrichment/CallbackCallResolver.d.ts +42 -0
- package/dist/plugins/enrichment/CallbackCallResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/CallbackCallResolver.js +311 -0
- package/dist/plugins/enrichment/CallbackCallResolver.js.map +1 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/ClosureCaptureEnricher.js +4 -2
- package/dist/plugins/enrichment/ClosureCaptureEnricher.js.map +1 -0
- package/dist/plugins/enrichment/ConfigRoutingMapBuilder.d.ts +17 -0
- package/dist/plugins/enrichment/ConfigRoutingMapBuilder.d.ts.map +1 -0
- package/dist/plugins/enrichment/ConfigRoutingMapBuilder.js +55 -0
- package/dist/plugins/enrichment/ConfigRoutingMapBuilder.js.map +1 -0
- package/dist/plugins/enrichment/ExpressHandlerLinker.d.ts +21 -0
- package/dist/plugins/enrichment/ExpressHandlerLinker.d.ts.map +1 -0
- package/dist/plugins/enrichment/ExpressHandlerLinker.js +139 -0
- package/dist/plugins/enrichment/ExpressHandlerLinker.js.map +1 -0
- package/dist/plugins/enrichment/ExternalCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/ExternalCallResolver.js +6 -9
- package/dist/plugins/enrichment/ExternalCallResolver.js.map +1 -0
- package/dist/plugins/enrichment/FunctionCallResolver.d.ts +5 -0
- package/dist/plugins/enrichment/FunctionCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/FunctionCallResolver.js +17 -18
- package/dist/plugins/enrichment/FunctionCallResolver.js.map +1 -0
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts +2 -0
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js +54 -14
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js.map +1 -0
- package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
- package/dist/plugins/enrichment/ImportExportLinker.js +6 -4
- package/dist/plugins/enrichment/ImportExportLinker.js.map +1 -0
- package/dist/plugins/enrichment/InstanceOfResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/InstanceOfResolver.js +5 -2
- package/dist/plugins/enrichment/InstanceOfResolver.js.map +1 -0
- package/dist/plugins/enrichment/MethodCallResolver.d.ts +17 -30
- package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MethodCallResolver.js +117 -181
- package/dist/plugins/enrichment/MethodCallResolver.js.map +1 -0
- package/dist/plugins/enrichment/MountPointResolver.d.ts +1 -1
- package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MountPointResolver.js +16 -25
- package/dist/plugins/enrichment/MountPointResolver.js.map +1 -0
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.js +9 -18
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.js.map +1 -0
- package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -1
- package/dist/plugins/enrichment/PrefixEvaluator.js +11 -6
- package/dist/plugins/enrichment/PrefixEvaluator.js.map +1 -0
- package/dist/plugins/enrichment/RejectionPropagationEnricher.d.ts +30 -0
- package/dist/plugins/enrichment/RejectionPropagationEnricher.d.ts.map +1 -0
- package/dist/plugins/enrichment/RejectionPropagationEnricher.js +192 -0
- package/dist/plugins/enrichment/RejectionPropagationEnricher.js.map +1 -0
- package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/RustFFIEnricher.js +4 -2
- package/dist/plugins/enrichment/RustFFIEnricher.js.map +1 -0
- package/dist/plugins/enrichment/ServiceConnectionEnricher.d.ts +76 -0
- package/dist/plugins/enrichment/ServiceConnectionEnricher.d.ts.map +1 -0
- package/dist/plugins/enrichment/ServiceConnectionEnricher.js +355 -0
- package/dist/plugins/enrichment/ServiceConnectionEnricher.js.map +1 -0
- package/dist/plugins/enrichment/SocketConnectionEnricher.d.ts +42 -0
- package/dist/plugins/enrichment/SocketConnectionEnricher.d.ts.map +1 -0
- package/dist/plugins/enrichment/SocketConnectionEnricher.js +166 -0
- package/dist/plugins/enrichment/SocketConnectionEnricher.js.map +1 -0
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +6 -3
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallData.d.ts +68 -0
- package/dist/plugins/enrichment/method-call/MethodCallData.d.ts.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallData.js +227 -0
- package/dist/plugins/enrichment/method-call/MethodCallData.js.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallDetectors.d.ts +21 -0
- package/dist/plugins/enrichment/method-call/MethodCallDetectors.d.ts.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallDetectors.js +52 -0
- package/dist/plugins/enrichment/method-call/MethodCallDetectors.js.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallErrorAnalysis.d.ts +22 -0
- package/dist/plugins/enrichment/method-call/MethodCallErrorAnalysis.d.ts.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallErrorAnalysis.js +105 -0
- package/dist/plugins/enrichment/method-call/MethodCallErrorAnalysis.js.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallIndexers.d.ts +19 -0
- package/dist/plugins/enrichment/method-call/MethodCallIndexers.d.ts.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallIndexers.js +63 -0
- package/dist/plugins/enrichment/method-call/MethodCallIndexers.js.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallResolution.d.ts +30 -0
- package/dist/plugins/enrichment/method-call/MethodCallResolution.d.ts.map +1 -0
- package/dist/plugins/enrichment/method-call/MethodCallResolution.js +138 -0
- package/dist/plugins/enrichment/method-call/MethodCallResolution.js.map +1 -0
- package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts +3 -1
- package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/IncrementalModuleIndexer.js +24 -37
- package/dist/plugins/indexing/IncrementalModuleIndexer.js.map +1 -0
- package/dist/plugins/indexing/JSModuleIndexer.d.ts +3 -1
- package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/JSModuleIndexer.js +31 -44
- package/dist/plugins/indexing/JSModuleIndexer.js.map +1 -0
- package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.js +14 -12
- package/dist/plugins/indexing/RustModuleIndexer.js.map +1 -0
- package/dist/plugins/validation/AwaitInLoopValidator.d.ts +24 -0
- package/dist/plugins/validation/AwaitInLoopValidator.d.ts.map +1 -0
- package/dist/plugins/validation/AwaitInLoopValidator.js +69 -0
- package/dist/plugins/validation/AwaitInLoopValidator.js.map +1 -0
- package/dist/plugins/validation/BrokenImportValidator.d.ts.map +1 -1
- package/dist/plugins/validation/BrokenImportValidator.js +3 -3
- package/dist/plugins/validation/BrokenImportValidator.js.map +1 -0
- package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
- package/dist/plugins/validation/CallResolverValidator.js +3 -3
- package/dist/plugins/validation/CallResolverValidator.js.map +1 -0
- package/dist/plugins/validation/DataFlowValidator.js +2 -1
- package/dist/plugins/validation/DataFlowValidator.js.map +1 -0
- package/dist/plugins/validation/EvalBanValidator.js +2 -1
- package/dist/plugins/validation/EvalBanValidator.js.map +1 -0
- package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
- package/dist/plugins/validation/GraphConnectivityValidator.js +2 -1
- package/dist/plugins/validation/GraphConnectivityValidator.js.map +1 -0
- package/dist/plugins/validation/PackageCoverageValidator.d.ts +33 -0
- package/dist/plugins/validation/PackageCoverageValidator.d.ts.map +1 -0
- package/dist/plugins/validation/PackageCoverageValidator.js +149 -0
- package/dist/plugins/validation/PackageCoverageValidator.js.map +1 -0
- package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
- package/dist/plugins/validation/SQLInjectionValidator.js +4 -2
- package/dist/plugins/validation/SQLInjectionValidator.js.map +1 -0
- package/dist/plugins/validation/ShadowingDetector.js +2 -1
- package/dist/plugins/validation/ShadowingDetector.js.map +1 -0
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -1
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +3 -3
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.js.map +1 -0
- package/dist/plugins/validation/UnconnectedRouteValidator.d.ts +18 -0
- package/dist/plugins/validation/UnconnectedRouteValidator.d.ts.map +1 -0
- package/dist/plugins/validation/UnconnectedRouteValidator.js +68 -0
- package/dist/plugins/validation/UnconnectedRouteValidator.js.map +1 -0
- package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -1
- package/dist/plugins/vcs/GitPlugin.js +13 -6
- package/dist/plugins/vcs/GitPlugin.js.map +1 -0
- package/dist/plugins/vcs/VCSPlugin.js +1 -0
- package/dist/plugins/vcs/VCSPlugin.js.map +1 -0
- package/dist/plugins/vcs/index.js +1 -0
- package/dist/plugins/vcs/index.js.map +1 -0
- package/dist/queries/NodeContext.d.ts +81 -0
- package/dist/queries/NodeContext.d.ts.map +1 -0
- package/dist/queries/NodeContext.js +193 -0
- package/dist/queries/NodeContext.js.map +1 -0
- package/dist/queries/findCallsInFunction.d.ts +1 -1
- package/dist/queries/findCallsInFunction.d.ts.map +1 -1
- package/dist/queries/findCallsInFunction.js +13 -4
- package/dist/queries/findCallsInFunction.js.map +1 -0
- package/dist/queries/findContainingFunction.d.ts +4 -3
- package/dist/queries/findContainingFunction.d.ts.map +1 -1
- package/dist/queries/findContainingFunction.js +14 -3
- package/dist/queries/findContainingFunction.js.map +1 -0
- package/dist/queries/index.d.ts +2 -0
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/index.js +2 -0
- package/dist/queries/index.js.map +1 -0
- package/dist/queries/traceValues.d.ts.map +1 -1
- package/dist/queries/traceValues.js +1 -0
- package/dist/queries/traceValues.js.map +1 -0
- package/dist/queries/types.js +1 -0
- package/dist/queries/types.js.map +1 -0
- package/dist/resources/InfraResourceMapImpl.d.ts +31 -0
- package/dist/resources/InfraResourceMapImpl.d.ts.map +1 -0
- package/dist/resources/InfraResourceMapImpl.js +110 -0
- package/dist/resources/InfraResourceMapImpl.js.map +1 -0
- package/dist/resources/RoutingMapImpl.d.ts +33 -0
- package/dist/resources/RoutingMapImpl.d.ts.map +1 -0
- package/dist/resources/RoutingMapImpl.js +115 -0
- package/dist/resources/RoutingMapImpl.js.map +1 -0
- package/dist/schema/GraphSchemaExtractor.js +1 -0
- package/dist/schema/GraphSchemaExtractor.js.map +1 -0
- package/dist/schema/InterfaceSchemaExtractor.js +1 -0
- package/dist/schema/InterfaceSchemaExtractor.js.map +1 -0
- package/dist/schema/index.js +1 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts +54 -1
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +143 -33
- package/dist/storage/backends/RFDBServerBackend.js.map +1 -0
- package/dist/storage/backends/typeValidation.d.ts.map +1 -1
- package/dist/storage/backends/typeValidation.js +3 -0
- package/dist/storage/backends/typeValidation.js.map +1 -0
- package/dist/utils/findRfdbBinary.d.ts +3 -2
- package/dist/utils/findRfdbBinary.d.ts.map +1 -1
- package/dist/utils/findRfdbBinary.js +23 -7
- package/dist/utils/findRfdbBinary.js.map +1 -0
- package/dist/utils/moduleResolution.d.ts +134 -0
- package/dist/utils/moduleResolution.d.ts.map +1 -0
- package/dist/utils/moduleResolution.js +189 -0
- package/dist/utils/moduleResolution.js.map +1 -0
- package/dist/utils/resolveNodeFile.d.ts +13 -0
- package/dist/utils/resolveNodeFile.d.ts.map +1 -0
- package/dist/utils/resolveNodeFile.js +18 -0
- package/dist/utils/resolveNodeFile.js.map +1 -0
- package/dist/validation/PathValidator.d.ts.map +1 -1
- package/dist/validation/PathValidator.js +1 -0
- package/dist/validation/PathValidator.js.map +1 -0
- package/dist/version.d.ts +11 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +26 -0
- package/dist/version.js.map +1 -0
- package/package.json +4 -3
- package/src/DiscoveryManager.ts +279 -0
- package/src/GraphInitializer.ts +131 -0
- package/src/GuaranteeChecker.ts +90 -0
- package/src/Orchestrator.ts +299 -714
- package/src/OrchestratorTypes.ts +122 -0
- package/src/ParallelAnalysisRunner.ts +188 -0
- package/src/PhaseRunner.ts +448 -0
- package/src/api/GraphAPI.ts +4 -2
- package/src/api/GuaranteeAPI.ts +3 -2
- package/src/config/ConfigLoader.ts +297 -5
- package/src/config/index.ts +9 -1
- package/src/core/ASTWorker.ts +17 -22
- package/src/core/ASTWorkerPool.ts +1 -1
- package/src/core/CoverageAnalyzer.ts +2 -2
- package/src/core/FileNodeManager.ts +3 -2
- package/src/core/FileOverview.ts +374 -0
- package/src/core/GraphFreshnessChecker.ts +7 -5
- package/src/core/GuaranteeManager.ts +71 -3
- package/src/core/IncrementalReanalyzer.ts +12 -6
- package/src/core/NodeFactory.ts +180 -626
- package/src/core/ResourceRegistry.ts +39 -0
- package/src/core/ScopeTracker.ts +23 -0
- package/src/core/SemanticId.ts +183 -0
- package/src/core/WorkerPool.ts +2 -1
- package/src/core/brandNodeInternal.ts +16 -0
- package/src/core/buildDependencyGraph.ts +98 -0
- package/src/core/factories/CoreFactory.ts +489 -0
- package/src/core/factories/DatabaseFactory.ts +63 -0
- package/src/core/factories/ExternalFactory.ts +23 -0
- package/src/core/factories/HttpFactory.ts +57 -0
- package/src/core/factories/ReactFactory.ts +15 -0
- package/src/core/factories/RustFactory.ts +128 -0
- package/src/core/factories/ServiceFactory.ts +27 -0
- package/src/core/factories/SocketFactory.ts +94 -0
- package/src/core/nodes/DatabaseNode.ts +175 -0
- package/src/core/nodes/ExpressMiddlewareNode.ts +98 -0
- package/src/core/nodes/ExpressMountNode.ts +94 -0
- package/src/core/nodes/ExternalApiNode.ts +53 -0
- package/src/core/nodes/ExternalFunctionNode.ts +77 -0
- package/src/core/nodes/FetchRequestNode.ts +105 -0
- package/src/core/nodes/HttpRouteNode.ts +113 -0
- package/src/core/nodes/NodeKind.ts +12 -0
- package/src/core/nodes/PluginNode.ts +144 -0
- package/src/core/nodes/ReactNode.ts +78 -0
- package/src/core/nodes/RustCallNode.ts +96 -0
- package/src/core/nodes/RustFunctionNode.ts +112 -0
- package/src/core/nodes/RustImplNode.ts +78 -0
- package/src/core/nodes/RustMethodNode.ts +125 -0
- package/src/core/nodes/RustModuleNode.ts +84 -0
- package/src/core/nodes/RustStructNode.ts +80 -0
- package/src/core/nodes/RustTraitNode.ts +82 -0
- package/src/core/nodes/ServiceLayerNode.ts +183 -0
- package/src/core/nodes/SocketIONode.ts +177 -0
- package/src/core/nodes/SocketNode.ts +206 -0
- package/src/core/nodes/TypeNode.ts +47 -4
- package/src/core/nodes/TypeParameterNode.ts +91 -0
- package/src/core/nodes/index.ts +61 -0
- package/src/core/toposort.ts +160 -0
- package/src/diagnostics/DiagnosticCollector.ts +8 -1
- package/src/diagnostics/DiagnosticReporter.ts +87 -16
- package/src/diagnostics/categories.ts +104 -0
- package/src/diagnostics/index.ts +14 -0
- package/src/errors/GrafemaError.ts +58 -0
- package/src/index.ts +113 -13
- package/src/instructions/index.ts +21 -0
- package/src/instructions/onboarding.md +121 -0
- package/src/logging/Logger.ts +155 -4
- package/src/plugins/InfraAnalyzer.ts +208 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +45 -28
- package/src/plugins/analysis/ExpressAnalyzer.ts +74 -49
- package/src/plugins/analysis/ExpressResponseAnalyzer.ts +77 -90
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +94 -79
- package/src/plugins/analysis/FetchAnalyzer.ts +200 -158
- package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +9 -9
- package/src/plugins/analysis/JSASTAnalyzer.ts +969 -2247
- package/src/plugins/analysis/NestJSRouteAnalyzer.ts +241 -0
- package/src/plugins/analysis/ReactAnalyzer.ts +52 -1097
- package/src/plugins/analysis/RustAnalyzer.ts +144 -134
- package/src/plugins/analysis/SQLiteAnalyzer.ts +39 -15
- package/src/plugins/analysis/ServiceLayerAnalyzer.ts +64 -38
- package/src/plugins/analysis/SocketAnalyzer.ts +601 -0
- package/src/plugins/analysis/SocketIOAnalyzer.ts +49 -43
- package/src/plugins/analysis/SystemDbAnalyzer.ts +35 -21
- package/src/plugins/analysis/ast/CollisionResolver.ts +137 -0
- package/src/plugins/analysis/ast/ExpressionEvaluator.ts +1 -3
- package/src/plugins/analysis/ast/FunctionBodyContext.ts +291 -0
- package/src/plugins/analysis/ast/GraphBuilder.ts +275 -2715
- package/src/plugins/analysis/ast/IdGenerator.ts +81 -1
- package/src/plugins/analysis/ast/builders/AssignmentBuilder.ts +407 -0
- package/src/plugins/analysis/ast/builders/CallFlowBuilder.ts +255 -0
- package/src/plugins/analysis/ast/builders/ControlFlowBuilder.ts +470 -0
- package/src/plugins/analysis/ast/builders/CoreBuilder.ts +306 -0
- package/src/plugins/analysis/ast/builders/ModuleRuntimeBuilder.ts +452 -0
- package/src/plugins/analysis/ast/builders/MutationBuilder.ts +372 -0
- package/src/plugins/analysis/ast/builders/ReturnBuilder.ts +279 -0
- package/src/plugins/analysis/ast/builders/TypeSystemBuilder.ts +475 -0
- package/src/plugins/analysis/ast/builders/UpdateExpressionBuilder.ts +262 -0
- package/src/plugins/analysis/ast/builders/YieldBuilder.ts +287 -0
- package/src/plugins/analysis/ast/builders/index.ts +11 -0
- package/src/plugins/analysis/ast/builders/types.ts +65 -0
- package/src/plugins/analysis/ast/handlers/AnalyzerDelegate.ts +183 -0
- package/src/plugins/analysis/ast/handlers/BranchHandler.ts +313 -0
- package/src/plugins/analysis/ast/handlers/CallExpressionHandler.ts +347 -0
- package/src/plugins/analysis/ast/handlers/FunctionBodyHandler.ts +24 -0
- package/src/plugins/analysis/ast/handlers/LoopHandler.ts +240 -0
- package/src/plugins/analysis/ast/handlers/NestedFunctionHandler.ts +201 -0
- package/src/plugins/analysis/ast/handlers/NewExpressionHandler.ts +159 -0
- package/src/plugins/analysis/ast/handlers/PropertyAccessHandler.ts +112 -0
- package/src/plugins/analysis/ast/handlers/ReturnYieldHandler.ts +166 -0
- package/src/plugins/analysis/ast/handlers/ThrowHandler.ts +101 -0
- package/src/plugins/analysis/ast/handlers/TryCatchHandler.ts +262 -0
- package/src/plugins/analysis/ast/handlers/VariableHandler.ts +93 -0
- package/src/plugins/analysis/ast/handlers/index.ts +12 -0
- package/src/plugins/analysis/ast/types.ts +259 -2
- package/src/plugins/analysis/ast/utils/babelTraverse.ts +74 -0
- package/src/plugins/analysis/ast/utils/createParameterNodes.ts +119 -14
- package/src/plugins/analysis/ast/utils/extractNamesFromPattern.ts +166 -0
- package/src/plugins/analysis/ast/utils/getExpressionValue.ts +34 -0
- package/src/plugins/analysis/ast/utils/getMemberExpressionName.ts +33 -0
- package/src/plugins/analysis/ast/utils/index.ts +2 -0
- package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +7 -2
- package/src/plugins/analysis/ast/visitors/ArgumentExtractor.ts +307 -0
- package/src/plugins/analysis/ast/visitors/ArrayElementExtractor.ts +172 -0
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +449 -1250
- package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +285 -8
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +48 -12
- package/src/plugins/analysis/ast/visitors/MutationDetector.ts +211 -0
- package/src/plugins/analysis/ast/visitors/ObjectPropertyExtractor.ts +217 -0
- package/src/plugins/analysis/ast/visitors/PropertyAccessVisitor.ts +407 -0
- package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +234 -16
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +9 -38
- package/src/plugins/analysis/ast/visitors/call-expression-helpers.ts +65 -0
- package/src/plugins/analysis/ast/visitors/call-expression-types.ts +179 -0
- package/src/plugins/analysis/ast/visitors/index.ts +2 -0
- package/src/plugins/analysis/react-internal/browser-api.ts +168 -0
- package/src/plugins/analysis/react-internal/hooks.ts +517 -0
- package/src/plugins/analysis/react-internal/jsx.ts +279 -0
- package/src/plugins/analysis/react-internal/types.ts +183 -0
- package/src/plugins/discovery/DiscoveryPlugin.ts +42 -11
- package/src/plugins/discovery/MonorepoServiceDiscovery.ts +8 -16
- package/src/plugins/discovery/SimpleProjectDiscovery.ts +2 -2
- package/src/plugins/discovery/WorkspaceDiscovery.ts +2 -2
- package/src/plugins/discovery/workspaces/globResolver.ts +1 -1
- package/src/plugins/enrichment/AliasTracker.ts +4 -2
- package/src/plugins/enrichment/ArgumentParameterLinker.ts +3 -2
- package/src/plugins/enrichment/CallbackCallResolver.ts +398 -0
- package/src/plugins/enrichment/ClosureCaptureEnricher.ts +3 -2
- package/src/plugins/enrichment/ConfigRoutingMapBuilder.ts +67 -0
- package/src/plugins/enrichment/ExpressHandlerLinker.ts +180 -0
- package/src/plugins/enrichment/ExternalCallResolver.ts +5 -9
- package/src/plugins/enrichment/FunctionCallResolver.ts +16 -24
- package/src/plugins/enrichment/HTTPConnectionEnricher.ts +68 -15
- package/src/plugins/enrichment/ImportExportLinker.ts +5 -4
- package/src/plugins/enrichment/InstanceOfResolver.ts +4 -2
- package/src/plugins/enrichment/MethodCallResolver.ts +138 -235
- package/src/plugins/enrichment/MountPointResolver.ts +15 -26
- package/src/plugins/enrichment/NodejsBuiltinsResolver.ts +14 -20
- package/src/plugins/enrichment/PrefixEvaluator.ts +10 -6
- package/src/plugins/enrichment/RejectionPropagationEnricher.ts +255 -0
- package/src/plugins/enrichment/RustFFIEnricher.ts +3 -2
- package/src/plugins/enrichment/ServiceConnectionEnricher.ts +472 -0
- package/src/plugins/enrichment/SocketConnectionEnricher.ts +228 -0
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +5 -3
- package/src/plugins/enrichment/method-call/MethodCallData.ts +299 -0
- package/src/plugins/enrichment/method-call/MethodCallDetectors.ts +70 -0
- package/src/plugins/enrichment/method-call/MethodCallErrorAnalysis.ts +131 -0
- package/src/plugins/enrichment/method-call/MethodCallIndexers.ts +83 -0
- package/src/plugins/enrichment/method-call/MethodCallResolution.ts +181 -0
- package/src/plugins/indexing/IncrementalModuleIndexer.ts +29 -40
- package/src/plugins/indexing/JSModuleIndexer.ts +34 -36
- package/src/plugins/indexing/RustModuleIndexer.ts +24 -18
- package/src/plugins/validation/AwaitInLoopValidator.ts +91 -0
- package/src/plugins/validation/BrokenImportValidator.ts +2 -3
- package/src/plugins/validation/CallResolverValidator.ts +2 -3
- package/src/plugins/validation/DataFlowValidator.ts +1 -1
- package/src/plugins/validation/EvalBanValidator.ts +1 -1
- package/src/plugins/validation/GraphConnectivityValidator.ts +1 -9
- package/src/plugins/validation/PackageCoverageValidator.ts +181 -0
- package/src/plugins/validation/SQLInjectionValidator.ts +3 -2
- package/src/plugins/validation/ShadowingDetector.ts +1 -1
- package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +2 -3
- package/src/plugins/validation/UnconnectedRouteValidator.ts +93 -0
- package/src/plugins/vcs/GitPlugin.ts +12 -6
- package/src/queries/NodeContext.ts +277 -0
- package/src/queries/findCallsInFunction.ts +15 -6
- package/src/queries/findContainingFunction.ts +15 -4
- package/src/queries/index.ts +13 -0
- package/src/queries/traceValues.ts +0 -1
- package/src/resources/InfraResourceMapImpl.ts +119 -0
- package/src/resources/RoutingMapImpl.ts +133 -0
- package/src/storage/backends/RFDBServerBackend.ts +157 -38
- package/src/storage/backends/typeValidation.ts +2 -0
- package/src/utils/findRfdbBinary.ts +22 -7
- package/src/utils/moduleResolution.ts +271 -0
- package/src/utils/resolveNodeFile.ts +18 -0
- package/src/validation/PathValidator.ts +0 -8
- package/src/version.ts +28 -0
- package/src/plugins/validation/NodeCreationValidator.ts +0 -554
|
@@ -1,21 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* GraphBuilder -
|
|
2
|
+
* GraphBuilder - orchestrator that delegates to domain-specific builders
|
|
3
3
|
* OPTIMIZED: Uses batched writes to reduce FFI overhead
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
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';
|
|
12
|
-
import { computeSemanticId, parseSemanticId } from '../../../core/SemanticId.js';
|
|
5
|
+
import { brandNodeInternal } from '../../../core/brandNodeInternal.js';
|
|
6
|
+
import { parseSemanticId } from '../../../core/SemanticId.js';
|
|
7
|
+
import { CoreBuilder, ControlFlowBuilder, AssignmentBuilder, CallFlowBuilder, MutationBuilder, UpdateExpressionBuilder, ReturnBuilder, YieldBuilder, TypeSystemBuilder, ModuleRuntimeBuilder, } from './builders/index.js';
|
|
13
8
|
export class GraphBuilder {
|
|
14
9
|
// Track singleton nodes to avoid duplicates (net:stdio, net:request, etc.)
|
|
15
10
|
_createdSingletons = new Set();
|
|
16
11
|
// Batching buffers for optimized writes
|
|
17
12
|
_nodeBuffer = [];
|
|
18
13
|
_edgeBuffer = [];
|
|
14
|
+
// Domain builders
|
|
15
|
+
_coreBuilder;
|
|
16
|
+
_controlFlowBuilder;
|
|
17
|
+
_assignmentBuilder;
|
|
18
|
+
_callFlowBuilder;
|
|
19
|
+
_mutationBuilder;
|
|
20
|
+
_updateExpressionBuilder;
|
|
21
|
+
_returnBuilder;
|
|
22
|
+
_yieldBuilder;
|
|
23
|
+
_typeSystemBuilder;
|
|
24
|
+
_moduleRuntimeBuilder;
|
|
25
|
+
constructor() {
|
|
26
|
+
const ctx = this._createContext();
|
|
27
|
+
this._coreBuilder = new CoreBuilder(ctx);
|
|
28
|
+
this._controlFlowBuilder = new ControlFlowBuilder(ctx);
|
|
29
|
+
this._assignmentBuilder = new AssignmentBuilder(ctx);
|
|
30
|
+
this._callFlowBuilder = new CallFlowBuilder(ctx);
|
|
31
|
+
this._mutationBuilder = new MutationBuilder(ctx);
|
|
32
|
+
this._updateExpressionBuilder = new UpdateExpressionBuilder(ctx);
|
|
33
|
+
this._returnBuilder = new ReturnBuilder(ctx);
|
|
34
|
+
this._yieldBuilder = new YieldBuilder(ctx);
|
|
35
|
+
this._typeSystemBuilder = new TypeSystemBuilder(ctx);
|
|
36
|
+
this._moduleRuntimeBuilder = new ModuleRuntimeBuilder(ctx);
|
|
37
|
+
}
|
|
38
|
+
_createContext() {
|
|
39
|
+
return {
|
|
40
|
+
bufferNode: (node) => this._bufferNode(node),
|
|
41
|
+
bufferEdge: (edge) => this._bufferEdge(edge),
|
|
42
|
+
isCreated: (key) => this._createdSingletons.has(key),
|
|
43
|
+
markCreated: (key) => { this._createdSingletons.add(key); },
|
|
44
|
+
findBufferedNode: (id) => this._nodeBuffer.find(n => n.id === id),
|
|
45
|
+
findFunctionByName: (functions, name, file, callScopeId) => this.findFunctionByName(functions, name, file, callScopeId),
|
|
46
|
+
resolveVariableInScope: (name, scopePath, file, variables) => this.resolveVariableInScope(name, scopePath, file, variables),
|
|
47
|
+
resolveParameterInScope: (name, scopePath, file, parameters) => this.resolveParameterInScope(name, scopePath, file, parameters),
|
|
48
|
+
scopePathsMatch: (a, b) => this.scopePathsMatch(a, b),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
19
51
|
/**
|
|
20
52
|
* Buffer a node for batched writing
|
|
21
53
|
*/
|
|
@@ -33,8 +65,9 @@ export class GraphBuilder {
|
|
|
33
65
|
*/
|
|
34
66
|
async _flushNodes(graph) {
|
|
35
67
|
if (this._nodeBuffer.length > 0) {
|
|
36
|
-
//
|
|
37
|
-
|
|
68
|
+
// Brand nodes before flushing - they're validated by builders
|
|
69
|
+
const brandedNodes = this._nodeBuffer.map(node => brandNodeInternal(node));
|
|
70
|
+
await graph.addNodes(brandedNodes);
|
|
38
71
|
const count = this._nodeBuffer.length;
|
|
39
72
|
this._nodeBuffer = [];
|
|
40
73
|
return count;
|
|
@@ -58,57 +91,53 @@ export class GraphBuilder {
|
|
|
58
91
|
* Создаёт ноды и рёбра в графе (BATCHED VERSION)
|
|
59
92
|
*/
|
|
60
93
|
async build(module, graph, projectPath, data) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
loops = [],
|
|
66
|
-
// Control flow (try/catch/finally) - Phase 4
|
|
67
|
-
tryBlocks = [], catchBlocks = [], finallyBlocks = [], variableDeclarations, callSites, methodCalls = [], eventListeners = [], classInstantiations = [], constructorCalls = [], classDeclarations = [], methodCallbacks = [], callArguments = [], imports = [], exports = [], httpRequests = [], literals = [], variableAssignments = [],
|
|
68
|
-
// TypeScript-specific collections
|
|
69
|
-
interfaces = [], typeAliases = [], enums = [], decorators = [],
|
|
70
|
-
// Array mutation tracking for FLOWS_INTO edges
|
|
71
|
-
arrayMutations = [],
|
|
72
|
-
// Object mutation tracking for FLOWS_INTO edges
|
|
73
|
-
objectMutations = [],
|
|
74
|
-
// Variable reassignment tracking for FLOWS_INTO edges (REG-290)
|
|
75
|
-
variableReassignments = [],
|
|
76
|
-
// Return statement tracking for RETURNS edges
|
|
77
|
-
returnStatements = [],
|
|
78
|
-
// Update expression tracking for MODIFIES edges (REG-288, REG-312)
|
|
79
|
-
updateExpressions = [],
|
|
80
|
-
// Promise resolution tracking for RESOLVES_TO edges (REG-334)
|
|
81
|
-
promiseResolutions = [],
|
|
82
|
-
// Object/Array literal tracking
|
|
83
|
-
objectLiterals = [], objectProperties = [], arrayLiterals = [] } = data;
|
|
94
|
+
// Phase 1 node buffering + post-flush fields only; builders receive `data` directly
|
|
95
|
+
const { functions, parameters = [], scopes, branches = [], cases = [], loops = [], tryBlocks = [], catchBlocks = [], finallyBlocks = [], variableDeclarations, callSites, constructorCalls = [],
|
|
96
|
+
// Post-flush fields
|
|
97
|
+
variableAssignments = [], propertyAccesses = [], hasTopLevelAwait = false } = data;
|
|
84
98
|
// Reset buffers for this build
|
|
85
99
|
this._nodeBuffer = [];
|
|
86
100
|
this._edgeBuffer = [];
|
|
87
101
|
// 1. Buffer all functions (without edges)
|
|
102
|
+
// REG-401: Strip invokesParamIndexes from node data and store in metadata
|
|
88
103
|
for (const func of functions) {
|
|
89
|
-
const { parentScopeId, ...funcData } = func;
|
|
90
|
-
|
|
104
|
+
const { parentScopeId: _parentScopeId, invokesParamIndexes: _invokesParamIndexes, invokesParamBindings: _invokesParamBindings, ...funcData } = func;
|
|
105
|
+
const node = funcData;
|
|
106
|
+
if (_invokesParamIndexes && _invokesParamIndexes.length > 0) {
|
|
107
|
+
if (!node.metadata) {
|
|
108
|
+
node.metadata = {};
|
|
109
|
+
}
|
|
110
|
+
node.metadata.invokesParamIndexes = _invokesParamIndexes;
|
|
111
|
+
}
|
|
112
|
+
// REG-417: Store property paths for destructured param bindings
|
|
113
|
+
if (_invokesParamBindings && _invokesParamBindings.length > 0) {
|
|
114
|
+
if (!node.metadata) {
|
|
115
|
+
node.metadata = {};
|
|
116
|
+
}
|
|
117
|
+
node.metadata.invokesParamBindings = _invokesParamBindings;
|
|
118
|
+
}
|
|
119
|
+
this._bufferNode(node);
|
|
91
120
|
}
|
|
92
121
|
// 2. Buffer all SCOPE (without edges)
|
|
93
122
|
for (const scope of scopes) {
|
|
94
|
-
const { parentFunctionId, parentScopeId, capturesFrom
|
|
123
|
+
const { parentFunctionId: _parentFunctionId, parentScopeId: _parentScopeId, capturesFrom: _capturesFrom, ...scopeData } = scope;
|
|
95
124
|
this._bufferNode(scopeData);
|
|
96
125
|
}
|
|
97
126
|
// 2.5. Buffer BRANCH nodes
|
|
98
127
|
// Note: parentScopeId is kept on node for query support (REG-275 test requirement)
|
|
99
128
|
for (const branch of branches) {
|
|
100
|
-
const { discriminantExpressionId, discriminantExpressionType, discriminantLine, discriminantColumn, ...branchData } = branch;
|
|
129
|
+
const { discriminantExpressionId: _discriminantExpressionId, discriminantExpressionType: _discriminantExpressionType, discriminantLine: _discriminantLine, discriminantColumn: _discriminantColumn, ...branchData } = branch;
|
|
101
130
|
this._bufferNode(branchData);
|
|
102
131
|
}
|
|
103
132
|
// 2.6. Buffer CASE nodes
|
|
104
133
|
for (const caseInfo of cases) {
|
|
105
|
-
const { parentBranchId, ...caseData } = caseInfo;
|
|
134
|
+
const { parentBranchId: _parentBranchId, ...caseData } = caseInfo;
|
|
106
135
|
this._bufferNode(caseData);
|
|
107
136
|
}
|
|
108
137
|
// 2.7. Buffer LOOP nodes
|
|
109
138
|
for (const loop of loops) {
|
|
110
139
|
// Exclude metadata used for edge creation (not stored on node)
|
|
111
|
-
const { iteratesOverName, iteratesOverLine, iteratesOverColumn, conditionExpressionId, conditionExpressionType, conditionLine, conditionColumn, ...loopData } = loop;
|
|
140
|
+
const { iteratesOverName: _iteratesOverName, iteratesOverLine: _iteratesOverLine, iteratesOverColumn: _iteratesOverColumn, conditionExpressionId: _conditionExpressionId, conditionExpressionType: _conditionExpressionType, conditionLine: _conditionLine, conditionColumn: _conditionColumn, ...loopData } = loop;
|
|
112
141
|
this._bufferNode(loopData);
|
|
113
142
|
}
|
|
114
143
|
// 2.8. Buffer TRY_BLOCK nodes (Phase 4)
|
|
@@ -117,12 +146,12 @@ export class GraphBuilder {
|
|
|
117
146
|
}
|
|
118
147
|
// 2.9. Buffer CATCH_BLOCK nodes (Phase 4)
|
|
119
148
|
for (const catchBlock of catchBlocks) {
|
|
120
|
-
const { parentTryBlockId, ...catchData } = catchBlock;
|
|
149
|
+
const { parentTryBlockId: _parentTryBlockId, ...catchData } = catchBlock;
|
|
121
150
|
this._bufferNode(catchData);
|
|
122
151
|
}
|
|
123
152
|
// 2.10. Buffer FINALLY_BLOCK nodes (Phase 4)
|
|
124
153
|
for (const finallyBlock of finallyBlocks) {
|
|
125
|
-
const { parentTryBlockId, ...finallyData } = finallyBlock;
|
|
154
|
+
const { parentTryBlockId: _parentTryBlockId2, ...finallyData } = finallyBlock;
|
|
126
155
|
this._bufferNode(finallyData);
|
|
127
156
|
}
|
|
128
157
|
// 3. Buffer variables (keep parentScopeId on node for queries)
|
|
@@ -131,7 +160,7 @@ export class GraphBuilder {
|
|
|
131
160
|
}
|
|
132
161
|
// 3.5. Buffer PARAMETER nodes and HAS_PARAMETER edges
|
|
133
162
|
for (const param of parameters) {
|
|
134
|
-
const { functionId, ...paramData } = param;
|
|
163
|
+
const { functionId: _functionId, ...paramData } = param;
|
|
135
164
|
// Keep parentFunctionId on the node for queries
|
|
136
165
|
this._bufferNode(paramData);
|
|
137
166
|
if (param.parentFunctionId) {
|
|
@@ -145,7 +174,7 @@ export class GraphBuilder {
|
|
|
145
174
|
}
|
|
146
175
|
// 4. Buffer CALL_SITE (keep parentScopeId on node for queries)
|
|
147
176
|
for (const callSite of callSites) {
|
|
148
|
-
const { targetFunctionName, ...callData } = callSite;
|
|
177
|
+
const { targetFunctionName: _targetFunctionName, ...callData } = callSite;
|
|
149
178
|
this._bufferNode(callData);
|
|
150
179
|
}
|
|
151
180
|
// 4.5 Buffer CONSTRUCTOR_CALL nodes
|
|
@@ -161,1453 +190,54 @@ export class GraphBuilder {
|
|
|
161
190
|
column: constructorCall.column
|
|
162
191
|
});
|
|
163
192
|
}
|
|
164
|
-
//
|
|
165
|
-
this.
|
|
166
|
-
|
|
167
|
-
this.
|
|
168
|
-
|
|
169
|
-
this.
|
|
170
|
-
|
|
171
|
-
this.
|
|
172
|
-
|
|
173
|
-
this.
|
|
174
|
-
|
|
175
|
-
// Phase 3 (REG-267): Now includes scopes for if-branches HAS_CONSEQUENT/HAS_ALTERNATE
|
|
176
|
-
this.bufferBranchEdges(branches, callSites, scopes);
|
|
177
|
-
// 6.6. Buffer edges for CASE
|
|
178
|
-
this.bufferCaseEdges(cases);
|
|
179
|
-
// 6.65. Buffer edges for TRY_BLOCK, CATCH_BLOCK, FINALLY_BLOCK (Phase 4)
|
|
180
|
-
this.bufferTryCatchFinallyEdges(tryBlocks, catchBlocks, finallyBlocks);
|
|
181
|
-
// 6.7. Buffer EXPRESSION nodes for switch discriminants (needs callSites for CallExpression)
|
|
182
|
-
this.bufferDiscriminantExpressions(branches, callSites);
|
|
183
|
-
// 7. Buffer edges for variables
|
|
184
|
-
this.bufferVariableEdges(variableDeclarations);
|
|
185
|
-
// 8. Buffer edges for CALL_SITE
|
|
186
|
-
this.bufferCallSiteEdges(callSites, functions);
|
|
187
|
-
// 9. Buffer METHOD_CALL nodes, CONTAINS edges, and USES edges (REG-262)
|
|
188
|
-
this.bufferMethodCalls(methodCalls, variableDeclarations, parameters);
|
|
189
|
-
// 10. Buffer net:stdio and WRITES_TO edges for console.log/error
|
|
190
|
-
this.bufferStdioNodes(methodCalls);
|
|
191
|
-
// 11. Buffer CLASS nodes for class declarations and CONTAINS edges
|
|
192
|
-
this.bufferClassDeclarationNodes(classDeclarations);
|
|
193
|
-
// 12. Buffer CLASS nodes and INSTANCE_OF edges for NewExpression
|
|
194
|
-
this.bufferClassNodes(module, classInstantiations, classDeclarations);
|
|
195
|
-
// 13. Buffer PASSES_ARGUMENT edges (METHOD_CALL -> FUNCTION)
|
|
196
|
-
this.bufferCallbackEdges(methodCallbacks, functions);
|
|
197
|
-
// 14. Buffer IMPORT nodes
|
|
198
|
-
this.bufferImportNodes(module, imports);
|
|
199
|
-
// 15. Buffer EXPORT nodes
|
|
200
|
-
this.bufferExportNodes(module, exports);
|
|
201
|
-
// 16. Buffer EVENT_LISTENER nodes and HANDLED_BY edges
|
|
202
|
-
this.bufferEventListeners(eventListeners, functions);
|
|
203
|
-
// 17. Buffer HTTP requests
|
|
204
|
-
this.bufferHttpRequests(httpRequests, functions);
|
|
205
|
-
// 18. Buffer LITERAL nodes
|
|
206
|
-
this.bufferLiterals(literals);
|
|
207
|
-
// 18.5. Buffer OBJECT_LITERAL nodes (moved before bufferArgumentEdges)
|
|
208
|
-
this.bufferObjectLiteralNodes(objectLiterals);
|
|
209
|
-
// 18.6. Buffer ARRAY_LITERAL nodes (moved before bufferArgumentEdges)
|
|
210
|
-
this.bufferArrayLiteralNodes(arrayLiterals);
|
|
211
|
-
// 18.7. Buffer HAS_PROPERTY edges (OBJECT_LITERAL -> property values)
|
|
212
|
-
// REG-329: Pass variableDeclarations and parameters for scope-aware variable resolution
|
|
213
|
-
this.bufferObjectPropertyEdges(objectProperties, variableDeclarations, parameters);
|
|
214
|
-
// 19. Buffer ASSIGNED_FROM edges for data flow (some need to create EXPRESSION nodes)
|
|
215
|
-
this.bufferAssignmentEdges(variableAssignments, variableDeclarations, callSites, methodCalls, functions, classInstantiations, parameters);
|
|
216
|
-
// 20. Buffer PASSES_ARGUMENT edges (CALL -> argument)
|
|
217
|
-
this.bufferArgumentEdges(callArguments, variableDeclarations, functions, callSites, methodCalls);
|
|
218
|
-
// 21. Buffer INTERFACE nodes and EXTENDS edges
|
|
219
|
-
this.bufferInterfaceNodes(module, interfaces);
|
|
220
|
-
// 22. Buffer TYPE nodes
|
|
221
|
-
this.bufferTypeAliasNodes(module, typeAliases);
|
|
222
|
-
// 23. Buffer ENUM nodes
|
|
223
|
-
this.bufferEnumNodes(module, enums);
|
|
224
|
-
// 24. Buffer DECORATOR nodes and DECORATED_BY edges
|
|
225
|
-
this.bufferDecoratorNodes(decorators);
|
|
226
|
-
// 25. Buffer IMPLEMENTS edges (CLASS -> INTERFACE)
|
|
227
|
-
this.bufferImplementsEdges(classDeclarations, interfaces);
|
|
228
|
-
// 26. Buffer FLOWS_INTO edges for array mutations (push, unshift, splice, indexed assignment)
|
|
229
|
-
this.bufferArrayMutationEdges(arrayMutations, variableDeclarations, parameters);
|
|
230
|
-
// 27. Buffer FLOWS_INTO edges for object mutations (property assignment, Object.assign)
|
|
231
|
-
// REG-152: Now includes classDeclarations for this.prop = value patterns
|
|
232
|
-
this.bufferObjectMutationEdges(objectMutations, variableDeclarations, parameters, functions, classDeclarations);
|
|
233
|
-
// 28. Buffer FLOWS_INTO edges for variable reassignments (REG-290)
|
|
234
|
-
this.bufferVariableReassignmentEdges(variableReassignments, variableDeclarations, callSites, methodCalls, parameters);
|
|
235
|
-
// 29. Buffer RETURNS edges for return statements
|
|
236
|
-
this.bufferReturnEdges(returnStatements, callSites, methodCalls, variableDeclarations, parameters);
|
|
237
|
-
// 30. Buffer UPDATE_EXPRESSION nodes and MODIFIES edges (REG-288, REG-312)
|
|
238
|
-
this.bufferUpdateExpressionEdges(updateExpressions, variableDeclarations, parameters, classDeclarations);
|
|
239
|
-
// 31. Buffer RESOLVES_TO edges for Promise data flow (REG-334)
|
|
240
|
-
this.bufferPromiseResolutionEdges(promiseResolutions);
|
|
193
|
+
// Phase 2: Delegate to domain builders
|
|
194
|
+
this._coreBuilder.buffer(module, data);
|
|
195
|
+
this._controlFlowBuilder.buffer(module, data);
|
|
196
|
+
this._callFlowBuilder.buffer(module, data);
|
|
197
|
+
this._assignmentBuilder.buffer(module, data);
|
|
198
|
+
this._mutationBuilder.buffer(module, data);
|
|
199
|
+
this._updateExpressionBuilder.buffer(module, data);
|
|
200
|
+
this._returnBuilder.buffer(module, data);
|
|
201
|
+
this._yieldBuilder.buffer(module, data);
|
|
202
|
+
this._typeSystemBuilder.buffer(module, data);
|
|
203
|
+
this._moduleRuntimeBuilder.buffer(module, data);
|
|
241
204
|
// FLUSH: Write all nodes first, then edges in single batch calls
|
|
242
205
|
const nodesCreated = await this._flushNodes(graph);
|
|
243
206
|
const edgesCreated = await this._flushEdges(graph);
|
|
244
207
|
// Handle async operations for ASSIGNED_FROM with CLASS lookups
|
|
245
208
|
const classAssignmentEdges = await this.createClassAssignmentEdges(variableAssignments, graph);
|
|
209
|
+
// REG-300: Update MODULE node with import.meta metadata
|
|
210
|
+
const importMetaProps = this.collectImportMetaProperties(propertyAccesses);
|
|
211
|
+
await this.updateModuleImportMetaMetadata(module, graph, importMetaProps);
|
|
212
|
+
// REG-297: Update MODULE node with hasTopLevelAwait metadata
|
|
213
|
+
await this.updateModuleTopLevelAwaitMetadata(module, graph, hasTopLevelAwait);
|
|
246
214
|
return { nodes: nodesCreated, edges: edgesCreated + classAssignmentEdges };
|
|
247
215
|
}
|
|
248
|
-
// =============
|
|
249
|
-
bufferFunctionEdges(module, functions) {
|
|
250
|
-
for (const func of functions) {
|
|
251
|
-
const { parentScopeId, ...funcData } = func;
|
|
252
|
-
// MODULE -> CONTAINS -> FUNCTION (для функций верхнего уровня)
|
|
253
|
-
// или SCOPE -> CONTAINS -> FUNCTION (для вложенных функций)
|
|
254
|
-
if (parentScopeId) {
|
|
255
|
-
this._bufferEdge({
|
|
256
|
-
type: 'CONTAINS',
|
|
257
|
-
src: parentScopeId,
|
|
258
|
-
dst: funcData.id
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
this._bufferEdge({
|
|
263
|
-
type: 'CONTAINS',
|
|
264
|
-
src: module.id,
|
|
265
|
-
dst: funcData.id
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
bufferScopeEdges(scopes, variableDeclarations) {
|
|
271
|
-
for (const scope of scopes) {
|
|
272
|
-
const { parentFunctionId, parentScopeId, capturesFrom, modifies, ...scopeData } = scope;
|
|
273
|
-
// FUNCTION -> HAS_SCOPE -> SCOPE (для function_body)
|
|
274
|
-
if (parentFunctionId) {
|
|
275
|
-
this._bufferEdge({
|
|
276
|
-
type: 'HAS_SCOPE',
|
|
277
|
-
src: parentFunctionId,
|
|
278
|
-
dst: scopeData.id
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
// SCOPE -> CONTAINS -> SCOPE (для вложенных scope, типа if внутри function)
|
|
282
|
-
if (parentScopeId) {
|
|
283
|
-
this._bufferEdge({
|
|
284
|
-
type: 'CONTAINS',
|
|
285
|
-
src: parentScopeId,
|
|
286
|
-
dst: scopeData.id
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
// CAPTURES - замыкания захватывают переменные из родительского scope
|
|
290
|
-
if (capturesFrom && scopeData.scopeType === 'closure') {
|
|
291
|
-
const parentVars = variableDeclarations.filter(v => v.parentScopeId === capturesFrom);
|
|
292
|
-
for (const parentVar of parentVars) {
|
|
293
|
-
this._bufferEdge({
|
|
294
|
-
type: 'CAPTURES',
|
|
295
|
-
src: scopeData.id,
|
|
296
|
-
dst: parentVar.id
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
// MODIFIES - scope модифицирует переменные (count++)
|
|
301
|
-
if (modifies && modifies.length > 0) {
|
|
302
|
-
for (const mod of modifies) {
|
|
303
|
-
this._bufferEdge({
|
|
304
|
-
type: 'MODIFIES',
|
|
305
|
-
src: scopeData.id,
|
|
306
|
-
dst: mod.variableId
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
216
|
+
// ============= SHARED UTILITY METHODS =============
|
|
312
217
|
/**
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* - Parent -> CONTAINS -> LOOP
|
|
317
|
-
* - LOOP -> HAS_BODY -> body SCOPE
|
|
318
|
-
* - LOOP -> ITERATES_OVER -> collection VARIABLE/PARAMETER (for for-in/for-of)
|
|
319
|
-
*
|
|
320
|
-
* Scope-aware variable lookup for ITERATES_OVER:
|
|
321
|
-
* For for-of/for-in, finds the iterated variable preferring:
|
|
322
|
-
* 1. Variables declared before the loop on same or earlier line (closest first)
|
|
323
|
-
* 2. Parameters (function arguments)
|
|
218
|
+
* Scope-aware function lookup: when multiple functions share the same name
|
|
219
|
+
* (e.g., inner function shadows outer), prefer the one in the same scope.
|
|
220
|
+
* Falls back to module-level function if no scope match found.
|
|
324
221
|
*/
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
// LOOP -> HAS_BODY -> body SCOPE
|
|
336
|
-
// Find the body scope by matching parentScopeId to loop.id
|
|
337
|
-
const bodyScope = scopes.find(s => s.parentScopeId === loop.id);
|
|
338
|
-
if (bodyScope) {
|
|
339
|
-
this._bufferEdge({
|
|
340
|
-
type: 'HAS_BODY',
|
|
341
|
-
src: loop.id,
|
|
342
|
-
dst: bodyScope.id
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
// LOOP -> ITERATES_OVER -> collection VARIABLE/PARAMETER (for for-in/for-of)
|
|
346
|
-
if (loop.iteratesOverName && (loop.loopType === 'for-in' || loop.loopType === 'for-of')) {
|
|
347
|
-
// For MemberExpression iterables (obj.items), extract base object
|
|
348
|
-
const iterableName = loop.iteratesOverName.includes('.')
|
|
349
|
-
? loop.iteratesOverName.split('.')[0]
|
|
350
|
-
: loop.iteratesOverName;
|
|
351
|
-
// Scope-aware lookup: prefer parameters over variables
|
|
352
|
-
// Parameters are function-local and shadow outer variables
|
|
353
|
-
const param = parameters.find(p => p.name === iterableName && p.file === loop.file);
|
|
354
|
-
// Determine iteration type: for-in iterates keys, for-of iterates values
|
|
355
|
-
const iterates = loop.loopType === 'for-in' ? 'keys' : 'values';
|
|
356
|
-
if (param) {
|
|
357
|
-
// Parameter found - most local binding
|
|
358
|
-
this._bufferEdge({
|
|
359
|
-
type: 'ITERATES_OVER',
|
|
360
|
-
src: loop.id,
|
|
361
|
-
dst: param.id,
|
|
362
|
-
metadata: { iterates }
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
// Find variable by name and line proximity (scope-aware heuristic)
|
|
367
|
-
// Prefer variables declared before the loop in the same file
|
|
368
|
-
const candidateVars = variableDeclarations.filter(v => v.name === iterableName &&
|
|
369
|
-
v.file === loop.file &&
|
|
370
|
-
(v.line ?? 0) <= loop.line // Declared before or on loop line
|
|
371
|
-
);
|
|
372
|
-
// Sort by line descending to find closest declaration
|
|
373
|
-
candidateVars.sort((a, b) => (b.line ?? 0) - (a.line ?? 0));
|
|
374
|
-
if (candidateVars.length > 0) {
|
|
375
|
-
this._bufferEdge({
|
|
376
|
-
type: 'ITERATES_OVER',
|
|
377
|
-
src: loop.id,
|
|
378
|
-
dst: candidateVars[0].id,
|
|
379
|
-
metadata: { iterates }
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
// REG-282: LOOP (for) -> HAS_INIT -> VARIABLE (let i = 0)
|
|
385
|
-
if (loop.loopType === 'for' && loop.initVariableName && loop.initLine) {
|
|
386
|
-
// Find the variable declared in the init on this line
|
|
387
|
-
const initVar = variableDeclarations.find(v => v.name === loop.initVariableName &&
|
|
388
|
-
v.file === loop.file &&
|
|
389
|
-
v.line === loop.initLine);
|
|
390
|
-
if (initVar) {
|
|
391
|
-
this._bufferEdge({
|
|
392
|
-
type: 'HAS_INIT',
|
|
393
|
-
src: loop.id,
|
|
394
|
-
dst: initVar.id
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
// REG-282: LOOP -> HAS_CONDITION -> EXPRESSION (i < 10 or condition for while/do-while)
|
|
399
|
-
if (loop.testExpressionId && loop.testExpressionType) {
|
|
400
|
-
// Create EXPRESSION node for the test
|
|
401
|
-
this._bufferNode({
|
|
402
|
-
id: loop.testExpressionId,
|
|
403
|
-
type: 'EXPRESSION',
|
|
404
|
-
name: loop.testExpressionType,
|
|
405
|
-
file: loop.file,
|
|
406
|
-
line: loop.testLine,
|
|
407
|
-
column: loop.testColumn,
|
|
408
|
-
expressionType: loop.testExpressionType
|
|
409
|
-
});
|
|
410
|
-
this._bufferEdge({
|
|
411
|
-
type: 'HAS_CONDITION',
|
|
412
|
-
src: loop.id,
|
|
413
|
-
dst: loop.testExpressionId
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
// REG-282: LOOP (for) -> HAS_UPDATE -> EXPRESSION (i++)
|
|
417
|
-
if (loop.loopType === 'for' && loop.updateExpressionId && loop.updateExpressionType) {
|
|
418
|
-
// Create EXPRESSION node for the update
|
|
419
|
-
this._bufferNode({
|
|
420
|
-
id: loop.updateExpressionId,
|
|
421
|
-
type: 'EXPRESSION',
|
|
422
|
-
name: loop.updateExpressionType,
|
|
423
|
-
file: loop.file,
|
|
424
|
-
line: loop.updateLine,
|
|
425
|
-
column: loop.updateColumn,
|
|
426
|
-
expressionType: loop.updateExpressionType
|
|
427
|
-
});
|
|
428
|
-
this._bufferEdge({
|
|
429
|
-
type: 'HAS_UPDATE',
|
|
430
|
-
src: loop.id,
|
|
431
|
-
dst: loop.updateExpressionId
|
|
432
|
-
});
|
|
433
|
-
}
|
|
222
|
+
findFunctionByName(functions, name, file, callScopeId) {
|
|
223
|
+
if (!name)
|
|
224
|
+
return undefined;
|
|
225
|
+
// Find all functions with matching name in the same file
|
|
226
|
+
const candidates = functions.filter(f => f.name === name && f.file === file);
|
|
227
|
+
if (candidates.length === 0) {
|
|
228
|
+
// Fallback: try without file constraint (legacy behavior)
|
|
229
|
+
return functions.find(f => f.name === name);
|
|
434
230
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
* Buffer HAS_CONDITION edges from LOOP to condition EXPRESSION/CALL nodes.
|
|
438
|
-
* Also creates EXPRESSION nodes for non-CallExpression conditions.
|
|
439
|
-
*
|
|
440
|
-
* REG-280: For while/do-while/for loops, creates HAS_CONDITION edge to the
|
|
441
|
-
* condition expression. For-in/for-of loops don't have conditions (use ITERATES_OVER).
|
|
442
|
-
*
|
|
443
|
-
* For CallExpression conditions, links to existing CALL_SITE node by coordinates.
|
|
444
|
-
*/
|
|
445
|
-
bufferLoopConditionEdges(loops, callSites) {
|
|
446
|
-
for (const loop of loops) {
|
|
447
|
-
// Skip for-in/for-of loops - they don't have test expressions
|
|
448
|
-
if (loop.loopType === 'for-in' || loop.loopType === 'for-of') {
|
|
449
|
-
continue;
|
|
450
|
-
}
|
|
451
|
-
// Skip if no condition (e.g., infinite for loop: for(;;))
|
|
452
|
-
if (!loop.conditionExpressionId) {
|
|
453
|
-
continue;
|
|
454
|
-
}
|
|
455
|
-
// LOOP -> HAS_CONDITION -> EXPRESSION/CALL
|
|
456
|
-
let targetId = loop.conditionExpressionId;
|
|
457
|
-
// For CallExpression conditions, look up the actual CALL_SITE by coordinates
|
|
458
|
-
// because CALL_SITE uses semantic IDs that don't match the generated ID
|
|
459
|
-
if (loop.conditionExpressionType === 'CallExpression' && loop.conditionLine && loop.conditionColumn !== undefined) {
|
|
460
|
-
const callSite = callSites.find(cs => cs.file === loop.file &&
|
|
461
|
-
cs.line === loop.conditionLine &&
|
|
462
|
-
cs.column === loop.conditionColumn);
|
|
463
|
-
if (callSite) {
|
|
464
|
-
targetId = callSite.id;
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
this._bufferEdge({
|
|
468
|
-
type: 'HAS_CONDITION',
|
|
469
|
-
src: loop.id,
|
|
470
|
-
dst: targetId
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
/**
|
|
475
|
-
* Buffer EXPRESSION nodes for loop condition expressions (non-CallExpression).
|
|
476
|
-
* Similar to bufferDiscriminantExpressions but for loops.
|
|
477
|
-
*
|
|
478
|
-
* REG-280: Creates EXPRESSION nodes for while/do-while/for loop conditions.
|
|
479
|
-
* CallExpression conditions use existing CALL_SITE nodes (no EXPRESSION created).
|
|
480
|
-
*/
|
|
481
|
-
bufferLoopConditionExpressions(loops) {
|
|
482
|
-
for (const loop of loops) {
|
|
483
|
-
// Skip for-in/for-of loops - they don't have test expressions
|
|
484
|
-
if (loop.loopType === 'for-in' || loop.loopType === 'for-of') {
|
|
485
|
-
continue;
|
|
486
|
-
}
|
|
487
|
-
if (loop.conditionExpressionId && loop.conditionExpressionType) {
|
|
488
|
-
// Skip CallExpression - we link to existing CALL_SITE in bufferLoopConditionEdges
|
|
489
|
-
if (loop.conditionExpressionType === 'CallExpression') {
|
|
490
|
-
continue;
|
|
491
|
-
}
|
|
492
|
-
// Only create if it looks like an EXPRESSION ID
|
|
493
|
-
if (loop.conditionExpressionId.includes(':EXPRESSION:')) {
|
|
494
|
-
this._bufferNode({
|
|
495
|
-
id: loop.conditionExpressionId,
|
|
496
|
-
type: 'EXPRESSION',
|
|
497
|
-
name: loop.conditionExpressionType,
|
|
498
|
-
file: loop.file,
|
|
499
|
-
line: loop.conditionLine,
|
|
500
|
-
column: loop.conditionColumn,
|
|
501
|
-
expressionType: loop.conditionExpressionType
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* Buffer BRANCH edges (CONTAINS, HAS_CONDITION, HAS_CONSEQUENT, HAS_ALTERNATE)
|
|
509
|
-
*
|
|
510
|
-
* REG-275: For CallExpression discriminants (switch(getType())), looks up the
|
|
511
|
-
* actual CALL_SITE node by coordinates since the CALL_SITE uses semantic IDs.
|
|
512
|
-
*
|
|
513
|
-
* Phase 3 (REG-267): For if-branches, creates HAS_CONSEQUENT and HAS_ALTERNATE edges
|
|
514
|
-
* pointing to the if-body and else-body SCOPEs.
|
|
515
|
-
*/
|
|
516
|
-
bufferBranchEdges(branches, callSites, scopes) {
|
|
517
|
-
for (const branch of branches) {
|
|
518
|
-
// Parent SCOPE -> CONTAINS -> BRANCH
|
|
519
|
-
if (branch.parentScopeId) {
|
|
520
|
-
this._bufferEdge({
|
|
521
|
-
type: 'CONTAINS',
|
|
522
|
-
src: branch.parentScopeId,
|
|
523
|
-
dst: branch.id
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
// BRANCH -> HAS_CONDITION -> EXPRESSION/CALL (discriminant)
|
|
527
|
-
if (branch.discriminantExpressionId) {
|
|
528
|
-
let targetId = branch.discriminantExpressionId;
|
|
529
|
-
// For CallExpression discriminants, look up the actual CALL_SITE by coordinates
|
|
530
|
-
// because CALL_SITE uses semantic IDs that don't match the generated ID
|
|
531
|
-
if (branch.discriminantExpressionType === 'CallExpression' && branch.discriminantLine && branch.discriminantColumn !== undefined) {
|
|
532
|
-
const callSite = callSites.find(cs => cs.file === branch.file &&
|
|
533
|
-
cs.line === branch.discriminantLine &&
|
|
534
|
-
cs.column === branch.discriminantColumn);
|
|
535
|
-
if (callSite) {
|
|
536
|
-
targetId = callSite.id;
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
this._bufferEdge({
|
|
540
|
-
type: 'HAS_CONDITION',
|
|
541
|
-
src: branch.id,
|
|
542
|
-
dst: targetId
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
// Phase 3: For if-branches, create HAS_CONSEQUENT and HAS_ALTERNATE edges
|
|
546
|
-
if (branch.branchType === 'if') {
|
|
547
|
-
// Find consequent (if-body) scope - parentScopeId matches branch.id, scopeType is 'if_statement'
|
|
548
|
-
const consequentScope = scopes.find(s => s.parentScopeId === branch.id && s.scopeType === 'if_statement');
|
|
549
|
-
if (consequentScope) {
|
|
550
|
-
this._bufferEdge({
|
|
551
|
-
type: 'HAS_CONSEQUENT',
|
|
552
|
-
src: branch.id,
|
|
553
|
-
dst: consequentScope.id
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
// Find alternate (else-body) scope - parentScopeId matches branch.id, scopeType is 'else_statement'
|
|
557
|
-
const alternateScope = scopes.find(s => s.parentScopeId === branch.id && s.scopeType === 'else_statement');
|
|
558
|
-
if (alternateScope) {
|
|
559
|
-
this._bufferEdge({
|
|
560
|
-
type: 'HAS_ALTERNATE',
|
|
561
|
-
src: branch.id,
|
|
562
|
-
dst: alternateScope.id
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
// For else-if chains: if this branch is the alternate of another branch
|
|
566
|
-
// This is handled differently - see below
|
|
567
|
-
}
|
|
568
|
-
// REG-287: For ternary branches, create HAS_CONSEQUENT and HAS_ALTERNATE edges to expressions
|
|
569
|
-
if (branch.branchType === 'ternary') {
|
|
570
|
-
if (branch.consequentExpressionId) {
|
|
571
|
-
this._bufferEdge({
|
|
572
|
-
type: 'HAS_CONSEQUENT',
|
|
573
|
-
src: branch.id,
|
|
574
|
-
dst: branch.consequentExpressionId
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
if (branch.alternateExpressionId) {
|
|
578
|
-
this._bufferEdge({
|
|
579
|
-
type: 'HAS_ALTERNATE',
|
|
580
|
-
src: branch.id,
|
|
581
|
-
dst: branch.alternateExpressionId
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
// Phase 3: For else-if chains, create HAS_ALTERNATE from parent branch to this branch
|
|
586
|
-
if (branch.isAlternateOfBranchId) {
|
|
587
|
-
this._bufferEdge({
|
|
588
|
-
type: 'HAS_ALTERNATE',
|
|
589
|
-
src: branch.isAlternateOfBranchId,
|
|
590
|
-
dst: branch.id
|
|
591
|
-
});
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* Buffer CASE edges (HAS_CASE, HAS_DEFAULT)
|
|
597
|
-
*/
|
|
598
|
-
bufferCaseEdges(cases) {
|
|
599
|
-
for (const caseInfo of cases) {
|
|
600
|
-
// BRANCH -> HAS_CASE or HAS_DEFAULT -> CASE
|
|
601
|
-
const edgeType = caseInfo.isDefault ? 'HAS_DEFAULT' : 'HAS_CASE';
|
|
602
|
-
this._bufferEdge({
|
|
603
|
-
type: edgeType,
|
|
604
|
-
src: caseInfo.parentBranchId,
|
|
605
|
-
dst: caseInfo.id
|
|
606
|
-
});
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
/**
|
|
610
|
-
* Buffer edges for TRY_BLOCK, CATCH_BLOCK, FINALLY_BLOCK nodes (Phase 4)
|
|
611
|
-
*
|
|
612
|
-
* Creates edges for:
|
|
613
|
-
* - Parent -> CONTAINS -> TRY_BLOCK
|
|
614
|
-
* - TRY_BLOCK -> HAS_CATCH -> CATCH_BLOCK
|
|
615
|
-
* - TRY_BLOCK -> HAS_FINALLY -> FINALLY_BLOCK
|
|
616
|
-
*/
|
|
617
|
-
bufferTryCatchFinallyEdges(tryBlocks, catchBlocks, finallyBlocks) {
|
|
618
|
-
// Buffer TRY_BLOCK edges
|
|
619
|
-
for (const tryBlock of tryBlocks) {
|
|
620
|
-
// Parent -> CONTAINS -> TRY_BLOCK
|
|
621
|
-
if (tryBlock.parentScopeId) {
|
|
622
|
-
this._bufferEdge({
|
|
623
|
-
type: 'CONTAINS',
|
|
624
|
-
src: tryBlock.parentScopeId,
|
|
625
|
-
dst: tryBlock.id
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
// Buffer CATCH_BLOCK edges (HAS_CATCH from TRY_BLOCK)
|
|
630
|
-
for (const catchBlock of catchBlocks) {
|
|
631
|
-
// TRY_BLOCK -> HAS_CATCH -> CATCH_BLOCK
|
|
632
|
-
this._bufferEdge({
|
|
633
|
-
type: 'HAS_CATCH',
|
|
634
|
-
src: catchBlock.parentTryBlockId,
|
|
635
|
-
dst: catchBlock.id
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
|
-
// Buffer FINALLY_BLOCK edges (HAS_FINALLY from TRY_BLOCK)
|
|
639
|
-
for (const finallyBlock of finallyBlocks) {
|
|
640
|
-
// TRY_BLOCK -> HAS_FINALLY -> FINALLY_BLOCK
|
|
641
|
-
this._bufferEdge({
|
|
642
|
-
type: 'HAS_FINALLY',
|
|
643
|
-
src: finallyBlock.parentTryBlockId,
|
|
644
|
-
dst: finallyBlock.id
|
|
645
|
-
});
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
/**
|
|
649
|
-
* Buffer EXPRESSION nodes for switch discriminants
|
|
650
|
-
* Uses stored metadata directly instead of parsing from ID (Linus improvement)
|
|
651
|
-
*
|
|
652
|
-
* REG-275: For CallExpression discriminants, we don't create nodes here since
|
|
653
|
-
* bufferBranchEdges links to the existing CALL_SITE node by coordinates.
|
|
654
|
-
*/
|
|
655
|
-
bufferDiscriminantExpressions(branches, callSites) {
|
|
656
|
-
for (const branch of branches) {
|
|
657
|
-
if (branch.discriminantExpressionId && branch.discriminantExpressionType) {
|
|
658
|
-
// Skip CallExpression - we link to existing CALL_SITE in bufferBranchEdges
|
|
659
|
-
if (branch.discriminantExpressionType === 'CallExpression') {
|
|
660
|
-
continue;
|
|
661
|
-
}
|
|
662
|
-
// Only create if it looks like an EXPRESSION ID
|
|
663
|
-
if (branch.discriminantExpressionId.includes(':EXPRESSION:')) {
|
|
664
|
-
this._bufferNode({
|
|
665
|
-
id: branch.discriminantExpressionId,
|
|
666
|
-
type: 'EXPRESSION',
|
|
667
|
-
name: branch.discriminantExpressionType,
|
|
668
|
-
file: branch.file,
|
|
669
|
-
line: branch.discriminantLine,
|
|
670
|
-
column: branch.discriminantColumn,
|
|
671
|
-
expressionType: branch.discriminantExpressionType
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
bufferVariableEdges(variableDeclarations) {
|
|
678
|
-
for (const varDecl of variableDeclarations) {
|
|
679
|
-
const { parentScopeId, ...varData } = varDecl;
|
|
680
|
-
// SCOPE -> DECLARES -> VARIABLE
|
|
681
|
-
this._bufferEdge({
|
|
682
|
-
type: 'DECLARES',
|
|
683
|
-
src: parentScopeId,
|
|
684
|
-
dst: varData.id
|
|
685
|
-
});
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
bufferCallSiteEdges(callSites, functions) {
|
|
689
|
-
for (const callSite of callSites) {
|
|
690
|
-
const { parentScopeId, targetFunctionName, ...callData } = callSite;
|
|
691
|
-
// SCOPE -> CONTAINS -> CALL_SITE
|
|
692
|
-
this._bufferEdge({
|
|
693
|
-
type: 'CONTAINS',
|
|
694
|
-
src: parentScopeId,
|
|
695
|
-
dst: callData.id
|
|
696
|
-
});
|
|
697
|
-
// CALL_SITE -> CALLS -> FUNCTION
|
|
698
|
-
const targetFunction = functions.find(f => f.name === targetFunctionName);
|
|
699
|
-
if (targetFunction) {
|
|
700
|
-
this._bufferEdge({
|
|
701
|
-
type: 'CALLS',
|
|
702
|
-
src: callData.id,
|
|
703
|
-
dst: targetFunction.id
|
|
704
|
-
});
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
bufferMethodCalls(methodCalls, variableDeclarations, parameters) {
|
|
709
|
-
for (const methodCall of methodCalls) {
|
|
710
|
-
// Keep parentScopeId on node for queries
|
|
711
|
-
this._bufferNode(methodCall);
|
|
712
|
-
// SCOPE -> CONTAINS -> METHOD_CALL
|
|
713
|
-
this._bufferEdge({
|
|
714
|
-
type: 'CONTAINS',
|
|
715
|
-
src: methodCall.parentScopeId,
|
|
716
|
-
dst: methodCall.id
|
|
717
|
-
});
|
|
718
|
-
// REG-262: Create USES edge from METHOD_CALL to receiver variable
|
|
719
|
-
// Skip 'this' - it's not a variable node
|
|
720
|
-
if (methodCall.object && methodCall.object !== 'this') {
|
|
721
|
-
// Handle nested member expressions: obj.nested.method() -> use base 'obj'
|
|
722
|
-
const receiverName = methodCall.object.includes('.')
|
|
723
|
-
? methodCall.object.split('.')[0]
|
|
724
|
-
: methodCall.object;
|
|
725
|
-
// Find receiver variable in current file
|
|
726
|
-
const receiverVar = variableDeclarations.find(v => v.name === receiverName && v.file === methodCall.file);
|
|
727
|
-
if (receiverVar) {
|
|
728
|
-
this._bufferEdge({
|
|
729
|
-
type: 'USES',
|
|
730
|
-
src: methodCall.id,
|
|
731
|
-
dst: receiverVar.id
|
|
732
|
-
});
|
|
733
|
-
}
|
|
734
|
-
else {
|
|
735
|
-
// Check parameters (function arguments)
|
|
736
|
-
const receiverParam = parameters.find(p => p.name === receiverName && p.file === methodCall.file);
|
|
737
|
-
if (receiverParam) {
|
|
738
|
-
this._bufferEdge({
|
|
739
|
-
type: 'USES',
|
|
740
|
-
src: methodCall.id,
|
|
741
|
-
dst: receiverParam.id
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
bufferStdioNodes(methodCalls) {
|
|
749
|
-
const consoleIOMethods = methodCalls.filter(mc => (mc.object === 'console' && (mc.method === 'log' || mc.method === 'error')));
|
|
750
|
-
if (consoleIOMethods.length > 0) {
|
|
751
|
-
const stdioNode = NodeFactory.createExternalStdio();
|
|
752
|
-
// Buffer net:stdio node only once (singleton)
|
|
753
|
-
if (!this._createdSingletons.has(stdioNode.id)) {
|
|
754
|
-
this._bufferNode(stdioNode);
|
|
755
|
-
this._createdSingletons.add(stdioNode.id);
|
|
756
|
-
}
|
|
757
|
-
// Buffer WRITES_TO edges for console.log/error
|
|
758
|
-
for (const methodCall of consoleIOMethods) {
|
|
759
|
-
this._bufferEdge({
|
|
760
|
-
type: 'WRITES_TO',
|
|
761
|
-
src: methodCall.id,
|
|
762
|
-
dst: stdioNode.id
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
bufferClassDeclarationNodes(classDeclarations) {
|
|
768
|
-
for (const classDecl of classDeclarations) {
|
|
769
|
-
const { id, type, name, file, line, column, superClass, methods } = classDecl;
|
|
770
|
-
// Buffer CLASS node
|
|
771
|
-
this._bufferNode({
|
|
772
|
-
id,
|
|
773
|
-
type,
|
|
774
|
-
name,
|
|
775
|
-
file,
|
|
776
|
-
line,
|
|
777
|
-
column,
|
|
778
|
-
superClass
|
|
779
|
-
});
|
|
780
|
-
// Buffer CONTAINS edges: CLASS -> METHOD
|
|
781
|
-
for (const methodId of methods) {
|
|
782
|
-
this._bufferEdge({
|
|
783
|
-
type: 'CONTAINS',
|
|
784
|
-
src: id,
|
|
785
|
-
dst: methodId
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
// If superClass, buffer DERIVES_FROM edge with computed ID
|
|
789
|
-
if (superClass) {
|
|
790
|
-
// Compute superclass ID using semantic ID format
|
|
791
|
-
// Assume superclass is in same file at global scope (most common case)
|
|
792
|
-
// When superclass is in different file, edge will be dangling until that file analyzed
|
|
793
|
-
const globalContext = { file, scopePath: [] };
|
|
794
|
-
const superClassId = computeSemanticId('CLASS', superClass, globalContext);
|
|
795
|
-
this._bufferEdge({
|
|
796
|
-
type: 'DERIVES_FROM',
|
|
797
|
-
src: id,
|
|
798
|
-
dst: superClassId
|
|
799
|
-
});
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
bufferClassNodes(module, classInstantiations, classDeclarations) {
|
|
804
|
-
// Create lookup map: className → declaration ID
|
|
805
|
-
// Use basename for comparison because CLASS nodes use scopeTracker.file (basename)
|
|
806
|
-
const moduleBasename = basename(module.file);
|
|
807
|
-
const declarationMap = new Map();
|
|
808
|
-
for (const decl of classDeclarations) {
|
|
809
|
-
if (decl.file === moduleBasename) {
|
|
810
|
-
declarationMap.set(decl.name, decl.id);
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
for (const instantiation of classInstantiations) {
|
|
814
|
-
const { variableId, className, line } = instantiation;
|
|
815
|
-
let classId = declarationMap.get(className);
|
|
816
|
-
if (!classId) {
|
|
817
|
-
// External class - compute semantic ID
|
|
818
|
-
// Use basename to match CLASS node format (scopeTracker uses basename)
|
|
819
|
-
// When class is in different file, edge will be dangling until that file analyzed
|
|
820
|
-
const globalContext = { file: moduleBasename, scopePath: [] };
|
|
821
|
-
classId = computeSemanticId('CLASS', className, globalContext);
|
|
822
|
-
// NO node creation - node will exist when class file analyzed
|
|
823
|
-
}
|
|
824
|
-
// Buffer INSTANCE_OF edge
|
|
825
|
-
this._bufferEdge({
|
|
826
|
-
type: 'INSTANCE_OF',
|
|
827
|
-
src: variableId,
|
|
828
|
-
dst: classId
|
|
829
|
-
});
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
bufferCallbackEdges(methodCallbacks, functions) {
|
|
833
|
-
for (const callback of methodCallbacks) {
|
|
834
|
-
const { methodCallId, callbackLine, callbackColumn } = callback;
|
|
835
|
-
const callbackFunction = functions.find(f => f.line === callbackLine && f.column === callbackColumn);
|
|
836
|
-
if (callbackFunction) {
|
|
837
|
-
this._bufferEdge({
|
|
838
|
-
type: 'HAS_CALLBACK',
|
|
839
|
-
src: methodCallId,
|
|
840
|
-
dst: callbackFunction.id
|
|
841
|
-
});
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
bufferImportNodes(module, imports) {
|
|
846
|
-
for (const imp of imports) {
|
|
847
|
-
const { source, specifiers, line, column, isDynamic, isResolvable, dynamicPath } = imp;
|
|
848
|
-
// REG-273: Handle side-effect-only imports (no specifiers)
|
|
849
|
-
if (specifiers.length === 0) {
|
|
850
|
-
// Side-effect import: import './polyfill.js'
|
|
851
|
-
const importNode = ImportNode.create(source, // name = source (no local binding)
|
|
852
|
-
module.file, // file
|
|
853
|
-
line, // line (stored as field, not in ID)
|
|
854
|
-
column || 0, // column
|
|
855
|
-
source, // source module
|
|
856
|
-
{
|
|
857
|
-
imported: '*', // no specific export
|
|
858
|
-
local: source, // source becomes local
|
|
859
|
-
sideEffect: true // mark as side-effect import
|
|
860
|
-
});
|
|
861
|
-
this._bufferNode(importNode);
|
|
862
|
-
// MODULE -> CONTAINS -> IMPORT
|
|
863
|
-
this._bufferEdge({
|
|
864
|
-
type: 'CONTAINS',
|
|
865
|
-
src: module.id,
|
|
866
|
-
dst: importNode.id
|
|
867
|
-
});
|
|
868
|
-
// Create EXTERNAL_MODULE node for external modules
|
|
869
|
-
const isRelative = source.startsWith('./') || source.startsWith('../');
|
|
870
|
-
if (!isRelative) {
|
|
871
|
-
const externalModule = NodeFactory.createExternalModule(source);
|
|
872
|
-
// Avoid duplicate EXTERNAL_MODULE nodes
|
|
873
|
-
if (!this._createdSingletons.has(externalModule.id)) {
|
|
874
|
-
this._bufferNode(externalModule);
|
|
875
|
-
this._createdSingletons.add(externalModule.id);
|
|
876
|
-
}
|
|
877
|
-
this._bufferEdge({
|
|
878
|
-
type: 'IMPORTS',
|
|
879
|
-
src: module.id,
|
|
880
|
-
dst: externalModule.id
|
|
881
|
-
});
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
else {
|
|
885
|
-
// Regular imports with specifiers
|
|
886
|
-
for (const spec of specifiers) {
|
|
887
|
-
// Use ImportNode factory for proper semantic IDs and field population
|
|
888
|
-
const importNode = ImportNode.create(spec.local, // name = local binding
|
|
889
|
-
module.file, // file
|
|
890
|
-
line, // line (stored as field, not in ID)
|
|
891
|
-
column || 0, // column
|
|
892
|
-
source, // source module
|
|
893
|
-
{
|
|
894
|
-
imported: spec.imported,
|
|
895
|
-
local: spec.local,
|
|
896
|
-
sideEffect: false, // regular imports are not side-effects
|
|
897
|
-
// importType is auto-detected from imported field
|
|
898
|
-
// Dynamic import fields
|
|
899
|
-
isDynamic,
|
|
900
|
-
isResolvable,
|
|
901
|
-
dynamicPath
|
|
902
|
-
});
|
|
903
|
-
this._bufferNode(importNode);
|
|
904
|
-
// MODULE -> CONTAINS -> IMPORT
|
|
905
|
-
this._bufferEdge({
|
|
906
|
-
type: 'CONTAINS',
|
|
907
|
-
src: module.id,
|
|
908
|
-
dst: importNode.id
|
|
909
|
-
});
|
|
910
|
-
// Create EXTERNAL_MODULE node for external modules
|
|
911
|
-
const isRelative = source.startsWith('./') || source.startsWith('../');
|
|
912
|
-
if (!isRelative) {
|
|
913
|
-
const externalModule = NodeFactory.createExternalModule(source);
|
|
914
|
-
// Avoid duplicate EXTERNAL_MODULE nodes
|
|
915
|
-
if (!this._createdSingletons.has(externalModule.id)) {
|
|
916
|
-
this._bufferNode(externalModule);
|
|
917
|
-
this._createdSingletons.add(externalModule.id);
|
|
918
|
-
}
|
|
919
|
-
this._bufferEdge({
|
|
920
|
-
type: 'IMPORTS',
|
|
921
|
-
src: module.id,
|
|
922
|
-
dst: externalModule.id
|
|
923
|
-
});
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
bufferExportNodes(module, exports) {
|
|
930
|
-
for (const exp of exports) {
|
|
931
|
-
const { type, line, name, specifiers, source } = exp;
|
|
932
|
-
if (type === 'default') {
|
|
933
|
-
const exportNode = NodeFactory.createExport('default', module.file, line, 0, { default: true, exportType: 'default' });
|
|
934
|
-
this._bufferNode(exportNode);
|
|
935
|
-
this._bufferEdge({
|
|
936
|
-
type: 'CONTAINS',
|
|
937
|
-
src: module.id,
|
|
938
|
-
dst: exportNode.id
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
else if (type === 'named') {
|
|
942
|
-
if (specifiers) {
|
|
943
|
-
for (const spec of specifiers) {
|
|
944
|
-
const exportNode = NodeFactory.createExport(spec.exported, module.file, line, 0, {
|
|
945
|
-
local: spec.local,
|
|
946
|
-
source: source,
|
|
947
|
-
exportType: 'named'
|
|
948
|
-
});
|
|
949
|
-
this._bufferNode(exportNode);
|
|
950
|
-
this._bufferEdge({
|
|
951
|
-
type: 'CONTAINS',
|
|
952
|
-
src: module.id,
|
|
953
|
-
dst: exportNode.id
|
|
954
|
-
});
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
else if (name) {
|
|
958
|
-
const exportNode = NodeFactory.createExport(name, module.file, line, 0, { exportType: 'named' });
|
|
959
|
-
this._bufferNode(exportNode);
|
|
960
|
-
this._bufferEdge({
|
|
961
|
-
type: 'CONTAINS',
|
|
962
|
-
src: module.id,
|
|
963
|
-
dst: exportNode.id
|
|
964
|
-
});
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
else if (type === 'all') {
|
|
968
|
-
const exportNode = NodeFactory.createExport('*', module.file, line, 0, {
|
|
969
|
-
source: source,
|
|
970
|
-
exportType: 'all'
|
|
971
|
-
});
|
|
972
|
-
this._bufferNode(exportNode);
|
|
973
|
-
this._bufferEdge({
|
|
974
|
-
type: 'CONTAINS',
|
|
975
|
-
src: module.id,
|
|
976
|
-
dst: exportNode.id
|
|
977
|
-
});
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
bufferEventListeners(eventListeners, functions) {
|
|
982
|
-
for (const eventListener of eventListeners) {
|
|
983
|
-
const { parentScopeId, callbackArg, ...listenerData } = eventListener;
|
|
984
|
-
this._bufferNode(listenerData);
|
|
985
|
-
this._bufferEdge({
|
|
986
|
-
type: 'CONTAINS',
|
|
987
|
-
src: parentScopeId,
|
|
988
|
-
dst: listenerData.id
|
|
989
|
-
});
|
|
990
|
-
if (callbackArg && callbackArg.type === 'ArrowFunctionExpression') {
|
|
991
|
-
const callbackLine = callbackArg.loc.start.line;
|
|
992
|
-
const callbackFunction = functions.find(f => f.line === callbackLine && f.arrowFunction);
|
|
993
|
-
if (callbackFunction) {
|
|
994
|
-
this._bufferEdge({
|
|
995
|
-
type: 'HANDLED_BY',
|
|
996
|
-
src: listenerData.id,
|
|
997
|
-
dst: callbackFunction.id
|
|
998
|
-
});
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
bufferHttpRequests(httpRequests, functions) {
|
|
1004
|
-
if (httpRequests.length > 0) {
|
|
1005
|
-
// Create net:request singleton using factory
|
|
1006
|
-
const networkNode = NetworkRequestNode.create();
|
|
1007
|
-
if (!this._createdSingletons.has(networkNode.id)) {
|
|
1008
|
-
this._bufferNode(networkNode);
|
|
1009
|
-
this._createdSingletons.add(networkNode.id);
|
|
1010
|
-
}
|
|
1011
|
-
for (const request of httpRequests) {
|
|
1012
|
-
const { parentScopeId, ...requestData } = request;
|
|
1013
|
-
this._bufferNode(requestData);
|
|
1014
|
-
this._bufferEdge({
|
|
1015
|
-
type: 'CALLS',
|
|
1016
|
-
src: request.id,
|
|
1017
|
-
dst: networkNode.id
|
|
1018
|
-
});
|
|
1019
|
-
if (parentScopeId) {
|
|
1020
|
-
const scopeParts = parentScopeId.split(':');
|
|
1021
|
-
if (scopeParts.length >= 3 && scopeParts[1] === 'SCOPE') {
|
|
1022
|
-
const functionName = scopeParts[2];
|
|
1023
|
-
const file = scopeParts[0];
|
|
1024
|
-
const parentFunction = functions.find(f => f.file === file && f.name === functionName);
|
|
1025
|
-
if (parentFunction) {
|
|
1026
|
-
this._bufferEdge({
|
|
1027
|
-
type: 'MAKES_REQUEST',
|
|
1028
|
-
src: parentFunction.id,
|
|
1029
|
-
dst: request.id
|
|
1030
|
-
});
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
bufferLiterals(literals) {
|
|
1038
|
-
for (const literal of literals) {
|
|
1039
|
-
const { parentCallId, argIndex, ...literalData } = literal;
|
|
1040
|
-
this._bufferNode(literalData);
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
bufferAssignmentEdges(variableAssignments, variableDeclarations, callSites, methodCalls, functions, classInstantiations, parameters) {
|
|
1044
|
-
for (const assignment of variableAssignments) {
|
|
1045
|
-
const { variableId, sourceId, sourceType, sourceName, sourceLine, sourceColumn, sourceFile, functionName, line, column, className } = assignment;
|
|
1046
|
-
// Skip CLASS sourceType - handled async in createClassAssignmentEdges
|
|
1047
|
-
if (sourceType === 'CLASS') {
|
|
1048
|
-
continue;
|
|
1049
|
-
}
|
|
1050
|
-
// CONSTRUCTOR_CALL: create ASSIGNED_FROM edge to existing node
|
|
1051
|
-
// Note: CONSTRUCTOR_CALL nodes are already created from constructorCalls collection in step 4.5
|
|
1052
|
-
if (sourceType === 'CONSTRUCTOR_CALL' && className) {
|
|
1053
|
-
const constructorLine = line ?? 0;
|
|
1054
|
-
const constructorColumn = column ?? 0;
|
|
1055
|
-
const constructorFile = assignment.file ?? '';
|
|
1056
|
-
// Generate ID matching the one created in NewExpression visitor
|
|
1057
|
-
const constructorCallId = NodeFactory.generateConstructorCallId(className, constructorFile, constructorLine, constructorColumn);
|
|
1058
|
-
this._bufferEdge({
|
|
1059
|
-
type: 'ASSIGNED_FROM',
|
|
1060
|
-
src: variableId,
|
|
1061
|
-
dst: constructorCallId
|
|
1062
|
-
});
|
|
1063
|
-
continue;
|
|
1064
|
-
}
|
|
1065
|
-
// Direct LITERAL assignment
|
|
1066
|
-
if (sourceId && sourceType !== 'EXPRESSION') {
|
|
1067
|
-
this._bufferEdge({
|
|
1068
|
-
type: 'ASSIGNED_FROM',
|
|
1069
|
-
src: variableId,
|
|
1070
|
-
dst: sourceId
|
|
1071
|
-
});
|
|
1072
|
-
}
|
|
1073
|
-
// METHOD_CALL by coordinates
|
|
1074
|
-
else if (sourceType === 'METHOD_CALL' && sourceLine && sourceColumn) {
|
|
1075
|
-
const methodCall = methodCalls.find(mc => mc.line === sourceLine &&
|
|
1076
|
-
mc.column === sourceColumn &&
|
|
1077
|
-
mc.file === sourceFile);
|
|
1078
|
-
if (methodCall) {
|
|
1079
|
-
this._bufferEdge({
|
|
1080
|
-
type: 'ASSIGNED_FROM',
|
|
1081
|
-
src: variableId,
|
|
1082
|
-
dst: methodCall.id
|
|
1083
|
-
});
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
// CALL_SITE by coordinates
|
|
1087
|
-
else if (sourceType === 'CALL_SITE') {
|
|
1088
|
-
const searchLine = sourceLine || assignment.callLine;
|
|
1089
|
-
const searchColumn = sourceColumn || assignment.callColumn;
|
|
1090
|
-
const searchName = assignment.callName;
|
|
1091
|
-
if (searchLine && searchColumn) {
|
|
1092
|
-
const callSite = callSites.find(cs => cs.line === searchLine &&
|
|
1093
|
-
cs.column === searchColumn &&
|
|
1094
|
-
(searchName ? cs.name === searchName : true));
|
|
1095
|
-
if (callSite) {
|
|
1096
|
-
this._bufferEdge({
|
|
1097
|
-
type: 'ASSIGNED_FROM',
|
|
1098
|
-
src: variableId,
|
|
1099
|
-
dst: callSite.id
|
|
1100
|
-
});
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
// VARIABLE by name
|
|
1105
|
-
else if (sourceType === 'VARIABLE' && sourceName) {
|
|
1106
|
-
// Find the current variable's file by looking it up in variableDeclarations
|
|
1107
|
-
// (semantic IDs don't have predictable file positions like old hash-based IDs)
|
|
1108
|
-
const currentVar = variableDeclarations.find(v => v.id === variableId);
|
|
1109
|
-
const varFile = currentVar?.file ?? null;
|
|
1110
|
-
const sourceVariable = variableDeclarations.find(v => v.name === sourceName && v.file === varFile);
|
|
1111
|
-
if (sourceVariable) {
|
|
1112
|
-
this._bufferEdge({
|
|
1113
|
-
type: 'ASSIGNED_FROM',
|
|
1114
|
-
src: variableId,
|
|
1115
|
-
dst: sourceVariable.id
|
|
1116
|
-
});
|
|
1117
|
-
}
|
|
1118
|
-
else {
|
|
1119
|
-
const sourceParam = parameters.find(p => p.name === sourceName && p.file === varFile);
|
|
1120
|
-
if (sourceParam) {
|
|
1121
|
-
this._bufferEdge({
|
|
1122
|
-
type: 'DERIVES_FROM',
|
|
1123
|
-
src: variableId,
|
|
1124
|
-
dst: sourceParam.id
|
|
1125
|
-
});
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
// FUNCTION (arrow function assigned to variable)
|
|
1130
|
-
else if (sourceType === 'FUNCTION' && functionName && line) {
|
|
1131
|
-
const sourceFunction = functions.find(f => f.name === functionName && f.line === line);
|
|
1132
|
-
if (sourceFunction) {
|
|
1133
|
-
this._bufferEdge({
|
|
1134
|
-
type: 'ASSIGNED_FROM',
|
|
1135
|
-
src: variableId,
|
|
1136
|
-
dst: sourceFunction.id
|
|
1137
|
-
});
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
// EXPRESSION node creation using NodeFactory
|
|
1141
|
-
else if (sourceType === 'EXPRESSION' && sourceId) {
|
|
1142
|
-
const { expressionType, object, property, computed, computedPropertyVar, operator, objectSourceName, leftSourceName, rightSourceName, consequentSourceName, alternateSourceName, file: exprFile, line: exprLine, column: exprColumn,
|
|
1143
|
-
// Destructuring support (REG-201)
|
|
1144
|
-
path, baseName, propertyPath, arrayIndex } = assignment;
|
|
1145
|
-
// Create node from upstream metadata using factory
|
|
1146
|
-
const expressionNode = NodeFactory.createExpressionFromMetadata(expressionType || 'Unknown', exprFile || '', exprLine || 0, exprColumn || 0, {
|
|
1147
|
-
id: sourceId, // ID from JSASTAnalyzer
|
|
1148
|
-
object,
|
|
1149
|
-
property,
|
|
1150
|
-
computed,
|
|
1151
|
-
computedPropertyVar: computedPropertyVar ?? undefined,
|
|
1152
|
-
operator,
|
|
1153
|
-
// Destructuring support (REG-201)
|
|
1154
|
-
path,
|
|
1155
|
-
baseName,
|
|
1156
|
-
propertyPath,
|
|
1157
|
-
arrayIndex
|
|
1158
|
-
});
|
|
1159
|
-
this._bufferNode(expressionNode);
|
|
1160
|
-
this._bufferEdge({
|
|
1161
|
-
type: 'ASSIGNED_FROM',
|
|
1162
|
-
src: variableId,
|
|
1163
|
-
dst: sourceId
|
|
1164
|
-
});
|
|
1165
|
-
// Buffer DERIVES_FROM edges
|
|
1166
|
-
const varParts = variableId.split('#');
|
|
1167
|
-
const varFile = varParts.length >= 3 ? varParts[2] : null;
|
|
1168
|
-
if (expressionType === 'MemberExpression' && objectSourceName) {
|
|
1169
|
-
const objectVar = variableDeclarations.find(v => v.name === objectSourceName && (!varFile || v.file === varFile));
|
|
1170
|
-
if (objectVar) {
|
|
1171
|
-
this._bufferEdge({
|
|
1172
|
-
type: 'DERIVES_FROM',
|
|
1173
|
-
src: sourceId,
|
|
1174
|
-
dst: objectVar.id
|
|
1175
|
-
});
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
// Call-based source lookup (REG-223)
|
|
1179
|
-
else if (expressionType === 'MemberExpression' && assignment.callSourceLine !== undefined) {
|
|
1180
|
-
const { callSourceLine, callSourceColumn, callSourceName, callSourceFile } = assignment;
|
|
1181
|
-
// Try CALL_SITE first (direct function calls)
|
|
1182
|
-
const callSite = callSites.find(cs => cs.line === callSourceLine &&
|
|
1183
|
-
cs.column === callSourceColumn &&
|
|
1184
|
-
(callSourceName ? cs.name === callSourceName : true));
|
|
1185
|
-
if (callSite) {
|
|
1186
|
-
this._bufferEdge({
|
|
1187
|
-
type: 'DERIVES_FROM',
|
|
1188
|
-
src: sourceId,
|
|
1189
|
-
dst: callSite.id
|
|
1190
|
-
});
|
|
1191
|
-
}
|
|
1192
|
-
// Fall back to methodCalls (arr.map(), obj.getConfig())
|
|
1193
|
-
else {
|
|
1194
|
-
const methodCall = methodCalls.find(mc => mc.line === callSourceLine &&
|
|
1195
|
-
mc.column === callSourceColumn &&
|
|
1196
|
-
(callSourceName ? mc.name === callSourceName : true));
|
|
1197
|
-
if (methodCall) {
|
|
1198
|
-
this._bufferEdge({
|
|
1199
|
-
type: 'DERIVES_FROM',
|
|
1200
|
-
src: sourceId,
|
|
1201
|
-
dst: methodCall.id
|
|
1202
|
-
});
|
|
1203
|
-
}
|
|
1204
|
-
// Log warning when lookup fails (per Linus review - no silent failures)
|
|
1205
|
-
else {
|
|
1206
|
-
console.warn(`[REG-223] DERIVES_FROM lookup failed for EXPRESSION(${assignment.object}.${assignment.property}) ` +
|
|
1207
|
-
`at ${callSourceFile}:${callSourceLine}:${callSourceColumn}. ` +
|
|
1208
|
-
`Expected CALL_SITE or methodCall for "${callSourceName}". ` +
|
|
1209
|
-
`This indicates a coordinate mismatch or missing call node.`);
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
if ((expressionType === 'BinaryExpression' || expressionType === 'LogicalExpression')) {
|
|
1214
|
-
if (leftSourceName) {
|
|
1215
|
-
const leftVar = variableDeclarations.find(v => v.name === leftSourceName && (!varFile || v.file === varFile));
|
|
1216
|
-
if (leftVar) {
|
|
1217
|
-
this._bufferEdge({
|
|
1218
|
-
type: 'DERIVES_FROM',
|
|
1219
|
-
src: sourceId,
|
|
1220
|
-
dst: leftVar.id
|
|
1221
|
-
});
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
if (rightSourceName) {
|
|
1225
|
-
const rightVar = variableDeclarations.find(v => v.name === rightSourceName && (!varFile || v.file === varFile));
|
|
1226
|
-
if (rightVar) {
|
|
1227
|
-
this._bufferEdge({
|
|
1228
|
-
type: 'DERIVES_FROM',
|
|
1229
|
-
src: sourceId,
|
|
1230
|
-
dst: rightVar.id
|
|
1231
|
-
});
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
if (expressionType === 'ConditionalExpression') {
|
|
1236
|
-
if (consequentSourceName) {
|
|
1237
|
-
const consequentVar = variableDeclarations.find(v => v.name === consequentSourceName && (!varFile || v.file === varFile));
|
|
1238
|
-
if (consequentVar) {
|
|
1239
|
-
this._bufferEdge({
|
|
1240
|
-
type: 'DERIVES_FROM',
|
|
1241
|
-
src: sourceId,
|
|
1242
|
-
dst: consequentVar.id
|
|
1243
|
-
});
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
if (alternateSourceName) {
|
|
1247
|
-
const alternateVar = variableDeclarations.find(v => v.name === alternateSourceName && (!varFile || v.file === varFile));
|
|
1248
|
-
if (alternateVar) {
|
|
1249
|
-
this._bufferEdge({
|
|
1250
|
-
type: 'DERIVES_FROM',
|
|
1251
|
-
src: sourceId,
|
|
1252
|
-
dst: alternateVar.id
|
|
1253
|
-
});
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
if (expressionType === 'TemplateLiteral') {
|
|
1258
|
-
const { expressionSourceNames } = assignment;
|
|
1259
|
-
if (expressionSourceNames && expressionSourceNames.length > 0) {
|
|
1260
|
-
for (const exprSourceName of expressionSourceNames) {
|
|
1261
|
-
const sourceVar = variableDeclarations.find(v => v.name === exprSourceName && (!varFile || v.file === varFile));
|
|
1262
|
-
if (sourceVar) {
|
|
1263
|
-
this._bufferEdge({
|
|
1264
|
-
type: 'DERIVES_FROM',
|
|
1265
|
-
src: sourceId,
|
|
1266
|
-
dst: sourceVar.id
|
|
1267
|
-
});
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
// DERIVES_FROM_VARIABLE
|
|
1274
|
-
else if (sourceType === 'DERIVES_FROM_VARIABLE' && sourceName) {
|
|
1275
|
-
const expressionId = variableId;
|
|
1276
|
-
const exprParts = expressionId.split('#');
|
|
1277
|
-
const exprFile = exprParts.length >= 3 ? exprParts[2] : assignment.file;
|
|
1278
|
-
const sourceVariable = variableDeclarations.find(v => v.name === sourceName && v.file === exprFile);
|
|
1279
|
-
if (sourceVariable) {
|
|
1280
|
-
this._bufferEdge({
|
|
1281
|
-
type: 'DERIVES_FROM',
|
|
1282
|
-
src: expressionId,
|
|
1283
|
-
dst: sourceVariable.id
|
|
1284
|
-
});
|
|
1285
|
-
}
|
|
1286
|
-
else {
|
|
1287
|
-
const sourceParam = parameters.find(p => p.name === sourceName && p.file === exprFile);
|
|
1288
|
-
if (sourceParam) {
|
|
1289
|
-
this._bufferEdge({
|
|
1290
|
-
type: 'DERIVES_FROM',
|
|
1291
|
-
src: expressionId,
|
|
1292
|
-
dst: sourceParam.id
|
|
1293
|
-
});
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
bufferArgumentEdges(callArguments, variableDeclarations, functions, callSites, methodCalls) {
|
|
1300
|
-
for (const arg of callArguments) {
|
|
1301
|
-
const { callId, argIndex, targetType, targetId, targetName, file, isSpread, functionLine, functionColumn, nestedCallLine, nestedCallColumn } = arg;
|
|
1302
|
-
let targetNodeId = targetId;
|
|
1303
|
-
if (targetType === 'VARIABLE' && targetName) {
|
|
1304
|
-
const varNode = variableDeclarations.find(v => v.name === targetName && v.file === file);
|
|
1305
|
-
if (varNode) {
|
|
1306
|
-
targetNodeId = varNode.id;
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
else if (targetType === 'FUNCTION' && functionLine && functionColumn) {
|
|
1310
|
-
const funcNode = functions.find(f => f.file === file && f.line === functionLine && f.column === functionColumn);
|
|
1311
|
-
if (funcNode) {
|
|
1312
|
-
targetNodeId = funcNode.id;
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1315
|
-
else if (targetType === 'CALL' && nestedCallLine && nestedCallColumn) {
|
|
1316
|
-
const nestedCall = callSites.find(c => c.file === file && c.line === nestedCallLine && c.column === nestedCallColumn) || methodCalls.find(c => c.file === file && c.line === nestedCallLine && c.column === nestedCallColumn);
|
|
1317
|
-
if (nestedCall) {
|
|
1318
|
-
targetNodeId = nestedCall.id;
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
else if (targetType === 'LITERAL' ||
|
|
1322
|
-
targetType === 'OBJECT_LITERAL' ||
|
|
1323
|
-
targetType === 'ARRAY_LITERAL') {
|
|
1324
|
-
// targetId is already set by CallExpressionVisitor
|
|
1325
|
-
targetNodeId = targetId;
|
|
1326
|
-
}
|
|
1327
|
-
if (targetNodeId) {
|
|
1328
|
-
const edgeData = {
|
|
1329
|
-
type: 'PASSES_ARGUMENT',
|
|
1330
|
-
src: callId,
|
|
1331
|
-
dst: targetNodeId,
|
|
1332
|
-
metadata: { argIndex }
|
|
1333
|
-
};
|
|
1334
|
-
if (isSpread) {
|
|
1335
|
-
edgeData.metadata = { ...edgeData.metadata, isSpread: true };
|
|
1336
|
-
}
|
|
1337
|
-
this._bufferEdge(edgeData);
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
// ============= TypeScript-specific buffer methods =============
|
|
1342
|
-
/**
|
|
1343
|
-
* Buffer INTERFACE nodes and EXTENDS edges
|
|
1344
|
-
*
|
|
1345
|
-
* Uses two-pass approach:
|
|
1346
|
-
* 1. First pass: create all interface nodes, store in Map
|
|
1347
|
-
* 2. Second pass: create EXTENDS edges using stored node IDs
|
|
1348
|
-
*/
|
|
1349
|
-
bufferInterfaceNodes(module, interfaces) {
|
|
1350
|
-
// First pass: create all interface nodes and store them
|
|
1351
|
-
const interfaceNodes = new Map();
|
|
1352
|
-
for (const iface of interfaces) {
|
|
1353
|
-
const interfaceNode = InterfaceNode.create(iface.name, iface.file, iface.line, iface.column || 0, {
|
|
1354
|
-
extends: iface.extends,
|
|
1355
|
-
properties: iface.properties
|
|
1356
|
-
});
|
|
1357
|
-
interfaceNodes.set(iface.name, interfaceNode);
|
|
1358
|
-
this._bufferNode(interfaceNode);
|
|
1359
|
-
// MODULE -> CONTAINS -> INTERFACE
|
|
1360
|
-
this._bufferEdge({
|
|
1361
|
-
type: 'CONTAINS',
|
|
1362
|
-
src: module.id,
|
|
1363
|
-
dst: interfaceNode.id
|
|
1364
|
-
});
|
|
1365
|
-
}
|
|
1366
|
-
// Second pass: create EXTENDS edges
|
|
1367
|
-
for (const iface of interfaces) {
|
|
1368
|
-
if (iface.extends && iface.extends.length > 0) {
|
|
1369
|
-
const srcNode = interfaceNodes.get(iface.name);
|
|
1370
|
-
for (const parentName of iface.extends) {
|
|
1371
|
-
const parentNode = interfaceNodes.get(parentName);
|
|
1372
|
-
if (parentNode) {
|
|
1373
|
-
// Same-file interface
|
|
1374
|
-
this._bufferEdge({
|
|
1375
|
-
type: 'EXTENDS',
|
|
1376
|
-
src: srcNode.id,
|
|
1377
|
-
dst: parentNode.id
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
else {
|
|
1381
|
-
// External interface - create a reference node
|
|
1382
|
-
const externalInterface = NodeFactory.createInterface(parentName, iface.file, iface.line, 0, { isExternal: true });
|
|
1383
|
-
this._bufferNode(externalInterface);
|
|
1384
|
-
this._bufferEdge({
|
|
1385
|
-
type: 'EXTENDS',
|
|
1386
|
-
src: srcNode.id,
|
|
1387
|
-
dst: externalInterface.id
|
|
1388
|
-
});
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
}
|
|
1394
|
-
/**
|
|
1395
|
-
* Buffer TYPE alias nodes
|
|
1396
|
-
*/
|
|
1397
|
-
bufferTypeAliasNodes(module, typeAliases) {
|
|
1398
|
-
for (const typeAlias of typeAliases) {
|
|
1399
|
-
// Create TYPE node using factory
|
|
1400
|
-
const typeNode = NodeFactory.createType(typeAlias.name, typeAlias.file, typeAlias.line, typeAlias.column || 0, { aliasOf: typeAlias.aliasOf });
|
|
1401
|
-
this._bufferNode(typeNode);
|
|
1402
|
-
// MODULE -> CONTAINS -> TYPE
|
|
1403
|
-
this._bufferEdge({
|
|
1404
|
-
type: 'CONTAINS',
|
|
1405
|
-
src: module.id,
|
|
1406
|
-
dst: typeNode.id
|
|
1407
|
-
});
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
/**
|
|
1411
|
-
* Buffer ENUM nodes
|
|
1412
|
-
* Uses EnumNode.create() to ensure consistent ID format (colon separator)
|
|
1413
|
-
*/
|
|
1414
|
-
bufferEnumNodes(module, enums) {
|
|
1415
|
-
for (const enumDecl of enums) {
|
|
1416
|
-
// Use EnumNode.create() to generate proper ID (colon format)
|
|
1417
|
-
// Do NOT use enumDecl.id which has legacy # format from TypeScriptVisitor
|
|
1418
|
-
const enumNode = EnumNode.create(enumDecl.name, enumDecl.file, enumDecl.line, enumDecl.column || 0, {
|
|
1419
|
-
isConst: enumDecl.isConst || false,
|
|
1420
|
-
members: enumDecl.members || []
|
|
1421
|
-
});
|
|
1422
|
-
this._bufferNode(enumNode);
|
|
1423
|
-
// MODULE -> CONTAINS -> ENUM
|
|
1424
|
-
this._bufferEdge({
|
|
1425
|
-
type: 'CONTAINS',
|
|
1426
|
-
src: module.id,
|
|
1427
|
-
dst: enumNode.id // Use factory-generated ID (colon format)
|
|
1428
|
-
});
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1431
|
-
/**
|
|
1432
|
-
* Buffer DECORATOR nodes and DECORATED_BY edges
|
|
1433
|
-
*/
|
|
1434
|
-
bufferDecoratorNodes(decorators) {
|
|
1435
|
-
for (const decorator of decorators) {
|
|
1436
|
-
// Create DECORATOR node using factory (generates colon-format ID)
|
|
1437
|
-
const decoratorNode = DecoratorNode.create(decorator.name, decorator.file, decorator.line, decorator.column || 0, decorator.targetId, // Now included in the node!
|
|
1438
|
-
decorator.targetType, { arguments: decorator.arguments });
|
|
1439
|
-
this._bufferNode(decoratorNode);
|
|
1440
|
-
// TARGET -> DECORATED_BY -> DECORATOR
|
|
1441
|
-
this._bufferEdge({
|
|
1442
|
-
type: 'DECORATED_BY',
|
|
1443
|
-
src: decorator.targetId,
|
|
1444
|
-
dst: decoratorNode.id // Use factory-generated ID (colon format)
|
|
1445
|
-
});
|
|
1446
|
-
}
|
|
1447
|
-
}
|
|
1448
|
-
/**
|
|
1449
|
-
* Buffer IMPLEMENTS edges (CLASS -> INTERFACE)
|
|
1450
|
-
*/
|
|
1451
|
-
bufferImplementsEdges(classDeclarations, interfaces) {
|
|
1452
|
-
for (const classDecl of classDeclarations) {
|
|
1453
|
-
if (classDecl.implements && classDecl.implements.length > 0) {
|
|
1454
|
-
for (const ifaceName of classDecl.implements) {
|
|
1455
|
-
// Try to find the interface in the same file
|
|
1456
|
-
const iface = interfaces.find(i => i.name === ifaceName);
|
|
1457
|
-
if (iface) {
|
|
1458
|
-
// Compute interface ID using same formula as InterfaceNode.create()
|
|
1459
|
-
// Format: {file}:INTERFACE:{name}:{line}
|
|
1460
|
-
const interfaceId = `${iface.file}:INTERFACE:${iface.name}:${iface.line}`;
|
|
1461
|
-
this._bufferEdge({
|
|
1462
|
-
type: 'IMPLEMENTS',
|
|
1463
|
-
src: classDecl.id,
|
|
1464
|
-
dst: interfaceId
|
|
1465
|
-
});
|
|
1466
|
-
}
|
|
1467
|
-
else {
|
|
1468
|
-
// External interface - create a reference node
|
|
1469
|
-
const externalInterface = NodeFactory.createInterface(ifaceName, classDecl.file, classDecl.line, 0, { isExternal: true });
|
|
1470
|
-
this._bufferNode(externalInterface);
|
|
1471
|
-
this._bufferEdge({
|
|
1472
|
-
type: 'IMPLEMENTS',
|
|
1473
|
-
src: classDecl.id,
|
|
1474
|
-
dst: externalInterface.id
|
|
1475
|
-
});
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1481
|
-
/**
|
|
1482
|
-
* Buffer FLOWS_INTO edges for array mutations (push, unshift, splice, indexed assignment)
|
|
1483
|
-
* Creates edges from inserted values to the array variable
|
|
1484
|
-
*
|
|
1485
|
-
* REG-117: Now handles nested mutations like obj.arr.push(item):
|
|
1486
|
-
* - For nested mutations, falls back to base object if array property not found
|
|
1487
|
-
* - Adds nestedProperty metadata for tracking
|
|
1488
|
-
*
|
|
1489
|
-
* OPTIMIZED: Uses Map-based lookup cache for O(1) variable lookups instead of O(n) find()
|
|
1490
|
-
*/
|
|
1491
|
-
bufferArrayMutationEdges(arrayMutations, variableDeclarations, parameters) {
|
|
1492
|
-
// Note: No longer using Map-based cache - scope-aware lookup requires scope chain walk
|
|
1493
|
-
for (const mutation of arrayMutations) {
|
|
1494
|
-
const { arrayName, mutationScopePath, mutationMethod, insertedValues, file, isNested, baseObjectName, propertyName } = mutation;
|
|
1495
|
-
const scopePath = mutationScopePath ?? [];
|
|
1496
|
-
// REG-117: For nested mutations (obj.arr.push), resolve target node
|
|
1497
|
-
let targetNodeId = null;
|
|
1498
|
-
let nestedProperty;
|
|
1499
|
-
if (isNested && baseObjectName) {
|
|
1500
|
-
// Skip 'this.items.push' - 'this' is not a variable node
|
|
1501
|
-
if (baseObjectName === 'this')
|
|
1502
|
-
continue;
|
|
1503
|
-
// Nested mutation: try base object lookup with scope chain (REG-309)
|
|
1504
|
-
const baseVar = this.resolveVariableInScope(baseObjectName, scopePath, file, variableDeclarations);
|
|
1505
|
-
const baseParam = !baseVar ? this.resolveParameterInScope(baseObjectName, scopePath, file, parameters) : null;
|
|
1506
|
-
targetNodeId = baseVar?.id ?? baseParam?.id ?? null;
|
|
1507
|
-
nestedProperty = propertyName;
|
|
1508
|
-
}
|
|
1509
|
-
else {
|
|
1510
|
-
// Direct mutation: arr.push() (REG-309)
|
|
1511
|
-
const arrayVar = this.resolveVariableInScope(arrayName, scopePath, file, variableDeclarations);
|
|
1512
|
-
const arrayParam = !arrayVar ? this.resolveParameterInScope(arrayName, scopePath, file, parameters) : null;
|
|
1513
|
-
targetNodeId = arrayVar?.id ?? arrayParam?.id ?? null;
|
|
1514
|
-
}
|
|
1515
|
-
if (!targetNodeId)
|
|
1516
|
-
continue;
|
|
1517
|
-
// Create FLOWS_INTO edges for each inserted value
|
|
1518
|
-
for (const arg of insertedValues) {
|
|
1519
|
-
if (arg.valueType === 'VARIABLE' && arg.valueName) {
|
|
1520
|
-
// Scope-aware lookup for source variable (REG-309)
|
|
1521
|
-
const sourceVar = this.resolveVariableInScope(arg.valueName, scopePath, file, variableDeclarations);
|
|
1522
|
-
const sourceParam = !sourceVar ? this.resolveParameterInScope(arg.valueName, scopePath, file, parameters) : null;
|
|
1523
|
-
const sourceNodeId = sourceVar?.id ?? sourceParam?.id;
|
|
1524
|
-
if (sourceNodeId) {
|
|
1525
|
-
const edgeData = {
|
|
1526
|
-
type: 'FLOWS_INTO',
|
|
1527
|
-
src: sourceNodeId,
|
|
1528
|
-
dst: targetNodeId,
|
|
1529
|
-
mutationMethod,
|
|
1530
|
-
argIndex: arg.argIndex
|
|
1531
|
-
};
|
|
1532
|
-
if (arg.isSpread) {
|
|
1533
|
-
edgeData.isSpread = true;
|
|
1534
|
-
}
|
|
1535
|
-
// REG-117: Add nested property metadata
|
|
1536
|
-
if (nestedProperty) {
|
|
1537
|
-
edgeData.nestedProperty = nestedProperty;
|
|
1538
|
-
}
|
|
1539
|
-
this._bufferEdge(edgeData);
|
|
1540
|
-
}
|
|
1541
|
-
}
|
|
1542
|
-
// For literals, object literals, etc. - we could create edges from LITERAL nodes
|
|
1543
|
-
// but for now we just track variable -> array flows
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
/**
|
|
1548
|
-
* Buffer FLOWS_INTO edges for object mutations (property assignment, Object.assign)
|
|
1549
|
-
* Creates edges from source values to the object variable being mutated.
|
|
1550
|
-
*
|
|
1551
|
-
* REG-152: For 'this.prop = value' patterns inside classes, creates edges
|
|
1552
|
-
* to the CLASS node with mutationType: 'this_property'.
|
|
1553
|
-
*/
|
|
1554
|
-
bufferObjectMutationEdges(objectMutations, variableDeclarations, parameters, functions, classDeclarations) {
|
|
1555
|
-
for (const mutation of objectMutations) {
|
|
1556
|
-
const { objectName, mutationScopePath, propertyName, mutationType, computedPropertyVar, value, file, enclosingClassName } = mutation;
|
|
1557
|
-
const scopePath = mutationScopePath ?? [];
|
|
1558
|
-
// Find the target node (object variable, parameter, or class for 'this')
|
|
1559
|
-
let objectNodeId = null;
|
|
1560
|
-
let effectiveMutationType = mutationType;
|
|
1561
|
-
if (objectName !== 'this') {
|
|
1562
|
-
// Regular object - find variable, parameter, or function using scope chain (REG-309)
|
|
1563
|
-
const objectVar = this.resolveVariableInScope(objectName, scopePath, file, variableDeclarations);
|
|
1564
|
-
const objectParam = !objectVar ? this.resolveParameterInScope(objectName, scopePath, file, parameters) : null;
|
|
1565
|
-
const objectFunc = !objectVar && !objectParam ? functions.find(f => f.name === objectName && f.file === file) : null;
|
|
1566
|
-
objectNodeId = objectVar?.id ?? objectParam?.id ?? objectFunc?.id ?? null;
|
|
1567
|
-
if (!objectNodeId)
|
|
1568
|
-
continue;
|
|
1569
|
-
}
|
|
1570
|
-
else {
|
|
1571
|
-
// REG-152: 'this' mutations - find the CLASS node
|
|
1572
|
-
if (!enclosingClassName)
|
|
1573
|
-
continue; // Skip if no class context (e.g., standalone function)
|
|
1574
|
-
// Compare using basename since classes use scopeTracker.file (basename)
|
|
1575
|
-
// but mutations use module.file (full path)
|
|
1576
|
-
const fileBasename = basename(file);
|
|
1577
|
-
const classDecl = classDeclarations.find(c => c.name === enclosingClassName && c.file === fileBasename);
|
|
1578
|
-
objectNodeId = classDecl?.id ?? null;
|
|
1579
|
-
if (!objectNodeId)
|
|
1580
|
-
continue; // Skip if class not found
|
|
1581
|
-
// Use special mutation type to distinguish from regular property mutations
|
|
1582
|
-
effectiveMutationType = 'this_property';
|
|
1583
|
-
}
|
|
1584
|
-
// Create FLOWS_INTO edge for VARIABLE value type
|
|
1585
|
-
if (value.valueType === 'VARIABLE' && value.valueName) {
|
|
1586
|
-
// Find the source: can be variable, parameter, or function using scope chain (REG-309)
|
|
1587
|
-
const sourceVar = this.resolveVariableInScope(value.valueName, scopePath, file, variableDeclarations);
|
|
1588
|
-
const sourceParam = !sourceVar ? this.resolveParameterInScope(value.valueName, scopePath, file, parameters) : null;
|
|
1589
|
-
const sourceFunc = !sourceVar && !sourceParam ? functions.find(f => f.name === value.valueName && f.file === file) : null;
|
|
1590
|
-
const sourceNodeId = sourceVar?.id ?? sourceParam?.id ?? sourceFunc?.id;
|
|
1591
|
-
if (sourceNodeId && objectNodeId) {
|
|
1592
|
-
const edgeData = {
|
|
1593
|
-
type: 'FLOWS_INTO',
|
|
1594
|
-
src: sourceNodeId,
|
|
1595
|
-
dst: objectNodeId,
|
|
1596
|
-
mutationType: effectiveMutationType,
|
|
1597
|
-
propertyName,
|
|
1598
|
-
computedPropertyVar // For enrichment phase resolution
|
|
1599
|
-
};
|
|
1600
|
-
if (value.argIndex !== undefined) {
|
|
1601
|
-
edgeData.argIndex = value.argIndex;
|
|
1602
|
-
}
|
|
1603
|
-
if (value.isSpread) {
|
|
1604
|
-
edgeData.isSpread = true;
|
|
1605
|
-
}
|
|
1606
|
-
this._bufferEdge(edgeData);
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1609
|
-
// For literals, object literals, etc. - we just track variable -> object flows for now
|
|
231
|
+
if (candidates.length === 1) {
|
|
232
|
+
return candidates[0];
|
|
1610
233
|
}
|
|
234
|
+
// Multiple candidates: prefer same scope, then module-level
|
|
235
|
+
const sameScope = candidates.find(f => f.parentScopeId === callScopeId);
|
|
236
|
+
if (sameScope)
|
|
237
|
+
return sameScope;
|
|
238
|
+
// Fallback: prefer module-level function (parentScopeId contains MODULE)
|
|
239
|
+
const moduleLevel = candidates.find(f => f.parentScopeId?.includes(':MODULE:'));
|
|
240
|
+
return moduleLevel || candidates[0];
|
|
1611
241
|
}
|
|
1612
242
|
/**
|
|
1613
243
|
* Resolve variable by name using scope chain lookup (REG-309).
|
|
@@ -1626,6 +256,14 @@ export class GraphBuilder {
|
|
|
1626
256
|
const matchingVar = variables.find(v => {
|
|
1627
257
|
if (v.name !== name || v.file !== file)
|
|
1628
258
|
return false;
|
|
259
|
+
// REG-464: v2 path — use scopePath field if available (set by visitors)
|
|
260
|
+
if (v.scopePath) {
|
|
261
|
+
if (searchScopePath.length === 0) {
|
|
262
|
+
return v.scopePath.length === 0;
|
|
263
|
+
}
|
|
264
|
+
return this.scopePathsMatch(v.scopePath, searchScopePath);
|
|
265
|
+
}
|
|
266
|
+
// v1 fallback: parse semanticId
|
|
1629
267
|
// Variable ID IS the semantic ID (when scopeTracker was available during analysis)
|
|
1630
268
|
// Format: file->scope1->scope2->TYPE->name
|
|
1631
269
|
// Legacy format: VARIABLE#name#file#line:column:counter
|
|
@@ -1664,6 +302,22 @@ export class GraphBuilder {
|
|
|
1664
302
|
return parameters.find(p => {
|
|
1665
303
|
if (p.name !== name || p.file !== file)
|
|
1666
304
|
return false;
|
|
305
|
+
// REG-464: v2 path — use scopePath field if available (set by visitors)
|
|
306
|
+
if (p.scopePath) {
|
|
307
|
+
for (let i = scopePath.length; i >= 0; i--) {
|
|
308
|
+
const searchScopePath = scopePath.slice(0, i);
|
|
309
|
+
if (searchScopePath.length === 0) {
|
|
310
|
+
if (p.scopePath.length === 0)
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
if (this.scopePathsMatch(p.scopePath, searchScopePath))
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
// v1 fallback: parse semanticId
|
|
1667
321
|
if (p.semanticId) {
|
|
1668
322
|
const parsed = parseSemanticId(p.semanticId);
|
|
1669
323
|
if (parsed && parsed.type === 'PARAMETER') {
|
|
@@ -1696,565 +350,51 @@ export class GraphBuilder {
|
|
|
1696
350
|
return false;
|
|
1697
351
|
return a.every((item, idx) => item === b[idx]);
|
|
1698
352
|
}
|
|
353
|
+
// ============= POST-FLUSH METHODS (need graph queries) =============
|
|
1699
354
|
/**
|
|
1700
|
-
*
|
|
1701
|
-
*
|
|
1702
|
-
*
|
|
1703
|
-
* Edge patterns:
|
|
1704
|
-
* - Simple assignment (=): source --FLOWS_INTO--> variable
|
|
1705
|
-
* - Compound operators (+=, -=, etc.):
|
|
1706
|
-
* - source --FLOWS_INTO--> variable (write new value)
|
|
1707
|
-
* - variable --READS_FROM--> variable (self-loop: reads current value before write)
|
|
1708
|
-
*
|
|
1709
|
-
* REG-309: Uses scope-aware variable lookup via resolveVariableInScope().
|
|
1710
|
-
*
|
|
1711
|
-
* REG-290: Complete implementation with inline node creation (no continue statements).
|
|
1712
|
-
*/
|
|
1713
|
-
bufferVariableReassignmentEdges(variableReassignments, variableDeclarations, callSites, methodCalls, parameters) {
|
|
1714
|
-
// Note: No longer using Map-based cache - scope-aware lookup requires scope chain walk
|
|
1715
|
-
// Performance: O(n*m*s) where s = scope depth (typically 2-3), acceptable for correctness
|
|
1716
|
-
for (const reassignment of variableReassignments) {
|
|
1717
|
-
const { variableName, mutationScopePath, valueType, valueName, valueId, callLine, callColumn, operator, literalValue, expressionType, expressionMetadata, file, line, column } = reassignment;
|
|
1718
|
-
// Find target variable node using scope chain resolution (REG-309)
|
|
1719
|
-
const scopePath = mutationScopePath ?? [];
|
|
1720
|
-
const targetVar = this.resolveVariableInScope(variableName, scopePath, file, variableDeclarations);
|
|
1721
|
-
const targetParam = !targetVar ? this.resolveParameterInScope(variableName, scopePath, file, parameters) : null;
|
|
1722
|
-
const targetNodeId = targetVar?.id ?? targetParam?.id;
|
|
1723
|
-
if (!targetNodeId) {
|
|
1724
|
-
// Variable not found - could be external reference
|
|
1725
|
-
continue;
|
|
1726
|
-
}
|
|
1727
|
-
// Resolve source node based on value type
|
|
1728
|
-
let sourceNodeId = null;
|
|
1729
|
-
// LITERAL: Create node inline (NO CONTINUE STATEMENT)
|
|
1730
|
-
if (valueType === 'LITERAL' && valueId) {
|
|
1731
|
-
// Create LITERAL node
|
|
1732
|
-
this._bufferNode({
|
|
1733
|
-
type: 'LITERAL',
|
|
1734
|
-
id: valueId,
|
|
1735
|
-
value: literalValue,
|
|
1736
|
-
file,
|
|
1737
|
-
line,
|
|
1738
|
-
column
|
|
1739
|
-
});
|
|
1740
|
-
sourceNodeId = valueId;
|
|
1741
|
-
}
|
|
1742
|
-
// VARIABLE: Look up existing variable/parameter node using scope chain (REG-309)
|
|
1743
|
-
else if (valueType === 'VARIABLE' && valueName) {
|
|
1744
|
-
const sourceVar = this.resolveVariableInScope(valueName, scopePath, file, variableDeclarations);
|
|
1745
|
-
const sourceParam = !sourceVar ? this.resolveParameterInScope(valueName, scopePath, file, parameters) : null;
|
|
1746
|
-
sourceNodeId = sourceVar?.id ?? sourceParam?.id ?? null;
|
|
1747
|
-
}
|
|
1748
|
-
// CALL_SITE: Look up existing call node
|
|
1749
|
-
else if (valueType === 'CALL_SITE' && callLine && callColumn) {
|
|
1750
|
-
const callSite = callSites.find(cs => cs.line === callLine && cs.column === callColumn && cs.file === file);
|
|
1751
|
-
sourceNodeId = callSite?.id ?? null;
|
|
1752
|
-
}
|
|
1753
|
-
// METHOD_CALL: Look up existing method call node
|
|
1754
|
-
else if (valueType === 'METHOD_CALL' && callLine && callColumn) {
|
|
1755
|
-
const methodCall = methodCalls.find(mc => mc.line === callLine && mc.column === callColumn && mc.file === file);
|
|
1756
|
-
sourceNodeId = methodCall?.id ?? null;
|
|
1757
|
-
}
|
|
1758
|
-
// EXPRESSION: Create node inline (NO CONTINUE STATEMENT)
|
|
1759
|
-
else if (valueType === 'EXPRESSION' && valueId && expressionType) {
|
|
1760
|
-
// Create EXPRESSION node using NodeFactory
|
|
1761
|
-
const expressionNode = NodeFactory.createExpressionFromMetadata(expressionType, file, line, column, {
|
|
1762
|
-
id: valueId, // ID from JSASTAnalyzer
|
|
1763
|
-
object: expressionMetadata?.object,
|
|
1764
|
-
property: expressionMetadata?.property,
|
|
1765
|
-
computed: expressionMetadata?.computed,
|
|
1766
|
-
computedPropertyVar: expressionMetadata?.computedPropertyVar ?? undefined,
|
|
1767
|
-
operator: expressionMetadata?.operator
|
|
1768
|
-
});
|
|
1769
|
-
this._bufferNode(expressionNode);
|
|
1770
|
-
sourceNodeId = valueId;
|
|
1771
|
-
}
|
|
1772
|
-
// Create edges if source found
|
|
1773
|
-
if (sourceNodeId && targetNodeId) {
|
|
1774
|
-
// For compound operators (operator !== '='), LHS reads its own current value
|
|
1775
|
-
// Create READS_FROM self-loop (Linus requirement)
|
|
1776
|
-
if (operator !== '=') {
|
|
1777
|
-
this._bufferEdge({
|
|
1778
|
-
type: 'READS_FROM',
|
|
1779
|
-
src: targetNodeId, // Variable reads from...
|
|
1780
|
-
dst: targetNodeId // ...itself (self-loop)
|
|
1781
|
-
});
|
|
1782
|
-
}
|
|
1783
|
-
// RHS flows into LHS (write side)
|
|
1784
|
-
this._bufferEdge({
|
|
1785
|
-
type: 'FLOWS_INTO',
|
|
1786
|
-
src: sourceNodeId,
|
|
1787
|
-
dst: targetNodeId
|
|
1788
|
-
});
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
}
|
|
1792
|
-
/**
|
|
1793
|
-
* Buffer RETURNS edges connecting return expressions to their containing functions.
|
|
1794
|
-
*
|
|
1795
|
-
* Edge direction: returnExpression --RETURNS--> function
|
|
1796
|
-
*
|
|
1797
|
-
* This enables tracing data flow through function calls:
|
|
1798
|
-
* - Query: "What does formatDate return?"
|
|
1799
|
-
* - Answer: Follow RETURNS edges from function to see all possible return values
|
|
1800
|
-
*/
|
|
1801
|
-
bufferReturnEdges(returnStatements, callSites, methodCalls, variableDeclarations, parameters) {
|
|
1802
|
-
for (const ret of returnStatements) {
|
|
1803
|
-
const { parentFunctionId, returnValueType, file } = ret;
|
|
1804
|
-
// Skip if no value returned (bare return;)
|
|
1805
|
-
if (returnValueType === 'NONE') {
|
|
1806
|
-
continue;
|
|
1807
|
-
}
|
|
1808
|
-
let sourceNodeId = null;
|
|
1809
|
-
switch (returnValueType) {
|
|
1810
|
-
case 'LITERAL':
|
|
1811
|
-
// Direct reference to literal node
|
|
1812
|
-
sourceNodeId = ret.returnValueId ?? null;
|
|
1813
|
-
break;
|
|
1814
|
-
case 'VARIABLE': {
|
|
1815
|
-
// Find variable declaration by name in same file
|
|
1816
|
-
const varName = ret.returnValueName;
|
|
1817
|
-
if (varName) {
|
|
1818
|
-
const sourceVar = variableDeclarations.find(v => v.name === varName && v.file === file);
|
|
1819
|
-
if (sourceVar) {
|
|
1820
|
-
sourceNodeId = sourceVar.id;
|
|
1821
|
-
}
|
|
1822
|
-
else {
|
|
1823
|
-
// Check parameters
|
|
1824
|
-
const sourceParam = parameters.find(p => p.name === varName && p.file === file);
|
|
1825
|
-
if (sourceParam) {
|
|
1826
|
-
sourceNodeId = sourceParam.id;
|
|
1827
|
-
}
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
break;
|
|
1831
|
-
}
|
|
1832
|
-
case 'CALL_SITE': {
|
|
1833
|
-
// Find call site by coordinates
|
|
1834
|
-
const { returnValueLine, returnValueColumn, returnValueCallName } = ret;
|
|
1835
|
-
if (returnValueLine && returnValueColumn) {
|
|
1836
|
-
const callSite = callSites.find(cs => cs.line === returnValueLine &&
|
|
1837
|
-
cs.column === returnValueColumn &&
|
|
1838
|
-
(returnValueCallName ? cs.name === returnValueCallName : true));
|
|
1839
|
-
if (callSite) {
|
|
1840
|
-
sourceNodeId = callSite.id;
|
|
1841
|
-
}
|
|
1842
|
-
}
|
|
1843
|
-
break;
|
|
1844
|
-
}
|
|
1845
|
-
case 'METHOD_CALL': {
|
|
1846
|
-
// Find method call by coordinates and method name
|
|
1847
|
-
const { returnValueLine, returnValueColumn, returnValueCallName } = ret;
|
|
1848
|
-
if (returnValueLine && returnValueColumn) {
|
|
1849
|
-
const methodCall = methodCalls.find(mc => mc.line === returnValueLine &&
|
|
1850
|
-
mc.column === returnValueColumn &&
|
|
1851
|
-
mc.file === file &&
|
|
1852
|
-
(returnValueCallName ? mc.method === returnValueCallName : true));
|
|
1853
|
-
if (methodCall) {
|
|
1854
|
-
sourceNodeId = methodCall.id;
|
|
1855
|
-
}
|
|
1856
|
-
}
|
|
1857
|
-
break;
|
|
1858
|
-
}
|
|
1859
|
-
case 'EXPRESSION': {
|
|
1860
|
-
// REG-276: Create EXPRESSION node and DERIVES_FROM edges for return expressions
|
|
1861
|
-
const { expressionType, returnValueId, returnValueLine, returnValueColumn, operator, object, property, computed, objectSourceName, leftSourceName, rightSourceName, consequentSourceName, alternateSourceName, expressionSourceNames, unaryArgSourceName } = ret;
|
|
1862
|
-
// Skip if no expression ID was generated
|
|
1863
|
-
if (!returnValueId) {
|
|
1864
|
-
break;
|
|
1865
|
-
}
|
|
1866
|
-
// Create EXPRESSION node using NodeFactory
|
|
1867
|
-
const expressionNode = NodeFactory.createExpressionFromMetadata(expressionType || 'Unknown', file, returnValueLine || ret.line, returnValueColumn || ret.column, {
|
|
1868
|
-
id: returnValueId,
|
|
1869
|
-
object,
|
|
1870
|
-
property,
|
|
1871
|
-
computed,
|
|
1872
|
-
operator
|
|
1873
|
-
});
|
|
1874
|
-
this._bufferNode(expressionNode);
|
|
1875
|
-
sourceNodeId = returnValueId;
|
|
1876
|
-
// Buffer DERIVES_FROM edges based on expression type
|
|
1877
|
-
// Helper function to find source variable or parameter
|
|
1878
|
-
const findSource = (name) => {
|
|
1879
|
-
const variable = variableDeclarations.find(v => v.name === name && v.file === file);
|
|
1880
|
-
if (variable)
|
|
1881
|
-
return variable.id;
|
|
1882
|
-
const param = parameters.find(p => p.name === name && p.file === file);
|
|
1883
|
-
if (param)
|
|
1884
|
-
return param.id;
|
|
1885
|
-
return null;
|
|
1886
|
-
};
|
|
1887
|
-
// MemberExpression: derives from the object
|
|
1888
|
-
if (expressionType === 'MemberExpression' && objectSourceName) {
|
|
1889
|
-
const sourceId = findSource(objectSourceName);
|
|
1890
|
-
if (sourceId) {
|
|
1891
|
-
this._bufferEdge({
|
|
1892
|
-
type: 'DERIVES_FROM',
|
|
1893
|
-
src: returnValueId,
|
|
1894
|
-
dst: sourceId
|
|
1895
|
-
});
|
|
1896
|
-
}
|
|
1897
|
-
}
|
|
1898
|
-
// BinaryExpression / LogicalExpression: derives from left and right operands
|
|
1899
|
-
if (expressionType === 'BinaryExpression' || expressionType === 'LogicalExpression') {
|
|
1900
|
-
if (leftSourceName) {
|
|
1901
|
-
const sourceId = findSource(leftSourceName);
|
|
1902
|
-
if (sourceId) {
|
|
1903
|
-
this._bufferEdge({
|
|
1904
|
-
type: 'DERIVES_FROM',
|
|
1905
|
-
src: returnValueId,
|
|
1906
|
-
dst: sourceId
|
|
1907
|
-
});
|
|
1908
|
-
}
|
|
1909
|
-
}
|
|
1910
|
-
if (rightSourceName) {
|
|
1911
|
-
const sourceId = findSource(rightSourceName);
|
|
1912
|
-
if (sourceId) {
|
|
1913
|
-
this._bufferEdge({
|
|
1914
|
-
type: 'DERIVES_FROM',
|
|
1915
|
-
src: returnValueId,
|
|
1916
|
-
dst: sourceId
|
|
1917
|
-
});
|
|
1918
|
-
}
|
|
1919
|
-
}
|
|
1920
|
-
}
|
|
1921
|
-
// ConditionalExpression: derives from consequent and alternate
|
|
1922
|
-
if (expressionType === 'ConditionalExpression') {
|
|
1923
|
-
if (consequentSourceName) {
|
|
1924
|
-
const sourceId = findSource(consequentSourceName);
|
|
1925
|
-
if (sourceId) {
|
|
1926
|
-
this._bufferEdge({
|
|
1927
|
-
type: 'DERIVES_FROM',
|
|
1928
|
-
src: returnValueId,
|
|
1929
|
-
dst: sourceId
|
|
1930
|
-
});
|
|
1931
|
-
}
|
|
1932
|
-
}
|
|
1933
|
-
if (alternateSourceName) {
|
|
1934
|
-
const sourceId = findSource(alternateSourceName);
|
|
1935
|
-
if (sourceId) {
|
|
1936
|
-
this._bufferEdge({
|
|
1937
|
-
type: 'DERIVES_FROM',
|
|
1938
|
-
src: returnValueId,
|
|
1939
|
-
dst: sourceId
|
|
1940
|
-
});
|
|
1941
|
-
}
|
|
1942
|
-
}
|
|
1943
|
-
}
|
|
1944
|
-
// UnaryExpression: derives from the argument
|
|
1945
|
-
if (expressionType === 'UnaryExpression' && unaryArgSourceName) {
|
|
1946
|
-
const sourceId = findSource(unaryArgSourceName);
|
|
1947
|
-
if (sourceId) {
|
|
1948
|
-
this._bufferEdge({
|
|
1949
|
-
type: 'DERIVES_FROM',
|
|
1950
|
-
src: returnValueId,
|
|
1951
|
-
dst: sourceId
|
|
1952
|
-
});
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
// TemplateLiteral: derives from all embedded expressions
|
|
1956
|
-
if (expressionType === 'TemplateLiteral' && expressionSourceNames && expressionSourceNames.length > 0) {
|
|
1957
|
-
for (const sourceName of expressionSourceNames) {
|
|
1958
|
-
const sourceId = findSource(sourceName);
|
|
1959
|
-
if (sourceId) {
|
|
1960
|
-
this._bufferEdge({
|
|
1961
|
-
type: 'DERIVES_FROM',
|
|
1962
|
-
src: returnValueId,
|
|
1963
|
-
dst: sourceId
|
|
1964
|
-
});
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
break;
|
|
1969
|
-
}
|
|
1970
|
-
}
|
|
1971
|
-
// Create RETURNS edge if we found a source node
|
|
1972
|
-
if (sourceNodeId && parentFunctionId) {
|
|
1973
|
-
this._bufferEdge({
|
|
1974
|
-
type: 'RETURNS',
|
|
1975
|
-
src: sourceNodeId,
|
|
1976
|
-
dst: parentFunctionId
|
|
1977
|
-
});
|
|
1978
|
-
}
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
/**
|
|
1982
|
-
* Buffer UPDATE_EXPRESSION nodes and edges for increment/decrement operations.
|
|
1983
|
-
*
|
|
1984
|
-
* Handles two target types:
|
|
1985
|
-
* - IDENTIFIER: Simple variable (i++, --count)
|
|
1986
|
-
* - MEMBER_EXPRESSION: Object property (obj.prop++, arr[i]++, this.count++)
|
|
1987
|
-
*
|
|
1988
|
-
* Creates:
|
|
1989
|
-
* - UPDATE_EXPRESSION node with operator and target metadata
|
|
1990
|
-
* - MODIFIES edge: UPDATE_EXPRESSION -> target (VARIABLE, PARAMETER, or CLASS)
|
|
1991
|
-
* - READS_FROM self-loop: target -> target (reads current value before update)
|
|
1992
|
-
* - CONTAINS edge: SCOPE -> UPDATE_EXPRESSION
|
|
1993
|
-
*
|
|
1994
|
-
* REG-288: Initial implementation for IDENTIFIER targets
|
|
1995
|
-
* REG-312: Extended for MEMBER_EXPRESSION targets
|
|
355
|
+
* Collect unique import.meta property names from property accesses (REG-300).
|
|
356
|
+
* Returns deduplicated array of property names (e.g., ["url", "env"]).
|
|
1996
357
|
*/
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
const
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
}
|
|
2003
|
-
const paramLookup = new Map();
|
|
2004
|
-
for (const p of parameters) {
|
|
2005
|
-
paramLookup.set(`${p.file}:${p.name}`, p);
|
|
2006
|
-
}
|
|
2007
|
-
for (const update of updateExpressions) {
|
|
2008
|
-
if (update.targetType === 'IDENTIFIER') {
|
|
2009
|
-
// REG-288: Simple identifier (i++, --count)
|
|
2010
|
-
this.bufferIdentifierUpdate(update, varLookup, paramLookup);
|
|
2011
|
-
}
|
|
2012
|
-
else if (update.targetType === 'MEMBER_EXPRESSION') {
|
|
2013
|
-
// REG-312: Member expression (obj.prop++, arr[i]++)
|
|
2014
|
-
this.bufferMemberExpressionUpdate(update, varLookup, paramLookup, classDeclarations);
|
|
358
|
+
collectImportMetaProperties(propertyAccesses) {
|
|
359
|
+
const metaProps = new Set();
|
|
360
|
+
for (const propAccess of propertyAccesses) {
|
|
361
|
+
if (propAccess.objectName === 'import.meta') {
|
|
362
|
+
metaProps.add(propAccess.propertyName);
|
|
2015
363
|
}
|
|
2016
364
|
}
|
|
365
|
+
return [...metaProps];
|
|
2017
366
|
}
|
|
2018
367
|
/**
|
|
2019
|
-
*
|
|
2020
|
-
*
|
|
368
|
+
* Update MODULE node with import.meta metadata (REG-300).
|
|
369
|
+
* Reads existing MODULE node, adds importMeta property list, re-adds it.
|
|
2021
370
|
*/
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
if (!variableName)
|
|
371
|
+
async updateModuleImportMetaMetadata(module, graph, importMetaProps) {
|
|
372
|
+
if (importMetaProps.length === 0)
|
|
2025
373
|
return;
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
const targetParam = !targetVar ? paramLookup.get(`${file}:${variableName}`) : null;
|
|
2029
|
-
const targetNodeId = targetVar?.id ?? targetParam?.id;
|
|
2030
|
-
if (!targetNodeId) {
|
|
2031
|
-
// Variable not found - could be module-level or external reference
|
|
374
|
+
const existingNode = await graph.getNode(module.id);
|
|
375
|
+
if (!existingNode)
|
|
2032
376
|
return;
|
|
2033
|
-
|
|
2034
|
-
//
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
id: updateId,
|
|
2039
|
-
name: `${prefix ? operator : ''}${variableName}${prefix ? '' : operator}`,
|
|
2040
|
-
targetType: 'IDENTIFIER',
|
|
2041
|
-
operator,
|
|
2042
|
-
prefix,
|
|
2043
|
-
variableName,
|
|
2044
|
-
file,
|
|
2045
|
-
line,
|
|
2046
|
-
column
|
|
2047
|
-
});
|
|
2048
|
-
// Create READS_FROM self-loop
|
|
2049
|
-
this._bufferEdge({
|
|
2050
|
-
type: 'READS_FROM',
|
|
2051
|
-
src: targetNodeId,
|
|
2052
|
-
dst: targetNodeId
|
|
377
|
+
// Re-add with importMeta at top level — addNode is upsert in RFDB,
|
|
378
|
+
// and backend spreads metadata fields to top level on read
|
|
379
|
+
await graph.addNode({
|
|
380
|
+
...existingNode,
|
|
381
|
+
importMeta: importMetaProps
|
|
2053
382
|
});
|
|
2054
|
-
// Create MODIFIES edge
|
|
2055
|
-
this._bufferEdge({
|
|
2056
|
-
type: 'MODIFIES',
|
|
2057
|
-
src: updateId,
|
|
2058
|
-
dst: targetNodeId
|
|
2059
|
-
});
|
|
2060
|
-
// Create CONTAINS edge
|
|
2061
|
-
if (parentScopeId) {
|
|
2062
|
-
this._bufferEdge({
|
|
2063
|
-
type: 'CONTAINS',
|
|
2064
|
-
src: parentScopeId,
|
|
2065
|
-
dst: updateId
|
|
2066
|
-
});
|
|
2067
|
-
}
|
|
2068
383
|
}
|
|
2069
384
|
/**
|
|
2070
|
-
*
|
|
2071
|
-
*
|
|
2072
|
-
*
|
|
2073
|
-
* Creates:
|
|
2074
|
-
* - UPDATE_EXPRESSION node with member expression metadata
|
|
2075
|
-
* - MODIFIES edge: UPDATE_EXPRESSION -> VARIABLE(object) or CLASS (for this.prop++)
|
|
2076
|
-
* - READS_FROM self-loop: VARIABLE(object) -> VARIABLE(object)
|
|
2077
|
-
* - CONTAINS edge: SCOPE -> UPDATE_EXPRESSION
|
|
385
|
+
* Update MODULE node with hasTopLevelAwait metadata (REG-297).
|
|
386
|
+
* Reads existing MODULE node, adds hasTopLevelAwait flag, re-adds it.
|
|
2078
387
|
*/
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
if (!objectName || !propertyName)
|
|
388
|
+
async updateModuleTopLevelAwaitMetadata(module, graph, hasTopLevelAwait) {
|
|
389
|
+
if (!hasTopLevelAwait)
|
|
2082
390
|
return;
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
if (objectName !== 'this') {
|
|
2086
|
-
// Regular object: obj.prop++, arr[i]++
|
|
2087
|
-
const targetVar = varLookup.get(`${file}:${objectName}`);
|
|
2088
|
-
const targetParam = !targetVar ? paramLookup.get(`${file}:${objectName}`) : null;
|
|
2089
|
-
objectNodeId = targetVar?.id ?? targetParam?.id ?? null;
|
|
2090
|
-
}
|
|
2091
|
-
else {
|
|
2092
|
-
// this.prop++ - follow REG-152 pattern from bufferObjectMutationEdges
|
|
2093
|
-
if (!enclosingClassName)
|
|
2094
|
-
return;
|
|
2095
|
-
const fileBasename = basename(file);
|
|
2096
|
-
const classDecl = classDeclarations.find(c => c.name === enclosingClassName && c.file === fileBasename);
|
|
2097
|
-
objectNodeId = classDecl?.id ?? null;
|
|
2098
|
-
}
|
|
2099
|
-
if (!objectNodeId) {
|
|
2100
|
-
// Object not found - external reference or scope issue
|
|
391
|
+
const existingNode = await graph.getNode(module.id);
|
|
392
|
+
if (!existingNode)
|
|
2101
393
|
return;
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
// Display name: "obj.prop++" or "this.count++" or "arr[i]++"
|
|
2106
|
-
const displayName = (() => {
|
|
2107
|
-
const opStr = prefix ? operator : '';
|
|
2108
|
-
const postOpStr = prefix ? '' : operator;
|
|
2109
|
-
if (objectName === 'this') {
|
|
2110
|
-
return `${opStr}this.${propertyName}${postOpStr}`;
|
|
2111
|
-
}
|
|
2112
|
-
if (mutationType === 'computed') {
|
|
2113
|
-
const computedPart = computedPropertyVar || '?';
|
|
2114
|
-
return `${opStr}${objectName}[${computedPart}]${postOpStr}`;
|
|
2115
|
-
}
|
|
2116
|
-
return `${opStr}${objectName}.${propertyName}${postOpStr}`;
|
|
2117
|
-
})();
|
|
2118
|
-
this._bufferNode({
|
|
2119
|
-
type: 'UPDATE_EXPRESSION',
|
|
2120
|
-
id: updateId,
|
|
2121
|
-
name: displayName,
|
|
2122
|
-
targetType: 'MEMBER_EXPRESSION',
|
|
2123
|
-
operator,
|
|
2124
|
-
prefix,
|
|
2125
|
-
objectName,
|
|
2126
|
-
propertyName,
|
|
2127
|
-
mutationType,
|
|
2128
|
-
computedPropertyVar,
|
|
2129
|
-
enclosingClassName,
|
|
2130
|
-
file,
|
|
2131
|
-
line,
|
|
2132
|
-
column
|
|
2133
|
-
});
|
|
2134
|
-
// Create READS_FROM self-loop (object reads from itself)
|
|
2135
|
-
this._bufferEdge({
|
|
2136
|
-
type: 'READS_FROM',
|
|
2137
|
-
src: objectNodeId,
|
|
2138
|
-
dst: objectNodeId
|
|
394
|
+
await graph.addNode({
|
|
395
|
+
...existingNode,
|
|
396
|
+
hasTopLevelAwait: true
|
|
2139
397
|
});
|
|
2140
|
-
// Create MODIFIES edge (UPDATE_EXPRESSION modifies object)
|
|
2141
|
-
this._bufferEdge({
|
|
2142
|
-
type: 'MODIFIES',
|
|
2143
|
-
src: updateId,
|
|
2144
|
-
dst: objectNodeId
|
|
2145
|
-
});
|
|
2146
|
-
// Create CONTAINS edge
|
|
2147
|
-
if (parentScopeId) {
|
|
2148
|
-
this._bufferEdge({
|
|
2149
|
-
type: 'CONTAINS',
|
|
2150
|
-
src: parentScopeId,
|
|
2151
|
-
dst: updateId
|
|
2152
|
-
});
|
|
2153
|
-
}
|
|
2154
|
-
}
|
|
2155
|
-
/**
|
|
2156
|
-
* Buffer RESOLVES_TO edges for Promise resolution data flow (REG-334).
|
|
2157
|
-
*
|
|
2158
|
-
* Links resolve/reject CALL nodes to their parent Promise CONSTRUCTOR_CALL.
|
|
2159
|
-
* This enables traceValues to follow Promise data flow:
|
|
2160
|
-
*
|
|
2161
|
-
* Example:
|
|
2162
|
-
* ```
|
|
2163
|
-
* const result = new Promise((resolve) => {
|
|
2164
|
-
* resolve(42); // CALL[resolve] --RESOLVES_TO--> CONSTRUCTOR_CALL[Promise]
|
|
2165
|
-
* });
|
|
2166
|
-
* ```
|
|
2167
|
-
*
|
|
2168
|
-
* The edge direction (CALL -> CONSTRUCTOR_CALL) matches data flow semantics:
|
|
2169
|
-
* data flows FROM resolve(value) TO the Promise result.
|
|
2170
|
-
*/
|
|
2171
|
-
bufferPromiseResolutionEdges(promiseResolutions) {
|
|
2172
|
-
for (const resolution of promiseResolutions) {
|
|
2173
|
-
this._bufferEdge({
|
|
2174
|
-
type: 'RESOLVES_TO',
|
|
2175
|
-
src: resolution.callId,
|
|
2176
|
-
dst: resolution.constructorCallId,
|
|
2177
|
-
metadata: {
|
|
2178
|
-
isReject: resolution.isReject
|
|
2179
|
-
}
|
|
2180
|
-
});
|
|
2181
|
-
}
|
|
2182
|
-
}
|
|
2183
|
-
/**
|
|
2184
|
-
* Buffer OBJECT_LITERAL nodes to the graph.
|
|
2185
|
-
* These are object literals passed as function arguments or nested in other literals.
|
|
2186
|
-
*/
|
|
2187
|
-
bufferObjectLiteralNodes(objectLiterals) {
|
|
2188
|
-
for (const obj of objectLiterals) {
|
|
2189
|
-
this._bufferNode({
|
|
2190
|
-
id: obj.id,
|
|
2191
|
-
type: obj.type,
|
|
2192
|
-
name: '<object>',
|
|
2193
|
-
file: obj.file,
|
|
2194
|
-
line: obj.line,
|
|
2195
|
-
column: obj.column,
|
|
2196
|
-
parentCallId: obj.parentCallId,
|
|
2197
|
-
argIndex: obj.argIndex
|
|
2198
|
-
});
|
|
2199
|
-
}
|
|
2200
|
-
}
|
|
2201
|
-
/**
|
|
2202
|
-
* Buffer ARRAY_LITERAL nodes to the graph.
|
|
2203
|
-
* These are array literals passed as function arguments or nested in other literals.
|
|
2204
|
-
*/
|
|
2205
|
-
bufferArrayLiteralNodes(arrayLiterals) {
|
|
2206
|
-
for (const arr of arrayLiterals) {
|
|
2207
|
-
this._bufferNode({
|
|
2208
|
-
id: arr.id,
|
|
2209
|
-
type: arr.type,
|
|
2210
|
-
name: '<array>',
|
|
2211
|
-
file: arr.file,
|
|
2212
|
-
line: arr.line,
|
|
2213
|
-
column: arr.column,
|
|
2214
|
-
parentCallId: arr.parentCallId,
|
|
2215
|
-
argIndex: arr.argIndex
|
|
2216
|
-
});
|
|
2217
|
-
}
|
|
2218
|
-
}
|
|
2219
|
-
/**
|
|
2220
|
-
* Buffer HAS_PROPERTY edges connecting OBJECT_LITERAL nodes to their property values.
|
|
2221
|
-
* Creates edges from object literal to its property value nodes (LITERAL, nested OBJECT_LITERAL, ARRAY_LITERAL, etc.)
|
|
2222
|
-
*
|
|
2223
|
-
* REG-329: Adds scope-aware variable resolution for VARIABLE property values.
|
|
2224
|
-
* Uses the same resolveVariableInScope infrastructure as mutation handlers.
|
|
2225
|
-
*/
|
|
2226
|
-
bufferObjectPropertyEdges(objectProperties, variableDeclarations, parameters) {
|
|
2227
|
-
for (const prop of objectProperties) {
|
|
2228
|
-
// REG-329: Handle VARIABLE value types with scope resolution
|
|
2229
|
-
if (prop.valueType === 'VARIABLE' && prop.valueName) {
|
|
2230
|
-
const scopePath = prop.valueScopePath ?? [];
|
|
2231
|
-
const file = prop.file;
|
|
2232
|
-
// Resolve variable using scope chain
|
|
2233
|
-
const resolvedVar = this.resolveVariableInScope(prop.valueName, scopePath, file, variableDeclarations);
|
|
2234
|
-
const resolvedParam = !resolvedVar
|
|
2235
|
-
? this.resolveParameterInScope(prop.valueName, scopePath, file, parameters)
|
|
2236
|
-
: null;
|
|
2237
|
-
const resolvedNodeId = resolvedVar?.id ?? resolvedParam?.semanticId ?? resolvedParam?.id;
|
|
2238
|
-
if (resolvedNodeId) {
|
|
2239
|
-
this._bufferEdge({
|
|
2240
|
-
type: 'HAS_PROPERTY',
|
|
2241
|
-
src: prop.objectId,
|
|
2242
|
-
dst: resolvedNodeId,
|
|
2243
|
-
propertyName: prop.propertyName
|
|
2244
|
-
});
|
|
2245
|
-
}
|
|
2246
|
-
continue;
|
|
2247
|
-
}
|
|
2248
|
-
// Existing logic for non-VARIABLE types
|
|
2249
|
-
if (prop.valueNodeId) {
|
|
2250
|
-
this._bufferEdge({
|
|
2251
|
-
type: 'HAS_PROPERTY',
|
|
2252
|
-
src: prop.objectId,
|
|
2253
|
-
dst: prop.valueNodeId,
|
|
2254
|
-
propertyName: prop.propertyName
|
|
2255
|
-
});
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
398
|
}
|
|
2259
399
|
/**
|
|
2260
400
|
* Handle CLASS ASSIGNED_FROM edges asynchronously (needs graph queries)
|
|
@@ -2286,3 +426,4 @@ export class GraphBuilder {
|
|
|
2286
426
|
return edgesCreated;
|
|
2287
427
|
}
|
|
2288
428
|
}
|
|
429
|
+
//# sourceMappingURL=GraphBuilder.js.map
|