@grafema/core 0.2.5-beta → 0.2.7
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 +34 -151
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +173 -741
- package/dist/Orchestrator.js.map +1 -1
- 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 +94 -0
- package/dist/PhaseRunner.d.ts.map +1 -0
- package/dist/PhaseRunner.js +332 -0
- package/dist/PhaseRunner.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +51 -1
- package/dist/config/ConfigLoader.d.ts.map +1 -1
- package/dist/config/ConfigLoader.js +121 -1
- package/dist/config/ConfigLoader.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/core/ASTWorker.d.ts +2 -0
- package/dist/core/ASTWorker.d.ts.map +1 -1
- package/dist/core/ASTWorker.js +6 -2
- package/dist/core/ASTWorker.js.map +1 -1
- 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/GraphFreshnessChecker.d.ts +1 -1
- package/dist/core/GraphFreshnessChecker.d.ts.map +1 -1
- package/dist/core/GraphFreshnessChecker.js +7 -5
- package/dist/core/GraphFreshnessChecker.js.map +1 -1
- package/dist/core/GuaranteeManager.d.ts +13 -0
- package/dist/core/GuaranteeManager.d.ts.map +1 -1
- package/dist/core/GuaranteeManager.js +63 -2
- package/dist/core/GuaranteeManager.js.map +1 -1
- package/dist/core/IncrementalReanalyzer.d.ts.map +1 -1
- package/dist/core/IncrementalReanalyzer.js +6 -3
- package/dist/core/IncrementalReanalyzer.js.map +1 -1
- package/dist/core/NodeFactory.d.ts +81 -415
- package/dist/core/NodeFactory.d.ts.map +1 -1
- package/dist/core/NodeFactory.js +139 -336
- package/dist/core/NodeFactory.js.map +1 -1
- 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 +24 -0
- package/dist/core/ScopeTracker.js.map +1 -1
- package/dist/core/SemanticId.d.ts +69 -0
- package/dist/core/SemanticId.d.ts.map +1 -1
- package/dist/core/SemanticId.js +134 -0
- package/dist/core/SemanticId.js.map +1 -1
- 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/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/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/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/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/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/NodeKind.d.ts +1 -0
- package/dist/core/nodes/NodeKind.d.ts.map +1 -1
- package/dist/core/nodes/NodeKind.js +1 -0
- package/dist/core/nodes/NodeKind.js.map +1 -1
- 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/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/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 +21 -3
- package/dist/core/nodes/TypeNode.js.map +1 -1
- 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/index.d.ts +19 -0
- package/dist/core/nodes/index.d.ts.map +1 -1
- package/dist/core/nodes/index.js +26 -0
- package/dist/core/nodes/index.js.map +1 -1
- package/dist/index.d.ts +33 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -3
- package/dist/index.js.map +1 -1
- 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/analysis/DatabaseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.js +18 -15
- package/dist/plugins/analysis/DatabaseAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.js +27 -26
- package/dist/plugins/analysis/ExpressAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressResponseAnalyzer.js +5 -3
- package/dist/plugins/analysis/ExpressResponseAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js +36 -39
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.js +23 -39
- package/dist/plugins/analysis/FetchAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -1
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +3 -2
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.js.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts +23 -85
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +351 -1887
- package/dist/plugins/analysis/JSASTAnalyzer.js.map +1 -1
- 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 +24 -915
- package/dist/plugins/analysis/ReactAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/RustAnalyzer.js +31 -66
- package/dist/plugins/analysis/RustAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.js +13 -6
- package/dist/plugins/analysis/SQLiteAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ServiceLayerAnalyzer.js +10 -7
- package/dist/plugins/analysis/ServiceLayerAnalyzer.js.map +1 -1
- 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 +13 -18
- package/dist/plugins/analysis/SocketIOAnalyzer.js.map +1 -1
- package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SystemDbAnalyzer.js +8 -5
- package/dist/plugins/analysis/SystemDbAnalyzer.js.map +1 -1
- 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/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 -261
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +251 -2494
- package/dist/plugins/analysis/ast/GraphBuilder.js.map +1 -1
- 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 +61 -1
- package/dist/plugins/analysis/ast/IdGenerator.js.map +1 -1
- 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 +57 -6
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts +5 -4
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/utils/createParameterNodes.js +94 -13
- package/dist/plugins/analysis/ast/utils/createParameterNodes.js.map +1 -1
- 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 +2 -0
- package/dist/plugins/analysis/ast/utils/index.js.map +1 -1
- 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 +15 -142
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +304 -937
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +26 -11
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.js.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +21 -6
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js.map +1 -1
- 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 +9 -1
- package/dist/plugins/analysis/ast/visitors/PropertyAccessVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/PropertyAccessVisitor.js +51 -3
- package/dist/plugins/analysis/ast/visitors/PropertyAccessVisitor.js.map +1 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +20 -0
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +188 -12
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +6 -4
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js.map +1 -1
- 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/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/MonorepoServiceDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/MonorepoServiceDiscovery.js +6 -13
- package/dist/plugins/discovery/MonorepoServiceDiscovery.js.map +1 -1
- package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
- package/dist/plugins/enrichment/AliasTracker.js +3 -1
- package/dist/plugins/enrichment/AliasTracker.js.map +1 -1
- package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts.map +1 -1
- package/dist/plugins/enrichment/ArgumentParameterLinker.js +3 -1
- package/dist/plugins/enrichment/ArgumentParameterLinker.js.map +1 -1
- 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 +3 -1
- package/dist/plugins/enrichment/ClosureCaptureEnricher.js.map +1 -1
- 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.map +1 -1
- package/dist/plugins/enrichment/ExpressHandlerLinker.js +3 -1
- package/dist/plugins/enrichment/ExpressHandlerLinker.js.map +1 -1
- package/dist/plugins/enrichment/ExternalCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/ExternalCallResolver.js +5 -8
- package/dist/plugins/enrichment/ExternalCallResolver.js.map +1 -1
- package/dist/plugins/enrichment/FunctionCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/FunctionCallResolver.js +6 -9
- package/dist/plugins/enrichment/FunctionCallResolver.js.map +1 -1
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js +3 -1
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js.map +1 -1
- package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
- package/dist/plugins/enrichment/ImportExportLinker.js +5 -3
- package/dist/plugins/enrichment/ImportExportLinker.js.map +1 -1
- package/dist/plugins/enrichment/InstanceOfResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/InstanceOfResolver.js +3 -1
- package/dist/plugins/enrichment/InstanceOfResolver.js.map +1 -1
- package/dist/plugins/enrichment/MethodCallResolver.d.ts +17 -68
- package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MethodCallResolver.js +42 -517
- package/dist/plugins/enrichment/MethodCallResolver.js.map +1 -1
- package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MountPointResolver.js +9 -2
- package/dist/plugins/enrichment/MountPointResolver.js.map +1 -1
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.js +7 -16
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.js.map +1 -1
- package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -1
- package/dist/plugins/enrichment/PrefixEvaluator.js +6 -2
- package/dist/plugins/enrichment/PrefixEvaluator.js.map +1 -1
- package/dist/plugins/enrichment/RejectionPropagationEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/RejectionPropagationEnricher.js +3 -1
- package/dist/plugins/enrichment/RejectionPropagationEnricher.js.map +1 -1
- package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/RustFFIEnricher.js +3 -1
- package/dist/plugins/enrichment/RustFFIEnricher.js.map +1 -1
- 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.map +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +3 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js.map +1 -1
- 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.map +1 -1
- package/dist/plugins/indexing/IncrementalModuleIndexer.js +2 -8
- package/dist/plugins/indexing/IncrementalModuleIndexer.js.map +1 -1
- package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/JSModuleIndexer.js +13 -20
- package/dist/plugins/indexing/JSModuleIndexer.js.map +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.js +4 -8
- package/dist/plugins/indexing/RustModuleIndexer.js.map +1 -1
- 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/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/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/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.map +1 -1
- package/dist/queries/findCallsInFunction.js +10 -2
- package/dist/queries/findCallsInFunction.js.map +1 -1
- package/dist/queries/findContainingFunction.d.ts +3 -2
- package/dist/queries/findContainingFunction.d.ts.map +1 -1
- package/dist/queries/findContainingFunction.js +13 -3
- package/dist/queries/findContainingFunction.js.map +1 -1
- package/dist/queries/index.d.ts +2 -0
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/index.js +1 -0
- package/dist/queries/index.js.map +1 -1
- 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/storage/backends/RFDBServerBackend.d.ts +35 -6
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +102 -70
- package/dist/storage/backends/RFDBServerBackend.js.map +1 -1
- package/dist/utils/findRfdbBinary.d.ts +3 -2
- package/dist/utils/findRfdbBinary.d.ts.map +1 -1
- package/dist/utils/findRfdbBinary.js +22 -7
- package/dist/utils/findRfdbBinary.js.map +1 -1
- package/dist/utils/moduleResolution.d.ts.map +1 -1
- package/dist/utils/moduleResolution.js +26 -1
- package/dist/utils/moduleResolution.js.map +1 -1
- 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/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 +3 -3
- package/src/DiscoveryManager.ts +279 -0
- package/src/GraphInitializer.ts +131 -0
- package/src/GuaranteeChecker.ts +90 -0
- package/src/Orchestrator.ts +222 -963
- package/src/OrchestratorTypes.ts +122 -0
- package/src/ParallelAnalysisRunner.ts +188 -0
- package/src/PhaseRunner.ts +450 -0
- package/src/config/ConfigLoader.ts +176 -2
- package/src/config/index.ts +2 -0
- package/src/core/ASTWorker.ts +9 -2
- package/src/core/FileOverview.ts +374 -0
- package/src/core/GraphFreshnessChecker.ts +7 -5
- package/src/core/GuaranteeManager.ts +70 -2
- package/src/core/IncrementalReanalyzer.ts +6 -3
- package/src/core/NodeFactory.ts +173 -652
- package/src/core/ResourceRegistry.ts +39 -0
- package/src/core/ScopeTracker.ts +23 -0
- package/src/core/SemanticId.ts +183 -0
- 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 +1 -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 +46 -3
- package/src/core/nodes/TypeParameterNode.ts +91 -0
- package/src/core/nodes/index.ts +57 -0
- package/src/index.ts +60 -4
- package/src/plugins/InfraAnalyzer.ts +208 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +27 -17
- package/src/plugins/analysis/ExpressAnalyzer.ts +51 -38
- package/src/plugins/analysis/ExpressResponseAnalyzer.ts +15 -12
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +56 -56
- package/src/plugins/analysis/FetchAnalyzer.ts +42 -52
- package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +3 -2
- package/src/plugins/analysis/JSASTAnalyzer.ts +391 -2304
- package/src/plugins/analysis/NestJSRouteAnalyzer.ts +241 -0
- package/src/plugins/analysis/ReactAnalyzer.ts +33 -1085
- package/src/plugins/analysis/RustAnalyzer.ts +112 -116
- package/src/plugins/analysis/SQLiteAnalyzer.ts +23 -9
- package/src/plugins/analysis/ServiceLayerAnalyzer.ts +32 -10
- package/src/plugins/analysis/SocketAnalyzer.ts +601 -0
- package/src/plugins/analysis/SocketIOAnalyzer.ts +25 -34
- package/src/plugins/analysis/SystemDbAnalyzer.ts +15 -12
- package/src/plugins/analysis/ast/CollisionResolver.ts +137 -0
- package/src/plugins/analysis/ast/FunctionBodyContext.ts +291 -0
- package/src/plugins/analysis/ast/GraphBuilder.ts +274 -3180
- 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 +68 -9
- package/src/plugins/analysis/ast/utils/createParameterNodes.ts +118 -13
- 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/ArgumentExtractor.ts +307 -0
- package/src/plugins/analysis/ast/visitors/ArrayElementExtractor.ts +172 -0
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +425 -1374
- package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +43 -12
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +39 -8
- 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 +69 -4
- package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +232 -13
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +8 -11
- 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/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/MonorepoServiceDiscovery.ts +6 -14
- package/src/plugins/enrichment/AliasTracker.ts +3 -1
- package/src/plugins/enrichment/ArgumentParameterLinker.ts +3 -1
- package/src/plugins/enrichment/CallbackCallResolver.ts +398 -0
- package/src/plugins/enrichment/ClosureCaptureEnricher.ts +3 -1
- package/src/plugins/enrichment/ConfigRoutingMapBuilder.ts +67 -0
- package/src/plugins/enrichment/ExpressHandlerLinker.ts +3 -1
- package/src/plugins/enrichment/ExternalCallResolver.ts +5 -8
- package/src/plugins/enrichment/FunctionCallResolver.ts +6 -9
- package/src/plugins/enrichment/HTTPConnectionEnricher.ts +3 -1
- package/src/plugins/enrichment/ImportExportLinker.ts +5 -3
- package/src/plugins/enrichment/InstanceOfResolver.ts +3 -1
- package/src/plugins/enrichment/MethodCallResolver.ts +48 -659
- package/src/plugins/enrichment/MountPointResolver.ts +9 -2
- package/src/plugins/enrichment/NodejsBuiltinsResolver.ts +13 -18
- package/src/plugins/enrichment/PrefixEvaluator.ts +6 -2
- package/src/plugins/enrichment/RejectionPropagationEnricher.ts +3 -1
- package/src/plugins/enrichment/RustFFIEnricher.ts +3 -1
- package/src/plugins/enrichment/ServiceConnectionEnricher.ts +472 -0
- package/src/plugins/enrichment/SocketConnectionEnricher.ts +228 -0
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +3 -1
- 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 +5 -10
- package/src/plugins/indexing/JSModuleIndexer.ts +17 -21
- package/src/plugins/indexing/RustModuleIndexer.ts +14 -13
- package/src/plugins/validation/AwaitInLoopValidator.ts +91 -0
- package/src/plugins/validation/PackageCoverageValidator.ts +181 -0
- package/src/plugins/validation/UnconnectedRouteValidator.ts +93 -0
- package/src/queries/NodeContext.ts +277 -0
- package/src/queries/findCallsInFunction.ts +11 -2
- package/src/queries/findContainingFunction.ts +14 -3
- package/src/queries/index.ts +13 -0
- package/src/resources/InfraResourceMapImpl.ts +119 -0
- package/src/resources/RoutingMapImpl.ts +133 -0
- package/src/storage/backends/RFDBServerBackend.ts +106 -77
- package/src/utils/findRfdbBinary.ts +22 -7
- package/src/utils/moduleResolution.ts +28 -1
- package/src/utils/resolveNodeFile.ts +18 -0
- package/src/version.ts +28 -0
|
@@ -8,1065 +8,70 @@
|
|
|
8
8
|
* - Constructor calls: new Foo(), new Function()
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { Node, CallExpression, NewExpression, Identifier, MemberExpression
|
|
11
|
+
import type { Node, CallExpression, NewExpression, Identifier, MemberExpression } from '@babel/types';
|
|
12
12
|
import type { NodePath } from '@babel/traverse';
|
|
13
13
|
import { ASTVisitor, type VisitorModule, type VisitorCollections, type VisitorHandlers, type CounterRef } from './ASTVisitor.js';
|
|
14
|
-
import { ExpressionEvaluator } from '../ExpressionEvaluator.js';
|
|
15
|
-
import type { ArrayMutationInfo, ArrayMutationArgument, ObjectMutationInfo, ObjectMutationValue, GrafemaIgnoreAnnotation } from '../types.js';
|
|
16
14
|
import type { ScopeTracker } from '../../../../core/ScopeTracker.js';
|
|
17
|
-
import {
|
|
15
|
+
import type { ContentHashHints } from '../../../../core/SemanticId.js';
|
|
16
|
+
import { MutationDetector } from './MutationDetector.js';
|
|
18
17
|
import { IdGenerator } from '../IdGenerator.js';
|
|
19
|
-
import {
|
|
20
|
-
import { ObjectLiteralNode } from '../../../../core/nodes/ObjectLiteralNode.js';
|
|
21
|
-
import { ArrayLiteralNode } from '../../../../core/nodes/ArrayLiteralNode.js';
|
|
18
|
+
import { ExpressionEvaluator } from '../ExpressionEvaluator.js';
|
|
22
19
|
import { getLine, getColumn } from '../utils/location.js';
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*/
|
|
36
|
-
function checkNodeComments(node: Node): GrafemaIgnoreAnnotation | null {
|
|
37
|
-
const comments = (node as { leadingComments?: Comment[] }).leadingComments;
|
|
38
|
-
if (!comments || comments.length === 0) return null;
|
|
39
|
-
|
|
40
|
-
// Check comments from last to first (closest to node wins)
|
|
41
|
-
for (let i = comments.length - 1; i >= 0; i--) {
|
|
42
|
-
const comment = comments[i];
|
|
43
|
-
const text = comment.value.trim();
|
|
44
|
-
const match = text.match(GRAFEMA_IGNORE_PATTERN);
|
|
45
|
-
if (match) {
|
|
46
|
-
return {
|
|
47
|
-
code: match[1],
|
|
48
|
-
reason: match[2]?.trim(),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Check if a call has a grafema-ignore comment for suppressing strict mode errors.
|
|
58
|
-
* Babel attaches leading comments to statements (VariableDeclaration, ExpressionStatement),
|
|
59
|
-
* not to nested CallExpression nodes. So we check:
|
|
60
|
-
* 1. The call node itself (rare, but possible for standalone calls)
|
|
61
|
-
* 2. The parent statement (VariableDeclaration, ExpressionStatement, etc.)
|
|
62
|
-
*
|
|
63
|
-
* @param path - Babel NodePath for the CallExpression
|
|
64
|
-
* @returns GrafemaIgnoreAnnotation if found, null otherwise
|
|
65
|
-
*/
|
|
66
|
-
function getGrafemaIgnore(path: NodePath): GrafemaIgnoreAnnotation | null {
|
|
67
|
-
// First check the call node itself
|
|
68
|
-
const callResult = checkNodeComments(path.node);
|
|
69
|
-
if (callResult) return callResult;
|
|
70
|
-
|
|
71
|
-
// Then check parent statement (where Babel typically attaches comments)
|
|
72
|
-
const statementPath = path.getStatementParent();
|
|
73
|
-
if (statementPath) {
|
|
74
|
-
return checkNodeComments(statementPath.node);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Object literal info for OBJECT_LITERAL nodes
|
|
82
|
-
*/
|
|
83
|
-
interface ObjectLiteralInfo {
|
|
84
|
-
id: string;
|
|
85
|
-
type: 'OBJECT_LITERAL';
|
|
86
|
-
file: string;
|
|
87
|
-
line: number;
|
|
88
|
-
column: number;
|
|
89
|
-
parentCallId?: string;
|
|
90
|
-
argIndex?: number;
|
|
91
|
-
isSpread?: boolean;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Object property info for HAS_PROPERTY edges
|
|
96
|
-
*/
|
|
97
|
-
interface ObjectPropertyInfo {
|
|
98
|
-
objectId: string;
|
|
99
|
-
propertyName: string;
|
|
100
|
-
valueNodeId?: string;
|
|
101
|
-
valueType: 'LITERAL' | 'VARIABLE' | 'CALL' | 'EXPRESSION' | 'OBJECT_LITERAL' | 'ARRAY_LITERAL' | 'SPREAD';
|
|
102
|
-
valueName?: string;
|
|
103
|
-
literalValue?: unknown;
|
|
104
|
-
file: string;
|
|
105
|
-
line: number;
|
|
106
|
-
column: number;
|
|
107
|
-
callLine?: number;
|
|
108
|
-
callColumn?: number;
|
|
109
|
-
nestedObjectId?: string;
|
|
110
|
-
nestedArrayId?: string;
|
|
111
|
-
// REG-329: Scope path for variable resolution
|
|
112
|
-
valueScopePath?: string[];
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Array literal info for ARRAY_LITERAL nodes
|
|
117
|
-
*/
|
|
118
|
-
interface ArrayLiteralInfo {
|
|
119
|
-
id: string;
|
|
120
|
-
type: 'ARRAY_LITERAL';
|
|
121
|
-
file: string;
|
|
122
|
-
line: number;
|
|
123
|
-
column: number;
|
|
124
|
-
parentCallId?: string;
|
|
125
|
-
argIndex?: number;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Array element info for HAS_ELEMENT edges
|
|
130
|
-
*/
|
|
131
|
-
interface ArrayElementInfo {
|
|
132
|
-
arrayId: string;
|
|
133
|
-
index: number;
|
|
134
|
-
valueNodeId?: string;
|
|
135
|
-
valueType: 'LITERAL' | 'VARIABLE' | 'CALL' | 'EXPRESSION' | 'OBJECT_LITERAL' | 'ARRAY_LITERAL' | 'SPREAD';
|
|
136
|
-
valueName?: string;
|
|
137
|
-
literalValue?: unknown;
|
|
138
|
-
file: string;
|
|
139
|
-
line: number;
|
|
140
|
-
column: number;
|
|
141
|
-
callLine?: number;
|
|
142
|
-
callColumn?: number;
|
|
143
|
-
nestedObjectId?: string;
|
|
144
|
-
nestedArrayId?: string;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Argument info for PASSES_ARGUMENT edges
|
|
149
|
-
*/
|
|
150
|
-
interface ArgumentInfo {
|
|
151
|
-
callId: string;
|
|
152
|
-
argIndex: number;
|
|
153
|
-
file: string;
|
|
154
|
-
line: number;
|
|
155
|
-
column: number;
|
|
156
|
-
isSpread?: boolean;
|
|
157
|
-
targetType?: string;
|
|
158
|
-
targetId?: string;
|
|
159
|
-
targetName?: string;
|
|
160
|
-
literalValue?: unknown;
|
|
161
|
-
functionLine?: number;
|
|
162
|
-
functionColumn?: number;
|
|
163
|
-
nestedCallLine?: number;
|
|
164
|
-
nestedCallColumn?: number;
|
|
165
|
-
objectName?: string;
|
|
166
|
-
propertyName?: string;
|
|
167
|
-
expressionType?: string;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Call site info
|
|
172
|
-
*/
|
|
173
|
-
interface CallSiteInfo {
|
|
174
|
-
id: string;
|
|
175
|
-
type: 'CALL';
|
|
176
|
-
name: string;
|
|
177
|
-
file: string;
|
|
178
|
-
line: number;
|
|
179
|
-
column: number;
|
|
180
|
-
parentScopeId: string;
|
|
181
|
-
targetFunctionName: string;
|
|
182
|
-
isNew?: boolean;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Method call info
|
|
187
|
-
*/
|
|
188
|
-
interface MethodCallInfo {
|
|
189
|
-
id: string;
|
|
190
|
-
type: 'CALL';
|
|
191
|
-
name: string;
|
|
192
|
-
object: string;
|
|
193
|
-
method: string;
|
|
194
|
-
computed?: boolean;
|
|
195
|
-
computedPropertyVar?: string | null;
|
|
196
|
-
file: string;
|
|
197
|
-
line: number;
|
|
198
|
-
column: number;
|
|
199
|
-
parentScopeId: string;
|
|
200
|
-
isNew?: boolean;
|
|
201
|
-
/** REG-332: Annotation to suppress strict mode errors */
|
|
202
|
-
grafemaIgnore?: GrafemaIgnoreAnnotation;
|
|
20
|
+
import { getGrafemaIgnore } from './call-expression-helpers.js';
|
|
21
|
+
import { ArgumentExtractor } from './ArgumentExtractor.js';
|
|
22
|
+
import type {
|
|
23
|
+
ArgumentInfo, CallSiteInfo, MethodCallInfo, EventListenerInfo,
|
|
24
|
+
MethodCallbackInfo, LiteralInfo,
|
|
25
|
+
} from './call-expression-types.js';
|
|
26
|
+
/** Dedup tracking used by handler methods. */
|
|
27
|
+
interface HandlerProcessedNodes {
|
|
28
|
+
callSites: Set<string>;
|
|
29
|
+
methodCalls: Set<string>;
|
|
30
|
+
eventListeners: Set<string>;
|
|
31
|
+
[key: string]: Set<string>;
|
|
203
32
|
}
|
|
204
33
|
|
|
205
|
-
/**
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
34
|
+
/** Shared state for handler methods, extracted once in getHandlers(). */
|
|
35
|
+
interface HandlerState {
|
|
36
|
+
module: VisitorModule;
|
|
37
|
+
callSites: CallSiteInfo[];
|
|
38
|
+
methodCalls: MethodCallInfo[];
|
|
39
|
+
eventListeners: EventListenerInfo[];
|
|
40
|
+
methodCallbacks: MethodCallbackInfo[];
|
|
41
|
+
literals: LiteralInfo[];
|
|
42
|
+
callArguments: ArgumentInfo[];
|
|
43
|
+
callSiteCounterRef: CounterRef;
|
|
44
|
+
literalCounterRef: CounterRef;
|
|
45
|
+
processedNodes: HandlerProcessedNodes;
|
|
46
|
+
scopeTracker?: ScopeTracker;
|
|
217
47
|
}
|
|
218
48
|
|
|
219
49
|
/**
|
|
220
|
-
*
|
|
50
|
+
* Extract the first literal argument value from a CallExpression for content hash hints.
|
|
221
51
|
*/
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
id: string;
|
|
234
|
-
type: 'LITERAL' | 'EXPRESSION';
|
|
235
|
-
value?: unknown;
|
|
236
|
-
valueType?: string;
|
|
237
|
-
expressionType?: string;
|
|
238
|
-
operator?: string;
|
|
239
|
-
name?: string;
|
|
240
|
-
file: string;
|
|
241
|
-
line: number;
|
|
242
|
-
column: number;
|
|
243
|
-
parentCallId: string;
|
|
244
|
-
argIndex: number;
|
|
52
|
+
function extractFirstLiteralArg(node: CallExpression | NewExpression): string | undefined {
|
|
53
|
+
if (node.arguments.length === 0) return undefined;
|
|
54
|
+
const firstArg = node.arguments[0];
|
|
55
|
+
if (!firstArg) return undefined;
|
|
56
|
+
|
|
57
|
+
const actualArg = firstArg.type === 'SpreadElement' ? firstArg.argument : firstArg;
|
|
58
|
+
const literalValue = ExpressionEvaluator.extractLiteralValue(actualArg);
|
|
59
|
+
if (literalValue !== null) {
|
|
60
|
+
return String(literalValue);
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
245
63
|
}
|
|
246
64
|
|
|
247
65
|
export class CallExpressionVisitor extends ASTVisitor {
|
|
248
66
|
private scopeTracker?: ScopeTracker;
|
|
67
|
+
private sharedIdGenerator?: IdGenerator;
|
|
249
68
|
|
|
250
|
-
|
|
251
|
-
* @param module - Current module being analyzed
|
|
252
|
-
* @param collections - Must contain arrays and counter refs
|
|
253
|
-
* @param scopeTracker - Optional ScopeTracker for semantic ID generation
|
|
254
|
-
*/
|
|
255
|
-
constructor(module: VisitorModule, collections: VisitorCollections, scopeTracker?: ScopeTracker) {
|
|
69
|
+
constructor(module: VisitorModule, collections: VisitorCollections, scopeTracker?: ScopeTracker, sharedIdGenerator?: IdGenerator) {
|
|
256
70
|
super(module, collections);
|
|
257
71
|
this.scopeTracker = scopeTracker;
|
|
72
|
+
this.sharedIdGenerator = sharedIdGenerator;
|
|
258
73
|
}
|
|
259
74
|
|
|
260
|
-
/**
|
|
261
|
-
* Extract argument information for PASSES_ARGUMENT edges
|
|
262
|
-
*/
|
|
263
|
-
extractArguments(
|
|
264
|
-
args: CallExpression['arguments'],
|
|
265
|
-
callId: string,
|
|
266
|
-
module: VisitorModule,
|
|
267
|
-
callArguments: ArgumentInfo[],
|
|
268
|
-
literals: LiteralInfo[],
|
|
269
|
-
literalCounterRef: CounterRef
|
|
270
|
-
): void {
|
|
271
|
-
args.forEach((arg, index) => {
|
|
272
|
-
const argInfo: ArgumentInfo = {
|
|
273
|
-
callId,
|
|
274
|
-
argIndex: index,
|
|
275
|
-
file: module.file,
|
|
276
|
-
line: arg.loc?.start.line || 0,
|
|
277
|
-
column: arg.loc?.start.column || 0
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
// Check for spread: ...arg
|
|
281
|
-
let actualArg: Node = arg;
|
|
282
|
-
if (arg.type === 'SpreadElement') {
|
|
283
|
-
argInfo.isSpread = true;
|
|
284
|
-
actualArg = arg.argument; // Get the actual argument
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Object literal - check BEFORE extractLiteralValue to handle object-typed args properly
|
|
288
|
-
if (actualArg.type === 'ObjectExpression') {
|
|
289
|
-
const objectExpr = actualArg as ObjectExpression;
|
|
290
|
-
// Initialize collections if not exist (must assign back to this.collections!)
|
|
291
|
-
if (!this.collections.objectLiteralCounterRef) {
|
|
292
|
-
this.collections.objectLiteralCounterRef = { value: 0 };
|
|
293
|
-
}
|
|
294
|
-
if (!this.collections.objectLiterals) {
|
|
295
|
-
this.collections.objectLiterals = [];
|
|
296
|
-
}
|
|
297
|
-
if (!this.collections.objectProperties) {
|
|
298
|
-
this.collections.objectProperties = [];
|
|
299
|
-
}
|
|
300
|
-
const objectLiteralCounterRef = this.collections.objectLiteralCounterRef as CounterRef;
|
|
301
|
-
|
|
302
|
-
// Use factory to create OBJECT_LITERAL node
|
|
303
|
-
const objectNode = ObjectLiteralNode.create(
|
|
304
|
-
module.file,
|
|
305
|
-
argInfo.line,
|
|
306
|
-
argInfo.column,
|
|
307
|
-
{
|
|
308
|
-
parentCallId: callId,
|
|
309
|
-
argIndex: index,
|
|
310
|
-
counter: objectLiteralCounterRef.value++
|
|
311
|
-
}
|
|
312
|
-
);
|
|
313
|
-
// Factory guarantees line is set, cast to ObjectLiteralInfo
|
|
314
|
-
(this.collections.objectLiterals as ObjectLiteralInfo[]).push(objectNode as unknown as ObjectLiteralInfo);
|
|
315
|
-
const objectId = objectNode.id;
|
|
316
|
-
|
|
317
|
-
// Extract properties
|
|
318
|
-
this.extractObjectProperties(
|
|
319
|
-
objectExpr,
|
|
320
|
-
objectId,
|
|
321
|
-
module,
|
|
322
|
-
this.collections.objectProperties as ObjectPropertyInfo[],
|
|
323
|
-
this.collections.objectLiterals as ObjectLiteralInfo[],
|
|
324
|
-
objectLiteralCounterRef,
|
|
325
|
-
literals as LiteralInfo[],
|
|
326
|
-
literalCounterRef
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
argInfo.targetType = 'OBJECT_LITERAL';
|
|
330
|
-
argInfo.targetId = objectId;
|
|
331
|
-
}
|
|
332
|
-
// Array literal - check BEFORE extractLiteralValue to handle array-typed args properly
|
|
333
|
-
else if (actualArg.type === 'ArrayExpression') {
|
|
334
|
-
const arrayExpr = actualArg as ArrayExpression;
|
|
335
|
-
// Initialize collections if not exist (must assign back to this.collections!)
|
|
336
|
-
if (!this.collections.arrayLiteralCounterRef) {
|
|
337
|
-
this.collections.arrayLiteralCounterRef = { value: 0 };
|
|
338
|
-
}
|
|
339
|
-
if (!this.collections.arrayLiterals) {
|
|
340
|
-
this.collections.arrayLiterals = [];
|
|
341
|
-
}
|
|
342
|
-
if (!this.collections.arrayElements) {
|
|
343
|
-
this.collections.arrayElements = [];
|
|
344
|
-
}
|
|
345
|
-
if (!this.collections.objectLiteralCounterRef) {
|
|
346
|
-
this.collections.objectLiteralCounterRef = { value: 0 };
|
|
347
|
-
}
|
|
348
|
-
if (!this.collections.objectLiterals) {
|
|
349
|
-
this.collections.objectLiterals = [];
|
|
350
|
-
}
|
|
351
|
-
if (!this.collections.objectProperties) {
|
|
352
|
-
this.collections.objectProperties = [];
|
|
353
|
-
}
|
|
354
|
-
const arrayLiteralCounterRef = this.collections.arrayLiteralCounterRef as CounterRef;
|
|
355
|
-
|
|
356
|
-
// Use factory to create ARRAY_LITERAL node
|
|
357
|
-
const arrayNode = ArrayLiteralNode.create(
|
|
358
|
-
module.file,
|
|
359
|
-
argInfo.line,
|
|
360
|
-
argInfo.column,
|
|
361
|
-
{
|
|
362
|
-
parentCallId: callId,
|
|
363
|
-
argIndex: index,
|
|
364
|
-
counter: arrayLiteralCounterRef.value++
|
|
365
|
-
}
|
|
366
|
-
);
|
|
367
|
-
// Factory guarantees line is set, cast to ArrayLiteralInfo
|
|
368
|
-
(this.collections.arrayLiterals as ArrayLiteralInfo[]).push(arrayNode as unknown as ArrayLiteralInfo);
|
|
369
|
-
const arrayId = arrayNode.id;
|
|
370
|
-
|
|
371
|
-
// Extract elements
|
|
372
|
-
this.extractArrayElements(
|
|
373
|
-
arrayExpr,
|
|
374
|
-
arrayId,
|
|
375
|
-
module,
|
|
376
|
-
this.collections.arrayElements as ArrayElementInfo[],
|
|
377
|
-
this.collections.arrayLiterals as ArrayLiteralInfo[],
|
|
378
|
-
arrayLiteralCounterRef,
|
|
379
|
-
this.collections.objectLiterals as ObjectLiteralInfo[],
|
|
380
|
-
this.collections.objectLiteralCounterRef as CounterRef,
|
|
381
|
-
this.collections.objectProperties as ObjectPropertyInfo[],
|
|
382
|
-
literals as LiteralInfo[],
|
|
383
|
-
literalCounterRef
|
|
384
|
-
);
|
|
385
|
-
|
|
386
|
-
argInfo.targetType = 'ARRAY_LITERAL';
|
|
387
|
-
argInfo.targetId = arrayId;
|
|
388
|
-
}
|
|
389
|
-
// Literal value (primitives only - objects/arrays handled above)
|
|
390
|
-
else {
|
|
391
|
-
const literalValue = ExpressionEvaluator.extractLiteralValue(actualArg);
|
|
392
|
-
if (literalValue !== null) {
|
|
393
|
-
const literalId = `LITERAL#arg${index}#${module.file}#${argInfo.line}:${argInfo.column}:${literalCounterRef.value++}`;
|
|
394
|
-
literals.push({
|
|
395
|
-
id: literalId,
|
|
396
|
-
type: 'LITERAL',
|
|
397
|
-
value: literalValue,
|
|
398
|
-
valueType: typeof literalValue,
|
|
399
|
-
file: module.file,
|
|
400
|
-
line: argInfo.line,
|
|
401
|
-
column: argInfo.column,
|
|
402
|
-
parentCallId: callId,
|
|
403
|
-
argIndex: index
|
|
404
|
-
});
|
|
405
|
-
argInfo.targetType = 'LITERAL';
|
|
406
|
-
argInfo.targetId = literalId;
|
|
407
|
-
argInfo.literalValue = literalValue;
|
|
408
|
-
}
|
|
409
|
-
// Variable reference
|
|
410
|
-
else if (actualArg.type === 'Identifier') {
|
|
411
|
-
argInfo.targetType = 'VARIABLE';
|
|
412
|
-
argInfo.targetName = (actualArg as Identifier).name; // Will be resolved in GraphBuilder
|
|
413
|
-
}
|
|
414
|
-
// Function expression (callback)
|
|
415
|
-
else if (actualArg.type === 'ArrowFunctionExpression' || actualArg.type === 'FunctionExpression') {
|
|
416
|
-
argInfo.targetType = 'FUNCTION';
|
|
417
|
-
argInfo.functionLine = actualArg.loc?.start.line;
|
|
418
|
-
argInfo.functionColumn = actualArg.loc?.start.column;
|
|
419
|
-
}
|
|
420
|
-
// Call expression (nested call)
|
|
421
|
-
else if (actualArg.type === 'CallExpression') {
|
|
422
|
-
argInfo.targetType = 'CALL';
|
|
423
|
-
// Nested calls will be processed separately, link by position
|
|
424
|
-
argInfo.nestedCallLine = actualArg.loc?.start.line;
|
|
425
|
-
argInfo.nestedCallColumn = actualArg.loc?.start.column;
|
|
426
|
-
}
|
|
427
|
-
// Member expression: obj.prop or obj[x]
|
|
428
|
-
else if (actualArg.type === 'MemberExpression') {
|
|
429
|
-
const memberExpr = actualArg as MemberExpression;
|
|
430
|
-
argInfo.targetType = 'EXPRESSION';
|
|
431
|
-
argInfo.expressionType = 'MemberExpression';
|
|
432
|
-
if (memberExpr.object.type === 'Identifier') {
|
|
433
|
-
argInfo.objectName = memberExpr.object.name;
|
|
434
|
-
}
|
|
435
|
-
if (!memberExpr.computed && memberExpr.property.type === 'Identifier') {
|
|
436
|
-
argInfo.propertyName = memberExpr.property.name;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
// Binary/Logical expression: a + b, a && b
|
|
440
|
-
else if (actualArg.type === 'BinaryExpression' || actualArg.type === 'LogicalExpression') {
|
|
441
|
-
const expr = actualArg as { operator?: string; type: string };
|
|
442
|
-
const operator = expr.operator || '?';
|
|
443
|
-
const counter = literalCounterRef.value++;
|
|
444
|
-
|
|
445
|
-
// Create EXPRESSION node via NodeFactory
|
|
446
|
-
const expressionNode = NodeFactory.createArgumentExpression(
|
|
447
|
-
actualArg.type,
|
|
448
|
-
module.file,
|
|
449
|
-
argInfo.line,
|
|
450
|
-
argInfo.column,
|
|
451
|
-
{
|
|
452
|
-
parentCallId: callId,
|
|
453
|
-
argIndex: index,
|
|
454
|
-
operator,
|
|
455
|
-
counter
|
|
456
|
-
}
|
|
457
|
-
);
|
|
458
|
-
|
|
459
|
-
literals.push(expressionNode as LiteralInfo);
|
|
460
|
-
|
|
461
|
-
argInfo.targetType = 'EXPRESSION';
|
|
462
|
-
argInfo.targetId = expressionNode.id;
|
|
463
|
-
argInfo.expressionType = actualArg.type;
|
|
464
|
-
|
|
465
|
-
// Track DERIVES_FROM edges for identifiers in expression
|
|
466
|
-
const identifiers = this.extractIdentifiers(actualArg);
|
|
467
|
-
const { variableAssignments } = this.collections;
|
|
468
|
-
if (variableAssignments) {
|
|
469
|
-
for (const identName of identifiers) {
|
|
470
|
-
variableAssignments.push({
|
|
471
|
-
variableId: expressionNode.id,
|
|
472
|
-
sourceId: null,
|
|
473
|
-
sourceName: identName,
|
|
474
|
-
sourceType: 'DERIVES_FROM_VARIABLE',
|
|
475
|
-
file: module.file
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
// Other expression types (fallback for unhandled expression types)
|
|
481
|
-
else {
|
|
482
|
-
argInfo.targetType = 'EXPRESSION';
|
|
483
|
-
argInfo.expressionType = actualArg.type;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
callArguments.push(argInfo);
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* Extract all Identifier names from an expression (recursively)
|
|
493
|
-
* Used for BinaryExpression/LogicalExpression to track DERIVES_FROM edges
|
|
494
|
-
*/
|
|
495
|
-
extractIdentifiers(node: Node | null | undefined, identifiers: Set<string> = new Set()): string[] {
|
|
496
|
-
if (!node) return Array.from(identifiers);
|
|
497
|
-
|
|
498
|
-
if (node.type === 'Identifier') {
|
|
499
|
-
identifiers.add((node as Identifier).name);
|
|
500
|
-
} else if (node.type === 'BinaryExpression' || node.type === 'LogicalExpression') {
|
|
501
|
-
const expr = node as { left: Node; right: Node };
|
|
502
|
-
this.extractIdentifiers(expr.left, identifiers);
|
|
503
|
-
this.extractIdentifiers(expr.right, identifiers);
|
|
504
|
-
} else if (node.type === 'UnaryExpression') {
|
|
505
|
-
const expr = node as { argument: Node };
|
|
506
|
-
this.extractIdentifiers(expr.argument, identifiers);
|
|
507
|
-
} else if (node.type === 'ConditionalExpression') {
|
|
508
|
-
const expr = node as { test: Node; consequent: Node; alternate: Node };
|
|
509
|
-
this.extractIdentifiers(expr.test, identifiers);
|
|
510
|
-
this.extractIdentifiers(expr.consequent, identifiers);
|
|
511
|
-
this.extractIdentifiers(expr.alternate, identifiers);
|
|
512
|
-
} else if (node.type === 'MemberExpression') {
|
|
513
|
-
const memberExpr = node as MemberExpression;
|
|
514
|
-
// For obj.prop - track obj (but not prop as it's a property name)
|
|
515
|
-
if (memberExpr.object.type === 'Identifier') {
|
|
516
|
-
identifiers.add(memberExpr.object.name);
|
|
517
|
-
} else {
|
|
518
|
-
this.extractIdentifiers(memberExpr.object, identifiers);
|
|
519
|
-
}
|
|
520
|
-
} else if (node.type === 'CallExpression') {
|
|
521
|
-
const callExpr = node as CallExpression;
|
|
522
|
-
// For func() - track func if identifier, and all arguments
|
|
523
|
-
if (callExpr.callee.type === 'Identifier') {
|
|
524
|
-
identifiers.add((callExpr.callee as Identifier).name);
|
|
525
|
-
}
|
|
526
|
-
for (const arg of callExpr.arguments) {
|
|
527
|
-
if (arg.type !== 'SpreadElement') {
|
|
528
|
-
this.extractIdentifiers(arg, identifiers);
|
|
529
|
-
} else {
|
|
530
|
-
this.extractIdentifiers(arg.argument, identifiers);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
return Array.from(identifiers);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* Extract object properties and create ObjectPropertyInfo records
|
|
540
|
-
*/
|
|
541
|
-
extractObjectProperties(
|
|
542
|
-
objectExpr: ObjectExpression,
|
|
543
|
-
objectId: string,
|
|
544
|
-
module: VisitorModule,
|
|
545
|
-
objectProperties: ObjectPropertyInfo[],
|
|
546
|
-
objectLiterals: ObjectLiteralInfo[],
|
|
547
|
-
objectLiteralCounterRef: CounterRef,
|
|
548
|
-
literals: LiteralInfo[],
|
|
549
|
-
literalCounterRef: CounterRef
|
|
550
|
-
): void {
|
|
551
|
-
for (const prop of objectExpr.properties) {
|
|
552
|
-
const propLine = prop.loc?.start.line || 0;
|
|
553
|
-
const propColumn = prop.loc?.start.column || 0;
|
|
554
|
-
|
|
555
|
-
// Handle spread properties: { ...other }
|
|
556
|
-
if (prop.type === 'SpreadElement') {
|
|
557
|
-
const spreadArg = prop.argument;
|
|
558
|
-
const propertyInfo: ObjectPropertyInfo = {
|
|
559
|
-
objectId,
|
|
560
|
-
propertyName: '<spread>',
|
|
561
|
-
valueType: 'SPREAD',
|
|
562
|
-
file: module.file,
|
|
563
|
-
line: propLine,
|
|
564
|
-
column: propColumn
|
|
565
|
-
};
|
|
566
|
-
|
|
567
|
-
if (spreadArg.type === 'Identifier') {
|
|
568
|
-
propertyInfo.valueName = spreadArg.name;
|
|
569
|
-
propertyInfo.valueType = 'VARIABLE';
|
|
570
|
-
// REG-329: Capture scope path for spread variable resolution
|
|
571
|
-
propertyInfo.valueScopePath = this.scopeTracker?.getContext().scopePath ?? [];
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
objectProperties.push(propertyInfo);
|
|
575
|
-
continue;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
// Handle regular properties
|
|
579
|
-
if (prop.type === 'ObjectProperty') {
|
|
580
|
-
const objProp = prop as ObjectProperty;
|
|
581
|
-
let propertyName: string;
|
|
582
|
-
|
|
583
|
-
// Get property name
|
|
584
|
-
if (objProp.key.type === 'Identifier') {
|
|
585
|
-
propertyName = objProp.key.name;
|
|
586
|
-
} else if (objProp.key.type === 'StringLiteral') {
|
|
587
|
-
propertyName = objProp.key.value;
|
|
588
|
-
} else if (objProp.key.type === 'NumericLiteral') {
|
|
589
|
-
propertyName = String(objProp.key.value);
|
|
590
|
-
} else {
|
|
591
|
-
propertyName = '<computed>';
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
const propertyInfo: ObjectPropertyInfo = {
|
|
595
|
-
objectId,
|
|
596
|
-
propertyName,
|
|
597
|
-
file: module.file,
|
|
598
|
-
line: propLine,
|
|
599
|
-
column: propColumn,
|
|
600
|
-
valueType: 'EXPRESSION'
|
|
601
|
-
};
|
|
602
|
-
|
|
603
|
-
const value = objProp.value;
|
|
604
|
-
|
|
605
|
-
// Nested object literal - check BEFORE extractLiteralValue
|
|
606
|
-
if (value.type === 'ObjectExpression') {
|
|
607
|
-
// Use factory - do NOT pass argIndex for nested literals (uses 'obj' suffix)
|
|
608
|
-
const nestedObjectNode = ObjectLiteralNode.create(
|
|
609
|
-
module.file,
|
|
610
|
-
value.loc?.start.line || 0,
|
|
611
|
-
value.loc?.start.column || 0,
|
|
612
|
-
{
|
|
613
|
-
counter: objectLiteralCounterRef.value++
|
|
614
|
-
}
|
|
615
|
-
);
|
|
616
|
-
objectLiterals.push(nestedObjectNode as unknown as ObjectLiteralInfo);
|
|
617
|
-
const nestedObjectId = nestedObjectNode.id;
|
|
618
|
-
|
|
619
|
-
// Recursively extract nested properties
|
|
620
|
-
this.extractObjectProperties(
|
|
621
|
-
value,
|
|
622
|
-
nestedObjectId,
|
|
623
|
-
module,
|
|
624
|
-
objectProperties,
|
|
625
|
-
objectLiterals,
|
|
626
|
-
objectLiteralCounterRef,
|
|
627
|
-
literals,
|
|
628
|
-
literalCounterRef
|
|
629
|
-
);
|
|
630
|
-
|
|
631
|
-
propertyInfo.valueType = 'OBJECT_LITERAL';
|
|
632
|
-
propertyInfo.nestedObjectId = nestedObjectId;
|
|
633
|
-
propertyInfo.valueNodeId = nestedObjectId;
|
|
634
|
-
}
|
|
635
|
-
// Nested array literal - check BEFORE extractLiteralValue
|
|
636
|
-
else if (value.type === 'ArrayExpression') {
|
|
637
|
-
const arrayLiteralCounterRef = (this.collections.arrayLiteralCounterRef ?? { value: 0 }) as CounterRef;
|
|
638
|
-
const arrayLiterals = this.collections.arrayLiterals ?? [];
|
|
639
|
-
const arrayElements = this.collections.arrayElements ?? [];
|
|
640
|
-
|
|
641
|
-
// Use factory - do NOT pass argIndex for nested literals (uses 'arr' suffix)
|
|
642
|
-
const nestedArrayNode = ArrayLiteralNode.create(
|
|
643
|
-
module.file,
|
|
644
|
-
value.loc?.start.line || 0,
|
|
645
|
-
value.loc?.start.column || 0,
|
|
646
|
-
{
|
|
647
|
-
counter: arrayLiteralCounterRef.value++
|
|
648
|
-
}
|
|
649
|
-
);
|
|
650
|
-
(arrayLiterals as ArrayLiteralInfo[]).push(nestedArrayNode as unknown as ArrayLiteralInfo);
|
|
651
|
-
const nestedArrayId = nestedArrayNode.id;
|
|
652
|
-
|
|
653
|
-
// Recursively extract array elements
|
|
654
|
-
this.extractArrayElements(
|
|
655
|
-
value,
|
|
656
|
-
nestedArrayId,
|
|
657
|
-
module,
|
|
658
|
-
arrayElements as ArrayElementInfo[],
|
|
659
|
-
arrayLiterals as ArrayLiteralInfo[],
|
|
660
|
-
arrayLiteralCounterRef,
|
|
661
|
-
objectLiterals,
|
|
662
|
-
objectLiteralCounterRef,
|
|
663
|
-
objectProperties,
|
|
664
|
-
literals,
|
|
665
|
-
literalCounterRef
|
|
666
|
-
);
|
|
667
|
-
|
|
668
|
-
propertyInfo.valueType = 'ARRAY_LITERAL';
|
|
669
|
-
propertyInfo.nestedArrayId = nestedArrayId;
|
|
670
|
-
propertyInfo.valueNodeId = nestedArrayId;
|
|
671
|
-
}
|
|
672
|
-
// Literal value (primitives only - objects/arrays handled above)
|
|
673
|
-
else {
|
|
674
|
-
const literalValue = ExpressionEvaluator.extractLiteralValue(value);
|
|
675
|
-
// Handle both non-null literals AND explicit null literals (NullLiteral)
|
|
676
|
-
if (literalValue !== null || value.type === 'NullLiteral') {
|
|
677
|
-
const literalId = `LITERAL#${propertyName}#${module.file}#${propLine}:${propColumn}:${literalCounterRef.value++}`;
|
|
678
|
-
literals.push({
|
|
679
|
-
id: literalId,
|
|
680
|
-
type: 'LITERAL',
|
|
681
|
-
value: literalValue,
|
|
682
|
-
valueType: typeof literalValue,
|
|
683
|
-
file: module.file,
|
|
684
|
-
line: propLine,
|
|
685
|
-
column: propColumn,
|
|
686
|
-
parentCallId: objectId,
|
|
687
|
-
argIndex: 0
|
|
688
|
-
});
|
|
689
|
-
propertyInfo.valueType = 'LITERAL';
|
|
690
|
-
propertyInfo.valueNodeId = literalId;
|
|
691
|
-
propertyInfo.literalValue = literalValue;
|
|
692
|
-
}
|
|
693
|
-
// Variable reference
|
|
694
|
-
else if (value.type === 'Identifier') {
|
|
695
|
-
propertyInfo.valueType = 'VARIABLE';
|
|
696
|
-
propertyInfo.valueName = value.name;
|
|
697
|
-
// REG-329: Capture scope path for scope-aware variable resolution
|
|
698
|
-
propertyInfo.valueScopePath = this.scopeTracker?.getContext().scopePath ?? [];
|
|
699
|
-
}
|
|
700
|
-
// Call expression
|
|
701
|
-
else if (value.type === 'CallExpression') {
|
|
702
|
-
propertyInfo.valueType = 'CALL';
|
|
703
|
-
propertyInfo.callLine = value.loc?.start.line;
|
|
704
|
-
propertyInfo.callColumn = value.loc?.start.column;
|
|
705
|
-
}
|
|
706
|
-
// Other expressions
|
|
707
|
-
else {
|
|
708
|
-
propertyInfo.valueType = 'EXPRESSION';
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
objectProperties.push(propertyInfo);
|
|
713
|
-
}
|
|
714
|
-
// Handle object methods: { foo() {} }
|
|
715
|
-
else if (prop.type === 'ObjectMethod') {
|
|
716
|
-
const propertyName = prop.key.type === 'Identifier' ? prop.key.name : '<computed>';
|
|
717
|
-
objectProperties.push({
|
|
718
|
-
objectId,
|
|
719
|
-
propertyName,
|
|
720
|
-
valueType: 'EXPRESSION',
|
|
721
|
-
file: module.file,
|
|
722
|
-
line: propLine,
|
|
723
|
-
column: propColumn
|
|
724
|
-
});
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
/**
|
|
730
|
-
* Extract array elements and create ArrayElementInfo records
|
|
731
|
-
*/
|
|
732
|
-
extractArrayElements(
|
|
733
|
-
arrayExpr: ArrayExpression,
|
|
734
|
-
arrayId: string,
|
|
735
|
-
module: VisitorModule,
|
|
736
|
-
arrayElements: ArrayElementInfo[],
|
|
737
|
-
arrayLiterals: ArrayLiteralInfo[],
|
|
738
|
-
arrayLiteralCounterRef: CounterRef,
|
|
739
|
-
objectLiterals: ObjectLiteralInfo[],
|
|
740
|
-
objectLiteralCounterRef: CounterRef,
|
|
741
|
-
objectProperties: ObjectPropertyInfo[],
|
|
742
|
-
literals: LiteralInfo[],
|
|
743
|
-
literalCounterRef: CounterRef
|
|
744
|
-
): void {
|
|
745
|
-
arrayExpr.elements.forEach((element, index) => {
|
|
746
|
-
if (!element) return; // Skip holes in arrays
|
|
747
|
-
|
|
748
|
-
const elemLine = element.loc?.start.line || 0;
|
|
749
|
-
const elemColumn = element.loc?.start.column || 0;
|
|
750
|
-
|
|
751
|
-
const elementInfo: ArrayElementInfo = {
|
|
752
|
-
arrayId,
|
|
753
|
-
index,
|
|
754
|
-
file: module.file,
|
|
755
|
-
line: elemLine,
|
|
756
|
-
column: elemColumn,
|
|
757
|
-
valueType: 'EXPRESSION'
|
|
758
|
-
};
|
|
759
|
-
|
|
760
|
-
// Handle spread elements: [...arr]
|
|
761
|
-
if (element.type === 'SpreadElement') {
|
|
762
|
-
const spreadArg = element.argument;
|
|
763
|
-
elementInfo.valueType = 'SPREAD';
|
|
764
|
-
if (spreadArg.type === 'Identifier') {
|
|
765
|
-
elementInfo.valueName = spreadArg.name;
|
|
766
|
-
}
|
|
767
|
-
arrayElements.push(elementInfo);
|
|
768
|
-
return;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
// Nested object literal - check BEFORE extractLiteralValue
|
|
772
|
-
if (element.type === 'ObjectExpression') {
|
|
773
|
-
// Use factory - do NOT pass argIndex for nested literals (uses 'obj' suffix)
|
|
774
|
-
const nestedObjectNode = ObjectLiteralNode.create(
|
|
775
|
-
module.file,
|
|
776
|
-
elemLine,
|
|
777
|
-
elemColumn,
|
|
778
|
-
{
|
|
779
|
-
counter: objectLiteralCounterRef.value++
|
|
780
|
-
}
|
|
781
|
-
);
|
|
782
|
-
objectLiterals.push(nestedObjectNode as unknown as ObjectLiteralInfo);
|
|
783
|
-
const nestedObjectId = nestedObjectNode.id;
|
|
784
|
-
|
|
785
|
-
// Recursively extract properties
|
|
786
|
-
this.extractObjectProperties(
|
|
787
|
-
element,
|
|
788
|
-
nestedObjectId,
|
|
789
|
-
module,
|
|
790
|
-
objectProperties,
|
|
791
|
-
objectLiterals,
|
|
792
|
-
objectLiteralCounterRef,
|
|
793
|
-
literals,
|
|
794
|
-
literalCounterRef
|
|
795
|
-
);
|
|
796
|
-
|
|
797
|
-
elementInfo.valueType = 'OBJECT_LITERAL';
|
|
798
|
-
elementInfo.nestedObjectId = nestedObjectId;
|
|
799
|
-
elementInfo.valueNodeId = nestedObjectId;
|
|
800
|
-
}
|
|
801
|
-
// Nested array literal - check BEFORE extractLiteralValue
|
|
802
|
-
else if (element.type === 'ArrayExpression') {
|
|
803
|
-
// Use factory - do NOT pass argIndex for nested literals (uses 'arr' suffix)
|
|
804
|
-
const nestedArrayNode = ArrayLiteralNode.create(
|
|
805
|
-
module.file,
|
|
806
|
-
elemLine,
|
|
807
|
-
elemColumn,
|
|
808
|
-
{
|
|
809
|
-
counter: arrayLiteralCounterRef.value++
|
|
810
|
-
}
|
|
811
|
-
);
|
|
812
|
-
arrayLiterals.push(nestedArrayNode as unknown as ArrayLiteralInfo);
|
|
813
|
-
const nestedArrayId = nestedArrayNode.id;
|
|
814
|
-
|
|
815
|
-
// Recursively extract elements
|
|
816
|
-
this.extractArrayElements(
|
|
817
|
-
element,
|
|
818
|
-
nestedArrayId,
|
|
819
|
-
module,
|
|
820
|
-
arrayElements,
|
|
821
|
-
arrayLiterals,
|
|
822
|
-
arrayLiteralCounterRef,
|
|
823
|
-
objectLiterals,
|
|
824
|
-
objectLiteralCounterRef,
|
|
825
|
-
objectProperties,
|
|
826
|
-
literals,
|
|
827
|
-
literalCounterRef
|
|
828
|
-
);
|
|
829
|
-
|
|
830
|
-
elementInfo.valueType = 'ARRAY_LITERAL';
|
|
831
|
-
elementInfo.nestedArrayId = nestedArrayId;
|
|
832
|
-
elementInfo.valueNodeId = nestedArrayId;
|
|
833
|
-
}
|
|
834
|
-
// Literal value (primitives only - objects/arrays handled above)
|
|
835
|
-
else {
|
|
836
|
-
const literalValue = ExpressionEvaluator.extractLiteralValue(element);
|
|
837
|
-
if (literalValue !== null) {
|
|
838
|
-
const literalId = `LITERAL#elem${index}#${module.file}#${elemLine}:${elemColumn}:${literalCounterRef.value++}`;
|
|
839
|
-
literals.push({
|
|
840
|
-
id: literalId,
|
|
841
|
-
type: 'LITERAL',
|
|
842
|
-
value: literalValue,
|
|
843
|
-
valueType: typeof literalValue,
|
|
844
|
-
file: module.file,
|
|
845
|
-
line: elemLine,
|
|
846
|
-
column: elemColumn,
|
|
847
|
-
parentCallId: arrayId,
|
|
848
|
-
argIndex: index
|
|
849
|
-
});
|
|
850
|
-
elementInfo.valueType = 'LITERAL';
|
|
851
|
-
elementInfo.valueNodeId = literalId;
|
|
852
|
-
elementInfo.literalValue = literalValue;
|
|
853
|
-
}
|
|
854
|
-
// Variable reference
|
|
855
|
-
else if (element.type === 'Identifier') {
|
|
856
|
-
elementInfo.valueType = 'VARIABLE';
|
|
857
|
-
elementInfo.valueName = element.name;
|
|
858
|
-
}
|
|
859
|
-
// Call expression
|
|
860
|
-
else if (element.type === 'CallExpression') {
|
|
861
|
-
elementInfo.valueType = 'CALL';
|
|
862
|
-
elementInfo.callLine = element.loc?.start.line;
|
|
863
|
-
elementInfo.callColumn = element.loc?.start.column;
|
|
864
|
-
}
|
|
865
|
-
// Other expressions
|
|
866
|
-
else {
|
|
867
|
-
elementInfo.valueType = 'EXPRESSION';
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
arrayElements.push(elementInfo);
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
/**
|
|
876
|
-
* Detect array mutation calls (push, unshift, splice) and collect mutation info
|
|
877
|
-
* for later FLOWS_INTO edge creation in GraphBuilder
|
|
878
|
-
*
|
|
879
|
-
* REG-117: Added isNested, baseObjectName, propertyName for nested mutations
|
|
880
|
-
*/
|
|
881
|
-
private detectArrayMutation(
|
|
882
|
-
callNode: CallExpression,
|
|
883
|
-
arrayName: string,
|
|
884
|
-
method: 'push' | 'unshift' | 'splice',
|
|
885
|
-
module: VisitorModule,
|
|
886
|
-
isNested?: boolean,
|
|
887
|
-
baseObjectName?: string,
|
|
888
|
-
propertyName?: string
|
|
889
|
-
): void {
|
|
890
|
-
// Initialize collection if not exists
|
|
891
|
-
if (!this.collections.arrayMutations) {
|
|
892
|
-
this.collections.arrayMutations = [];
|
|
893
|
-
}
|
|
894
|
-
const arrayMutations = this.collections.arrayMutations as ArrayMutationInfo[];
|
|
895
|
-
|
|
896
|
-
const mutationArgs: ArrayMutationArgument[] = [];
|
|
897
|
-
|
|
898
|
-
// For splice, only arguments from index 2 onwards are insertions
|
|
899
|
-
// splice(start, deleteCount, item1, item2, ...)
|
|
900
|
-
callNode.arguments.forEach((arg, index) => {
|
|
901
|
-
// Skip start and deleteCount for splice
|
|
902
|
-
if (method === 'splice' && index < 2) return;
|
|
903
|
-
|
|
904
|
-
const argInfo: ArrayMutationArgument = {
|
|
905
|
-
argIndex: method === 'splice' ? index - 2 : index,
|
|
906
|
-
isSpread: arg.type === 'SpreadElement',
|
|
907
|
-
valueType: 'EXPRESSION' // Default
|
|
908
|
-
};
|
|
909
|
-
|
|
910
|
-
let actualArg = arg;
|
|
911
|
-
if (arg.type === 'SpreadElement') {
|
|
912
|
-
actualArg = arg.argument;
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
// Determine value type and store coordinates for node lookup in GraphBuilder.
|
|
916
|
-
// IMPORTANT: Check ObjectExpression/ArrayExpression BEFORE extractLiteralValue
|
|
917
|
-
// to match the order in extractArguments (which creates the actual nodes).
|
|
918
|
-
// extractLiteralValue returns objects/arrays with all-literal properties as
|
|
919
|
-
// literal values, but extractArguments creates OBJECT_LITERAL/ARRAY_LITERAL nodes.
|
|
920
|
-
if (actualArg.type === 'ObjectExpression') {
|
|
921
|
-
argInfo.valueType = 'OBJECT_LITERAL';
|
|
922
|
-
argInfo.valueLine = actualArg.loc?.start.line;
|
|
923
|
-
argInfo.valueColumn = actualArg.loc?.start.column;
|
|
924
|
-
} else if (actualArg.type === 'ArrayExpression') {
|
|
925
|
-
argInfo.valueType = 'ARRAY_LITERAL';
|
|
926
|
-
argInfo.valueLine = actualArg.loc?.start.line;
|
|
927
|
-
argInfo.valueColumn = actualArg.loc?.start.column;
|
|
928
|
-
} else if (actualArg.type === 'Identifier') {
|
|
929
|
-
argInfo.valueType = 'VARIABLE';
|
|
930
|
-
argInfo.valueName = actualArg.name;
|
|
931
|
-
} else if (actualArg.type === 'CallExpression') {
|
|
932
|
-
argInfo.valueType = 'CALL';
|
|
933
|
-
argInfo.callLine = actualArg.loc?.start.line;
|
|
934
|
-
argInfo.callColumn = actualArg.loc?.start.column;
|
|
935
|
-
} else {
|
|
936
|
-
const literalValue = ExpressionEvaluator.extractLiteralValue(actualArg);
|
|
937
|
-
if (literalValue !== null) {
|
|
938
|
-
argInfo.valueType = 'LITERAL';
|
|
939
|
-
argInfo.literalValue = literalValue;
|
|
940
|
-
argInfo.valueLine = actualArg.loc?.start.line;
|
|
941
|
-
argInfo.valueColumn = actualArg.loc?.start.column;
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
mutationArgs.push(argInfo);
|
|
946
|
-
});
|
|
947
|
-
|
|
948
|
-
// Only record if there are actual insertions
|
|
949
|
-
if (mutationArgs.length > 0) {
|
|
950
|
-
const line = callNode.loc?.start.line ?? 0;
|
|
951
|
-
const column = callNode.loc?.start.column ?? 0;
|
|
952
|
-
|
|
953
|
-
// Generate semantic ID for array mutation if scopeTracker available
|
|
954
|
-
const scopeTracker = this.scopeTracker;
|
|
955
|
-
let mutationId: string | undefined;
|
|
956
|
-
// Capture scope path for scope-aware lookup (REG-309)
|
|
957
|
-
const scopePath = scopeTracker?.getContext().scopePath ?? [];
|
|
958
|
-
|
|
959
|
-
if (scopeTracker) {
|
|
960
|
-
const discriminator = scopeTracker.getItemCounter(`ARRAY_MUTATION:${arrayName}.${method}`);
|
|
961
|
-
mutationId = computeSemanticId('ARRAY_MUTATION', `${arrayName}.${method}`, scopeTracker.getContext(), { discriminator });
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
arrayMutations.push({
|
|
965
|
-
id: mutationId,
|
|
966
|
-
arrayName,
|
|
967
|
-
mutationScopePath: scopePath,
|
|
968
|
-
mutationMethod: method,
|
|
969
|
-
file: module.file,
|
|
970
|
-
line,
|
|
971
|
-
column,
|
|
972
|
-
insertedValues: mutationArgs,
|
|
973
|
-
// REG-117: Nested mutation fields
|
|
974
|
-
isNested,
|
|
975
|
-
baseObjectName,
|
|
976
|
-
propertyName
|
|
977
|
-
});
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
/**
|
|
982
|
-
* Detect Object.assign(target, source1, source2, ...) calls
|
|
983
|
-
* Creates ObjectMutationInfo for FLOWS_INTO edge generation in GraphBuilder
|
|
984
|
-
*
|
|
985
|
-
* @param callNode - The call expression node
|
|
986
|
-
* @param module - Current module being analyzed
|
|
987
|
-
*/
|
|
988
|
-
private detectObjectAssign(
|
|
989
|
-
callNode: CallExpression,
|
|
990
|
-
module: VisitorModule
|
|
991
|
-
): void {
|
|
992
|
-
// Need at least 2 arguments: target and at least one source
|
|
993
|
-
if (callNode.arguments.length < 2) return;
|
|
994
|
-
|
|
995
|
-
// Initialize object mutations collection if not exists
|
|
996
|
-
if (!this.collections.objectMutations) {
|
|
997
|
-
this.collections.objectMutations = [];
|
|
998
|
-
}
|
|
999
|
-
const objectMutations = this.collections.objectMutations as ObjectMutationInfo[];
|
|
1000
|
-
|
|
1001
|
-
// First argument is target
|
|
1002
|
-
const targetArg = callNode.arguments[0];
|
|
1003
|
-
let targetName: string;
|
|
1004
|
-
|
|
1005
|
-
if (targetArg.type === 'Identifier') {
|
|
1006
|
-
targetName = targetArg.name;
|
|
1007
|
-
} else if (targetArg.type === 'ObjectExpression') {
|
|
1008
|
-
targetName = '<anonymous>';
|
|
1009
|
-
} else {
|
|
1010
|
-
return;
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
const line = callNode.loc?.start.line ?? 0;
|
|
1014
|
-
const column = callNode.loc?.start.column ?? 0;
|
|
1015
|
-
|
|
1016
|
-
for (let i = 1; i < callNode.arguments.length; i++) {
|
|
1017
|
-
let arg = callNode.arguments[i];
|
|
1018
|
-
let isSpread = false;
|
|
1019
|
-
|
|
1020
|
-
if (arg.type === 'SpreadElement') {
|
|
1021
|
-
isSpread = true;
|
|
1022
|
-
arg = arg.argument;
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
const valueInfo: ObjectMutationValue = {
|
|
1026
|
-
valueType: 'EXPRESSION',
|
|
1027
|
-
argIndex: i - 1,
|
|
1028
|
-
isSpread
|
|
1029
|
-
};
|
|
1030
|
-
|
|
1031
|
-
const literalValue = ExpressionEvaluator.extractLiteralValue(arg);
|
|
1032
|
-
if (literalValue !== null) {
|
|
1033
|
-
valueInfo.valueType = 'LITERAL';
|
|
1034
|
-
valueInfo.literalValue = literalValue;
|
|
1035
|
-
} else if (arg.type === 'Identifier') {
|
|
1036
|
-
valueInfo.valueType = 'VARIABLE';
|
|
1037
|
-
valueInfo.valueName = arg.name;
|
|
1038
|
-
} else if (arg.type === 'ObjectExpression') {
|
|
1039
|
-
valueInfo.valueType = 'OBJECT_LITERAL';
|
|
1040
|
-
} else if (arg.type === 'ArrayExpression') {
|
|
1041
|
-
valueInfo.valueType = 'ARRAY_LITERAL';
|
|
1042
|
-
} else if (arg.type === 'CallExpression') {
|
|
1043
|
-
valueInfo.valueType = 'CALL';
|
|
1044
|
-
valueInfo.callLine = arg.loc?.start.line;
|
|
1045
|
-
valueInfo.callColumn = arg.loc?.start.column;
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
// Capture scope path for scope-aware lookup (REG-309)
|
|
1049
|
-
const scopePath = this.scopeTracker?.getContext().scopePath ?? [];
|
|
1050
|
-
|
|
1051
|
-
let mutationId: string | undefined;
|
|
1052
|
-
if (this.scopeTracker) {
|
|
1053
|
-
const discriminator = this.scopeTracker.getItemCounter(`OBJECT_MUTATION:Object.assign:${targetName}`);
|
|
1054
|
-
mutationId = computeSemanticId('OBJECT_MUTATION', `Object.assign:${targetName}`, this.scopeTracker.getContext(), { discriminator });
|
|
1055
|
-
}
|
|
1056
|
-
|
|
1057
|
-
objectMutations.push({
|
|
1058
|
-
id: mutationId,
|
|
1059
|
-
objectName: targetName,
|
|
1060
|
-
mutationScopePath: scopePath,
|
|
1061
|
-
propertyName: '<assign>',
|
|
1062
|
-
mutationType: 'assign',
|
|
1063
|
-
file: module.file,
|
|
1064
|
-
line,
|
|
1065
|
-
column,
|
|
1066
|
-
value: valueInfo
|
|
1067
|
-
});
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
75
|
|
|
1071
76
|
/**
|
|
1072
77
|
* Extract full dotted name from a MemberExpression chain.
|
|
@@ -1162,356 +167,402 @@ export class CallExpressionVisitor extends ASTVisitor {
|
|
|
1162
167
|
}
|
|
1163
168
|
|
|
1164
169
|
getHandlers(): VisitorHandlers {
|
|
1165
|
-
const
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
170
|
+
const s: HandlerState = {
|
|
171
|
+
module: this.module,
|
|
172
|
+
callSites: (this.collections.callSites ?? []) as CallSiteInfo[],
|
|
173
|
+
methodCalls: (this.collections.methodCalls ?? []) as MethodCallInfo[],
|
|
174
|
+
eventListeners: (this.collections.eventListeners ?? []) as EventListenerInfo[],
|
|
175
|
+
methodCallbacks: (this.collections.methodCallbacks ?? []) as MethodCallbackInfo[],
|
|
176
|
+
literals: (this.collections.literals ?? []) as LiteralInfo[],
|
|
177
|
+
callArguments: (this.collections.callArguments ?? []) as ArgumentInfo[],
|
|
178
|
+
callSiteCounterRef: (this.collections.callSiteCounterRef ?? { value: 0 }) as CounterRef,
|
|
179
|
+
literalCounterRef: (this.collections.literalCounterRef ?? { value: 0 }) as CounterRef,
|
|
180
|
+
processedNodes: this.collections.processedNodes ?? { callSites: new Set(), methodCalls: new Set(), eventListeners: new Set() },
|
|
181
|
+
scopeTracker: this.scopeTracker,
|
|
182
|
+
};
|
|
1176
183
|
|
|
1177
184
|
return {
|
|
1178
185
|
CallExpression: (path: NodePath) => {
|
|
1179
186
|
const callNode = path.node as CallExpression;
|
|
1180
187
|
const functionParent = path.getFunctionParent();
|
|
1181
188
|
|
|
1182
|
-
//
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
// Identifier calls (direct function calls)
|
|
1186
|
-
// Skip if inside function - they will be processed by analyzeFunctionBody with proper scope tracking
|
|
1187
|
-
if (callNode.callee.type === 'Identifier') {
|
|
1188
|
-
if (functionParent) {
|
|
1189
|
-
return;
|
|
1190
|
-
}
|
|
1191
|
-
const callee = callNode.callee as Identifier;
|
|
1192
|
-
|
|
1193
|
-
const line = getLine(callNode);
|
|
1194
|
-
const column = getColumn(callNode);
|
|
1195
|
-
|
|
1196
|
-
// Generate ID using centralized IdGenerator
|
|
1197
|
-
const idGenerator = new IdGenerator(scopeTracker);
|
|
1198
|
-
const callId = idGenerator.generate(
|
|
1199
|
-
'CALL', callee.name, module.file,
|
|
1200
|
-
line, column,
|
|
1201
|
-
callSiteCounterRef,
|
|
1202
|
-
{ useDiscriminator: true, discriminatorKey: `CALL:${callee.name}` }
|
|
1203
|
-
);
|
|
1204
|
-
|
|
1205
|
-
(callSites as CallSiteInfo[]).push({
|
|
1206
|
-
id: callId,
|
|
1207
|
-
type: 'CALL',
|
|
1208
|
-
name: callee.name,
|
|
1209
|
-
file: module.file,
|
|
1210
|
-
line,
|
|
1211
|
-
column,
|
|
1212
|
-
parentScopeId,
|
|
1213
|
-
targetFunctionName: callee.name
|
|
1214
|
-
});
|
|
1215
|
-
|
|
1216
|
-
// Extract arguments for PASSES_ARGUMENT edges
|
|
1217
|
-
if (callNode.arguments.length > 0) {
|
|
1218
|
-
this.extractArguments(
|
|
1219
|
-
callNode.arguments,
|
|
1220
|
-
callId,
|
|
1221
|
-
module,
|
|
1222
|
-
callArguments as ArgumentInfo[],
|
|
1223
|
-
literals as LiteralInfo[],
|
|
1224
|
-
literalCounterRef
|
|
1225
|
-
);
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
// MemberExpression calls (method calls)
|
|
1229
|
-
// Skip if inside function - they will be processed by analyzeFunctionBody with proper scope tracking
|
|
1230
|
-
else if (callNode.callee.type === 'MemberExpression') {
|
|
1231
|
-
if (functionParent) {
|
|
1232
|
-
return;
|
|
1233
|
-
}
|
|
1234
|
-
const memberCallee = callNode.callee as MemberExpression;
|
|
1235
|
-
const object = memberCallee.object;
|
|
1236
|
-
const property = memberCallee.property;
|
|
1237
|
-
const isComputed = memberCallee.computed;
|
|
1238
|
-
|
|
1239
|
-
if ((object.type === 'Identifier' || object.type === 'ThisExpression') && property.type === 'Identifier') {
|
|
1240
|
-
const objectName = object.type === 'Identifier' ? (object as Identifier).name : 'this';
|
|
1241
|
-
// For computed access obj[x](), methodName is '<computed>' but we save the variable name
|
|
1242
|
-
const methodName = isComputed ? '<computed>' : (property as Identifier).name;
|
|
1243
|
-
const computedPropertyVar = isComputed ? (property as Identifier).name : null;
|
|
1244
|
-
|
|
1245
|
-
// Special handling for .on() event handlers
|
|
1246
|
-
if (methodName === 'on' && callNode.arguments.length >= 2) {
|
|
1247
|
-
const firstArg = callNode.arguments[0];
|
|
1248
|
-
const secondArg = callNode.arguments[1];
|
|
1249
|
-
|
|
1250
|
-
if (firstArg.type === 'StringLiteral') {
|
|
1251
|
-
const eventName = firstArg.value;
|
|
1252
|
-
|
|
1253
|
-
// Dedup check
|
|
1254
|
-
const nodeKey = `${callNode.start}:${callNode.end}`;
|
|
1255
|
-
if (processedNodes.eventListeners.has(nodeKey)) {
|
|
1256
|
-
return;
|
|
1257
|
-
}
|
|
1258
|
-
processedNodes.eventListeners.add(nodeKey);
|
|
1259
|
-
|
|
1260
|
-
const eventLine = getLine(callNode);
|
|
1261
|
-
const eventColumn = getColumn(callNode);
|
|
1262
|
-
|
|
1263
|
-
(eventListeners as EventListenerInfo[]).push({
|
|
1264
|
-
id: `event:listener#${eventName}#${module.file}#${eventLine}:${eventColumn}:${callSiteCounterRef.value++}`,
|
|
1265
|
-
type: 'event:listener',
|
|
1266
|
-
name: eventName,
|
|
1267
|
-
object: objectName,
|
|
1268
|
-
file: module.file,
|
|
1269
|
-
line: eventLine,
|
|
1270
|
-
parentScopeId,
|
|
1271
|
-
callbackArg: secondArg
|
|
1272
|
-
});
|
|
1273
|
-
}
|
|
1274
|
-
} else {
|
|
1275
|
-
// Regular method call
|
|
1276
|
-
const nodeKey = `${callNode.start}:${callNode.end}`;
|
|
1277
|
-
if (processedNodes.methodCalls.has(nodeKey)) {
|
|
1278
|
-
return;
|
|
1279
|
-
}
|
|
1280
|
-
processedNodes.methodCalls.add(nodeKey);
|
|
1281
|
-
|
|
1282
|
-
const fullName = `${objectName}.${methodName}`;
|
|
1283
|
-
const methodLine = getLine(callNode);
|
|
1284
|
-
const methodColumn = getColumn(callNode);
|
|
1285
|
-
|
|
1286
|
-
// Generate ID using centralized IdGenerator
|
|
1287
|
-
const idGenerator = new IdGenerator(scopeTracker);
|
|
1288
|
-
const methodCallId = idGenerator.generate(
|
|
1289
|
-
'CALL', fullName, module.file,
|
|
1290
|
-
methodLine, methodColumn,
|
|
1291
|
-
callSiteCounterRef,
|
|
1292
|
-
{ useDiscriminator: true, discriminatorKey: `CALL:${fullName}` }
|
|
1293
|
-
);
|
|
1294
|
-
|
|
1295
|
-
// REG-332: Check for grafema-ignore comment
|
|
1296
|
-
const grafemaIgnore = getGrafemaIgnore(path);
|
|
1297
|
-
|
|
1298
|
-
(methodCalls as MethodCallInfo[]).push({
|
|
1299
|
-
id: methodCallId,
|
|
1300
|
-
type: 'CALL',
|
|
1301
|
-
name: fullName,
|
|
1302
|
-
object: objectName,
|
|
1303
|
-
method: methodName,
|
|
1304
|
-
computed: isComputed,
|
|
1305
|
-
computedPropertyVar, // Variable name used in obj[x]() calls
|
|
1306
|
-
file: module.file,
|
|
1307
|
-
line: methodLine,
|
|
1308
|
-
column: methodColumn,
|
|
1309
|
-
parentScopeId,
|
|
1310
|
-
grafemaIgnore: grafemaIgnore ?? undefined,
|
|
1311
|
-
});
|
|
1312
|
-
|
|
1313
|
-
// Check for array mutation methods (push, unshift, splice)
|
|
1314
|
-
const ARRAY_MUTATION_METHODS = ['push', 'unshift', 'splice'];
|
|
1315
|
-
if (ARRAY_MUTATION_METHODS.includes(methodName)) {
|
|
1316
|
-
this.detectArrayMutation(
|
|
1317
|
-
callNode,
|
|
1318
|
-
objectName,
|
|
1319
|
-
methodName as 'push' | 'unshift' | 'splice',
|
|
1320
|
-
module
|
|
1321
|
-
);
|
|
1322
|
-
}
|
|
1323
|
-
|
|
1324
|
-
// Check for Object.assign() calls
|
|
1325
|
-
if (objectName === 'Object' && methodName === 'assign') {
|
|
1326
|
-
this.detectObjectAssign(callNode, module);
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1329
|
-
// Extract arguments for PASSES_ARGUMENT edges
|
|
1330
|
-
if (callNode.arguments.length > 0) {
|
|
1331
|
-
this.extractArguments(
|
|
1332
|
-
callNode.arguments,
|
|
1333
|
-
methodCallId,
|
|
1334
|
-
module,
|
|
1335
|
-
callArguments as ArgumentInfo[],
|
|
1336
|
-
literals as LiteralInfo[],
|
|
1337
|
-
literalCounterRef
|
|
1338
|
-
);
|
|
1339
|
-
|
|
1340
|
-
// Also track callbacks for HAS_CALLBACK edges
|
|
1341
|
-
callNode.arguments.forEach((arg) => {
|
|
1342
|
-
if (arg.type === 'ArrowFunctionExpression' || arg.type === 'FunctionExpression') {
|
|
1343
|
-
(methodCallbacks as MethodCallbackInfo[]).push({
|
|
1344
|
-
methodCallId,
|
|
1345
|
-
callbackLine: getLine(arg),
|
|
1346
|
-
callbackColumn: getColumn(arg),
|
|
1347
|
-
callbackType: arg.type
|
|
1348
|
-
});
|
|
1349
|
-
}
|
|
1350
|
-
});
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
// REG-117: Nested array mutations like obj.arr.push(item)
|
|
1355
|
-
// REG-395: General nested method calls like a.b.c() or obj.nested.method()
|
|
1356
|
-
// object is MemberExpression, property is the method name
|
|
1357
|
-
else if (object.type === 'MemberExpression' && property.type === 'Identifier') {
|
|
1358
|
-
const nestedMember = object as MemberExpression;
|
|
1359
|
-
const methodName = isComputed ? '<computed>' : (property as Identifier).name;
|
|
1360
|
-
const ARRAY_MUTATION_METHODS = ['push', 'unshift', 'splice'];
|
|
1361
|
-
|
|
1362
|
-
if (ARRAY_MUTATION_METHODS.includes(methodName)) {
|
|
1363
|
-
// Extract base object and property from nested MemberExpression
|
|
1364
|
-
const base = nestedMember.object;
|
|
1365
|
-
const prop = nestedMember.property;
|
|
1366
|
-
|
|
1367
|
-
// Only handle single-level nesting: obj.arr.push() or this.items.push()
|
|
1368
|
-
if ((base.type === 'Identifier' || base.type === 'ThisExpression') &&
|
|
1369
|
-
!nestedMember.computed &&
|
|
1370
|
-
prop.type === 'Identifier') {
|
|
1371
|
-
const baseObjectName = base.type === 'Identifier' ? (base as Identifier).name : 'this';
|
|
1372
|
-
const propertyName = (prop as Identifier).name;
|
|
1373
|
-
|
|
1374
|
-
this.detectArrayMutation(
|
|
1375
|
-
callNode,
|
|
1376
|
-
`${baseObjectName}.${propertyName}`, // arrayName for ID purposes
|
|
1377
|
-
methodName as 'push' | 'unshift' | 'splice',
|
|
1378
|
-
module,
|
|
1379
|
-
true, // isNested
|
|
1380
|
-
baseObjectName,
|
|
1381
|
-
propertyName
|
|
1382
|
-
);
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
|
-
// REG-395: Create CALL node for nested method calls like a.b.c()
|
|
1387
|
-
// Extract full object name by walking the MemberExpression chain
|
|
1388
|
-
const objectName = CallExpressionVisitor.extractMemberExpressionName(nestedMember);
|
|
1389
|
-
if (objectName) {
|
|
1390
|
-
const nodeKey = `${callNode.start}:${callNode.end}`;
|
|
1391
|
-
if (!processedNodes.methodCalls.has(nodeKey)) {
|
|
1392
|
-
processedNodes.methodCalls.add(nodeKey);
|
|
1393
|
-
|
|
1394
|
-
const fullName = `${objectName}.${methodName}`;
|
|
1395
|
-
const methodLine = getLine(callNode);
|
|
1396
|
-
const methodColumn = getColumn(callNode);
|
|
1397
|
-
|
|
1398
|
-
const idGenerator = new IdGenerator(scopeTracker);
|
|
1399
|
-
const methodCallId = idGenerator.generate(
|
|
1400
|
-
'CALL', fullName, module.file,
|
|
1401
|
-
methodLine, methodColumn,
|
|
1402
|
-
callSiteCounterRef,
|
|
1403
|
-
{ useDiscriminator: true, discriminatorKey: `CALL:${fullName}` }
|
|
1404
|
-
);
|
|
1405
|
-
|
|
1406
|
-
const grafemaIgnore = getGrafemaIgnore(path);
|
|
1407
|
-
|
|
1408
|
-
(methodCalls as MethodCallInfo[]).push({
|
|
1409
|
-
id: methodCallId,
|
|
1410
|
-
type: 'CALL',
|
|
1411
|
-
name: fullName,
|
|
1412
|
-
object: objectName,
|
|
1413
|
-
method: methodName,
|
|
1414
|
-
file: module.file,
|
|
1415
|
-
line: methodLine,
|
|
1416
|
-
column: methodColumn,
|
|
1417
|
-
parentScopeId,
|
|
1418
|
-
grafemaIgnore: grafemaIgnore ?? undefined,
|
|
1419
|
-
});
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
},
|
|
189
|
+
// Skip if inside function - handled by analyzeFunctionBody
|
|
190
|
+
if (functionParent) return;
|
|
1425
191
|
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
NewExpression: (path: NodePath) => {
|
|
1429
|
-
const newNode = path.node as NewExpression;
|
|
1430
|
-
const functionParent = path.getFunctionParent();
|
|
192
|
+
const parentScopeId = s.module.id;
|
|
193
|
+
const isAwaited = path.parentPath?.isAwaitExpression() ?? false;
|
|
1431
194
|
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
195
|
+
if (callNode.callee.type === 'Identifier') {
|
|
196
|
+
this.handleDirectCall(callNode, s, parentScopeId, isAwaited);
|
|
197
|
+
} else if (callNode.callee.type === 'MemberExpression') {
|
|
198
|
+
this.handleMemberCall(path, callNode, s, parentScopeId, isAwaited);
|
|
1435
199
|
}
|
|
200
|
+
},
|
|
1436
201
|
|
|
1437
|
-
|
|
202
|
+
NewExpression: (path: NodePath) => this.handleNewExpression(path, s),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
1438
205
|
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
206
|
+
/** Handle direct function calls: foo() */
|
|
207
|
+
private handleDirectCall(
|
|
208
|
+
callNode: CallExpression, s: HandlerState,
|
|
209
|
+
parentScopeId: string, isAwaited: boolean
|
|
210
|
+
): void {
|
|
211
|
+
const callee = callNode.callee as Identifier;
|
|
212
|
+
const line = getLine(callNode);
|
|
213
|
+
const column = getColumn(callNode);
|
|
214
|
+
|
|
215
|
+
const callInfo: CallSiteInfo = {
|
|
216
|
+
id: '', // Placeholder — resolved by generateV2 or set below
|
|
217
|
+
type: 'CALL',
|
|
218
|
+
name: callee.name,
|
|
219
|
+
file: s.module.file,
|
|
220
|
+
line,
|
|
221
|
+
column,
|
|
222
|
+
parentScopeId,
|
|
223
|
+
targetFunctionName: callee.name,
|
|
224
|
+
isAwaited: isAwaited || undefined
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
if (this.sharedIdGenerator) {
|
|
228
|
+
const contentHints: ContentHashHints = {
|
|
229
|
+
arity: callNode.arguments.length,
|
|
230
|
+
firstLiteralArg: extractFirstLiteralArg(callNode)
|
|
231
|
+
};
|
|
232
|
+
this.sharedIdGenerator.generateV2('CALL', callee.name, s.module.file, contentHints, callInfo);
|
|
233
|
+
} else {
|
|
234
|
+
const idGenerator = new IdGenerator(s.scopeTracker);
|
|
235
|
+
callInfo.id = idGenerator.generate(
|
|
236
|
+
'CALL', callee.name, s.module.file,
|
|
237
|
+
line, column,
|
|
238
|
+
s.callSiteCounterRef,
|
|
239
|
+
{ useDiscriminator: true, discriminatorKey: `CALL:${callee.name}` }
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
const callId = callInfo.id;
|
|
243
|
+
|
|
244
|
+
s.callSites.push(callInfo);
|
|
245
|
+
|
|
246
|
+
if (callNode.arguments.length > 0) {
|
|
247
|
+
ArgumentExtractor.extract(
|
|
248
|
+
callNode.arguments, callId, s.module,
|
|
249
|
+
s.callArguments, s.literals, s.literalCounterRef,
|
|
250
|
+
this.collections, s.scopeTracker
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/** Handle method calls: obj.method(), obj.on('event', handler), obj.arr.push() */
|
|
256
|
+
private handleMemberCall(
|
|
257
|
+
path: NodePath, callNode: CallExpression, s: HandlerState,
|
|
258
|
+
parentScopeId: string, isAwaited: boolean
|
|
259
|
+
): void {
|
|
260
|
+
const memberCallee = callNode.callee as MemberExpression;
|
|
261
|
+
const object = memberCallee.object;
|
|
262
|
+
const property = memberCallee.property;
|
|
263
|
+
const isComputed = memberCallee.computed;
|
|
264
|
+
|
|
265
|
+
if ((object.type === 'Identifier' || object.type === 'ThisExpression') && property.type === 'Identifier') {
|
|
266
|
+
this.handleSimpleMethodCall(path, callNode, s, parentScopeId, isAwaited,
|
|
267
|
+
memberCallee, object, property as Identifier, isComputed);
|
|
268
|
+
}
|
|
269
|
+
// REG-117/REG-395: Nested method calls like obj.arr.push() or a.b.c()
|
|
270
|
+
else if (object.type === 'MemberExpression' && property.type === 'Identifier') {
|
|
271
|
+
this.handleNestedMethodCall(path, callNode, s, parentScopeId,
|
|
272
|
+
object as MemberExpression, property as Identifier, isComputed);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** Handle simple method calls: obj.method() or obj.on('event', handler) */
|
|
277
|
+
private handleSimpleMethodCall(
|
|
278
|
+
path: NodePath, callNode: CallExpression, s: HandlerState,
|
|
279
|
+
parentScopeId: string, isAwaited: boolean,
|
|
280
|
+
memberCallee: MemberExpression, object: Node, property: Identifier, isComputed: boolean
|
|
281
|
+
): void {
|
|
282
|
+
const objectName = object.type === 'Identifier' ? (object as Identifier).name : 'this';
|
|
283
|
+
const methodName = isComputed ? '<computed>' : property.name;
|
|
284
|
+
const computedPropertyVar = isComputed ? property.name : null;
|
|
285
|
+
|
|
286
|
+
// Special handling for .on() event handlers
|
|
287
|
+
if (methodName === 'on' && callNode.arguments.length >= 2) {
|
|
288
|
+
const firstArg = callNode.arguments[0];
|
|
289
|
+
const secondArg = callNode.arguments[1];
|
|
290
|
+
|
|
291
|
+
if (firstArg.type === 'StringLiteral') {
|
|
292
|
+
const nodeKey = `${callNode.start}:${callNode.end}`;
|
|
293
|
+
if (s.processedNodes.eventListeners.has(nodeKey)) return;
|
|
294
|
+
s.processedNodes.eventListeners.add(nodeKey);
|
|
295
|
+
|
|
296
|
+
const eventLine = getLine(callNode);
|
|
297
|
+
const eventColumn = getColumn(callNode);
|
|
298
|
+
|
|
299
|
+
s.eventListeners.push({
|
|
300
|
+
id: `event:listener#${firstArg.value}#${s.module.file}#${eventLine}:${eventColumn}:${s.callSiteCounterRef.value++}`,
|
|
301
|
+
type: 'event:listener',
|
|
302
|
+
name: firstArg.value,
|
|
303
|
+
object: objectName,
|
|
304
|
+
file: s.module.file,
|
|
305
|
+
line: eventLine,
|
|
306
|
+
parentScopeId,
|
|
307
|
+
callbackArg: secondArg
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Regular method call
|
|
314
|
+
const nodeKey = `${callNode.start}:${callNode.end}`;
|
|
315
|
+
if (s.processedNodes.methodCalls.has(nodeKey)) return;
|
|
316
|
+
s.processedNodes.methodCalls.add(nodeKey);
|
|
317
|
+
|
|
318
|
+
const fullName = `${objectName}.${methodName}`;
|
|
319
|
+
const methodLine = getLine(callNode);
|
|
320
|
+
const methodColumn = getColumn(callNode);
|
|
321
|
+
|
|
322
|
+
const grafemaIgnore = getGrafemaIgnore(path);
|
|
323
|
+
|
|
324
|
+
const methodCallInfo: MethodCallInfo = {
|
|
325
|
+
id: '', // Placeholder — resolved by generateV2 or set below
|
|
326
|
+
type: 'CALL',
|
|
327
|
+
name: fullName,
|
|
328
|
+
object: objectName,
|
|
329
|
+
method: methodName,
|
|
330
|
+
computed: isComputed,
|
|
331
|
+
computedPropertyVar,
|
|
332
|
+
file: s.module.file,
|
|
333
|
+
line: methodLine,
|
|
334
|
+
column: methodColumn,
|
|
335
|
+
parentScopeId,
|
|
336
|
+
grafemaIgnore: grafemaIgnore ?? undefined,
|
|
337
|
+
isAwaited: isAwaited || undefined,
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
if (this.sharedIdGenerator) {
|
|
341
|
+
const contentHints: ContentHashHints = {
|
|
342
|
+
arity: callNode.arguments.length,
|
|
343
|
+
firstLiteralArg: extractFirstLiteralArg(callNode)
|
|
344
|
+
};
|
|
345
|
+
this.sharedIdGenerator.generateV2('CALL', fullName, s.module.file, contentHints, methodCallInfo);
|
|
346
|
+
} else {
|
|
347
|
+
const idGenerator = new IdGenerator(s.scopeTracker);
|
|
348
|
+
methodCallInfo.id = idGenerator.generate(
|
|
349
|
+
'CALL', fullName, s.module.file,
|
|
350
|
+
methodLine, methodColumn,
|
|
351
|
+
s.callSiteCounterRef,
|
|
352
|
+
{ useDiscriminator: true, discriminatorKey: `CALL:${fullName}` }
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
const methodCallId = methodCallInfo.id;
|
|
356
|
+
|
|
357
|
+
s.methodCalls.push(methodCallInfo);
|
|
358
|
+
|
|
359
|
+
// Check for array mutation methods (push, unshift, splice)
|
|
360
|
+
const ARRAY_MUTATION_METHODS = ['push', 'unshift', 'splice'];
|
|
361
|
+
if (ARRAY_MUTATION_METHODS.includes(methodName)) {
|
|
362
|
+
MutationDetector.detectArrayMutation(
|
|
363
|
+
callNode, objectName,
|
|
364
|
+
methodName as 'push' | 'unshift' | 'splice',
|
|
365
|
+
s.module, this.collections, s.scopeTracker
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// Check for Object.assign() calls
|
|
370
|
+
if (objectName === 'Object' && methodName === 'assign') {
|
|
371
|
+
MutationDetector.detectObjectAssign(callNode, s.module, this.collections, s.scopeTracker);
|
|
372
|
+
}
|
|
1461
373
|
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
374
|
+
// Extract arguments for PASSES_ARGUMENT edges
|
|
375
|
+
if (callNode.arguments.length > 0) {
|
|
376
|
+
ArgumentExtractor.extract(
|
|
377
|
+
callNode.arguments, methodCallId, s.module,
|
|
378
|
+
s.callArguments, s.literals, s.literalCounterRef,
|
|
379
|
+
this.collections, s.scopeTracker
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
// Also track callbacks for HAS_CALLBACK edges
|
|
383
|
+
callNode.arguments.forEach((arg) => {
|
|
384
|
+
if (arg.type === 'ArrowFunctionExpression' || arg.type === 'FunctionExpression') {
|
|
385
|
+
s.methodCallbacks.push({
|
|
386
|
+
methodCallId,
|
|
387
|
+
callbackLine: getLine(arg),
|
|
388
|
+
callbackColumn: getColumn(arg),
|
|
389
|
+
callbackType: arg.type
|
|
1472
390
|
});
|
|
1473
391
|
}
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Handle nested method calls: obj.arr.push(), a.b.c() (REG-117, REG-395) */
|
|
397
|
+
private handleNestedMethodCall(
|
|
398
|
+
path: NodePath, callNode: CallExpression, s: HandlerState,
|
|
399
|
+
parentScopeId: string,
|
|
400
|
+
nestedMember: MemberExpression, property: Identifier, isComputed: boolean
|
|
401
|
+
): void {
|
|
402
|
+
const methodName = isComputed ? '<computed>' : property.name;
|
|
403
|
+
const ARRAY_MUTATION_METHODS = ['push', 'unshift', 'splice'];
|
|
404
|
+
|
|
405
|
+
if (ARRAY_MUTATION_METHODS.includes(methodName)) {
|
|
406
|
+
const base = nestedMember.object;
|
|
407
|
+
const prop = nestedMember.property;
|
|
408
|
+
|
|
409
|
+
if ((base.type === 'Identifier' || base.type === 'ThisExpression') &&
|
|
410
|
+
!nestedMember.computed && prop.type === 'Identifier') {
|
|
411
|
+
const baseObjectName = base.type === 'Identifier' ? (base as Identifier).name : 'this';
|
|
412
|
+
const propertyName = (prop as Identifier).name;
|
|
413
|
+
|
|
414
|
+
MutationDetector.detectArrayMutation(
|
|
415
|
+
callNode,
|
|
416
|
+
`${baseObjectName}.${propertyName}`,
|
|
417
|
+
methodName as 'push' | 'unshift' | 'splice',
|
|
418
|
+
s.module, this.collections, s.scopeTracker,
|
|
419
|
+
true, baseObjectName, propertyName
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// REG-395: Create CALL node for nested method calls like a.b.c()
|
|
425
|
+
const objectName = CallExpressionVisitor.extractMemberExpressionName(nestedMember);
|
|
426
|
+
if (objectName) {
|
|
427
|
+
const nodeKey = `${callNode.start}:${callNode.end}`;
|
|
428
|
+
if (!s.processedNodes.methodCalls.has(nodeKey)) {
|
|
429
|
+
s.processedNodes.methodCalls.add(nodeKey);
|
|
430
|
+
|
|
431
|
+
const fullName = `${objectName}.${methodName}`;
|
|
432
|
+
const methodLine = getLine(callNode);
|
|
433
|
+
const methodColumn = getColumn(callNode);
|
|
434
|
+
|
|
435
|
+
const grafemaIgnore = getGrafemaIgnore(path);
|
|
436
|
+
|
|
437
|
+
const methodCallInfo: MethodCallInfo = {
|
|
438
|
+
id: '', // Placeholder — resolved by generateV2 or set below
|
|
439
|
+
type: 'CALL',
|
|
440
|
+
name: fullName,
|
|
441
|
+
object: objectName,
|
|
442
|
+
method: methodName,
|
|
443
|
+
file: s.module.file,
|
|
444
|
+
line: methodLine,
|
|
445
|
+
column: methodColumn,
|
|
446
|
+
parentScopeId,
|
|
447
|
+
grafemaIgnore: grafemaIgnore ?? undefined,
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
if (this.sharedIdGenerator) {
|
|
451
|
+
const contentHints: ContentHashHints = {
|
|
452
|
+
arity: callNode.arguments.length,
|
|
453
|
+
firstLiteralArg: extractFirstLiteralArg(callNode)
|
|
454
|
+
};
|
|
455
|
+
this.sharedIdGenerator.generateV2('CALL', fullName, s.module.file, contentHints, methodCallInfo);
|
|
456
|
+
} else {
|
|
457
|
+
const idGenerator = new IdGenerator(s.scopeTracker);
|
|
458
|
+
methodCallInfo.id = idGenerator.generate(
|
|
459
|
+
'CALL', fullName, s.module.file,
|
|
460
|
+
methodLine, methodColumn,
|
|
461
|
+
s.callSiteCounterRef,
|
|
462
|
+
{ useDiscriminator: true, discriminatorKey: `CALL:${fullName}` }
|
|
463
|
+
);
|
|
1513
464
|
}
|
|
465
|
+
|
|
466
|
+
s.methodCalls.push(methodCallInfo);
|
|
1514
467
|
}
|
|
1515
|
-
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/** Handle new expressions: new Foo(), new obj.Constructor() */
|
|
472
|
+
private handleNewExpression(path: NodePath, s: HandlerState): void {
|
|
473
|
+
const newNode = path.node as NewExpression;
|
|
474
|
+
const functionParent = path.getFunctionParent();
|
|
475
|
+
|
|
476
|
+
// Skip if inside function - handled by analyzeFunctionBody
|
|
477
|
+
if (functionParent) return;
|
|
478
|
+
|
|
479
|
+
const parentScopeId = s.module.id;
|
|
480
|
+
|
|
481
|
+
// Dedup check
|
|
482
|
+
const nodeKey = `new:${newNode.start}:${newNode.end}`;
|
|
483
|
+
if (s.processedNodes.methodCalls.has(nodeKey)) return;
|
|
484
|
+
s.processedNodes.methodCalls.add(nodeKey);
|
|
485
|
+
|
|
486
|
+
if (newNode.callee.type === 'Identifier') {
|
|
487
|
+
const constructorName = (newNode.callee as Identifier).name;
|
|
488
|
+
const newLine = getLine(newNode);
|
|
489
|
+
const newColumn = getColumn(newNode);
|
|
490
|
+
|
|
491
|
+
const callInfo: CallSiteInfo = {
|
|
492
|
+
id: '', // Placeholder — resolved by generateV2 or set below
|
|
493
|
+
type: 'CALL',
|
|
494
|
+
name: constructorName,
|
|
495
|
+
file: s.module.file,
|
|
496
|
+
line: newLine,
|
|
497
|
+
column: newColumn,
|
|
498
|
+
parentScopeId,
|
|
499
|
+
targetFunctionName: constructorName,
|
|
500
|
+
isNew: true
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
if (this.sharedIdGenerator) {
|
|
504
|
+
const contentHints: ContentHashHints = {
|
|
505
|
+
arity: newNode.arguments.length,
|
|
506
|
+
firstLiteralArg: undefined // constructor args not used for hash
|
|
507
|
+
};
|
|
508
|
+
this.sharedIdGenerator.generateV2('CALL', `new:${constructorName}`, s.module.file, contentHints, callInfo);
|
|
509
|
+
} else {
|
|
510
|
+
const idGenerator = new IdGenerator(s.scopeTracker);
|
|
511
|
+
callInfo.id = idGenerator.generate(
|
|
512
|
+
'CALL', `new:${constructorName}`, s.module.file,
|
|
513
|
+
newLine, newColumn,
|
|
514
|
+
s.callSiteCounterRef,
|
|
515
|
+
{ useDiscriminator: true, discriminatorKey: `CALL:new:${constructorName}` }
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
s.callSites.push(callInfo);
|
|
520
|
+
} else if (newNode.callee.type === 'MemberExpression') {
|
|
521
|
+
const memberCallee = newNode.callee as MemberExpression;
|
|
522
|
+
const object = memberCallee.object;
|
|
523
|
+
const property = memberCallee.property;
|
|
524
|
+
|
|
525
|
+
if (object.type === 'Identifier' && property.type === 'Identifier') {
|
|
526
|
+
const objectName = (object as Identifier).name;
|
|
527
|
+
const constructorName = (property as Identifier).name;
|
|
528
|
+
const fullName = `${objectName}.${constructorName}`;
|
|
529
|
+
const memberNewLine = getLine(newNode);
|
|
530
|
+
const memberNewColumn = getColumn(newNode);
|
|
531
|
+
|
|
532
|
+
const grafemaIgnore = getGrafemaIgnore(path);
|
|
533
|
+
|
|
534
|
+
const methodCallInfo: MethodCallInfo = {
|
|
535
|
+
id: '', // Placeholder — resolved by generateV2 or set below
|
|
536
|
+
type: 'CALL',
|
|
537
|
+
name: fullName,
|
|
538
|
+
object: objectName,
|
|
539
|
+
method: constructorName,
|
|
540
|
+
file: s.module.file,
|
|
541
|
+
line: memberNewLine,
|
|
542
|
+
column: memberNewColumn,
|
|
543
|
+
parentScopeId,
|
|
544
|
+
isNew: true,
|
|
545
|
+
grafemaIgnore: grafemaIgnore ?? undefined,
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
if (this.sharedIdGenerator) {
|
|
549
|
+
const contentHints: ContentHashHints = {
|
|
550
|
+
arity: newNode.arguments.length,
|
|
551
|
+
firstLiteralArg: undefined // constructor args not used for hash
|
|
552
|
+
};
|
|
553
|
+
this.sharedIdGenerator.generateV2('CALL', `new:${fullName}`, s.module.file, contentHints, methodCallInfo);
|
|
554
|
+
} else {
|
|
555
|
+
const idGenerator = new IdGenerator(s.scopeTracker);
|
|
556
|
+
methodCallInfo.id = idGenerator.generate(
|
|
557
|
+
'CALL', `new:${fullName}`, s.module.file,
|
|
558
|
+
memberNewLine, memberNewColumn,
|
|
559
|
+
s.callSiteCounterRef,
|
|
560
|
+
{ useDiscriminator: true, discriminatorKey: `CALL:new:${fullName}` }
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
s.methodCalls.push(methodCallInfo);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
1516
567
|
}
|
|
1517
568
|
}
|