@grafema/core 0.1.0-alpha.5 → 0.2.0-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/Orchestrator.d.ts +31 -2
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +222 -27
- package/dist/config/ConfigLoader.d.ts +90 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +249 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/core/ASTWorker.d.ts +11 -36
- package/dist/core/ASTWorker.d.ts.map +1 -1
- package/dist/core/ASTWorker.js +93 -99
- package/dist/core/CoverageAnalyzer.d.ts +65 -0
- package/dist/core/CoverageAnalyzer.d.ts.map +1 -0
- package/dist/core/CoverageAnalyzer.js +198 -0
- package/dist/core/FileExplainer.d.ts +101 -0
- package/dist/core/FileExplainer.d.ts.map +1 -0
- package/dist/core/FileExplainer.js +139 -0
- package/dist/core/FileNodeManager.d.ts +40 -0
- package/dist/core/FileNodeManager.d.ts.map +1 -0
- package/dist/core/FileNodeManager.js +84 -0
- package/dist/core/GraphFreshnessChecker.d.ts +33 -0
- package/dist/core/GraphFreshnessChecker.d.ts.map +1 -0
- package/dist/core/GraphFreshnessChecker.js +101 -0
- package/dist/core/HashUtils.d.ts +24 -0
- package/dist/core/HashUtils.d.ts.map +1 -0
- package/dist/core/HashUtils.js +45 -0
- package/dist/core/IncrementalReanalyzer.d.ts +36 -0
- package/dist/core/IncrementalReanalyzer.d.ts.map +1 -0
- package/dist/core/IncrementalReanalyzer.js +132 -0
- package/dist/core/NodeFactory.d.ts +266 -19
- package/dist/core/NodeFactory.d.ts.map +1 -1
- package/dist/core/NodeFactory.js +256 -21
- package/dist/core/ScopeTracker.d.ts +84 -0
- package/dist/core/ScopeTracker.d.ts.map +1 -0
- package/dist/core/ScopeTracker.js +116 -0
- package/dist/core/SemanticId.d.ts +90 -0
- package/dist/core/SemanticId.d.ts.map +1 -0
- package/dist/core/SemanticId.js +115 -0
- package/dist/core/VersionManager.d.ts.map +1 -1
- package/dist/core/VersionManager.js +3 -2
- package/dist/core/nodes/ArgumentExpressionNode.d.ts +43 -0
- package/dist/core/nodes/ArgumentExpressionNode.d.ts.map +1 -0
- package/dist/core/nodes/ArgumentExpressionNode.js +60 -0
- package/dist/core/nodes/ArrayLiteralNode.d.ts +27 -0
- package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -0
- package/dist/core/nodes/ArrayLiteralNode.js +43 -0
- package/dist/core/nodes/BranchNode.d.ts +41 -0
- package/dist/core/nodes/BranchNode.d.ts.map +1 -0
- package/dist/core/nodes/BranchNode.js +82 -0
- package/dist/core/nodes/CallSiteNode.d.ts +30 -2
- package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
- package/dist/core/nodes/CallSiteNode.js +54 -4
- package/dist/core/nodes/CaseNode.d.ts +43 -0
- package/dist/core/nodes/CaseNode.d.ts.map +1 -0
- package/dist/core/nodes/CaseNode.js +81 -0
- package/dist/core/nodes/ClassNode.d.ts +34 -2
- package/dist/core/nodes/ClassNode.d.ts.map +1 -1
- package/dist/core/nodes/ClassNode.js +52 -4
- package/dist/core/nodes/ConstantNode.d.ts +2 -2
- package/dist/core/nodes/ConstantNode.d.ts.map +1 -1
- package/dist/core/nodes/ConstantNode.js +6 -4
- package/dist/core/nodes/ConstructorCallNode.d.ts +51 -0
- package/dist/core/nodes/ConstructorCallNode.d.ts.map +1 -0
- package/dist/core/nodes/ConstructorCallNode.js +171 -0
- package/dist/core/nodes/DatabaseQueryNode.d.ts +3 -2
- package/dist/core/nodes/DatabaseQueryNode.d.ts.map +1 -1
- package/dist/core/nodes/DatabaseQueryNode.js +5 -2
- package/dist/core/nodes/DecoratorNode.d.ts +42 -0
- package/dist/core/nodes/DecoratorNode.d.ts.map +1 -0
- package/dist/core/nodes/DecoratorNode.js +64 -0
- package/dist/core/nodes/EnumNode.d.ts +42 -0
- package/dist/core/nodes/EnumNode.d.ts.map +1 -0
- package/dist/core/nodes/EnumNode.js +56 -0
- package/dist/core/nodes/EventListenerNode.d.ts +4 -4
- package/dist/core/nodes/EventListenerNode.d.ts.map +1 -1
- package/dist/core/nodes/EventListenerNode.js +7 -4
- package/dist/core/nodes/ExportNode.d.ts +38 -2
- package/dist/core/nodes/ExportNode.d.ts.map +1 -1
- package/dist/core/nodes/ExportNode.js +54 -4
- package/dist/core/nodes/ExpressionNode.d.ts +97 -0
- package/dist/core/nodes/ExpressionNode.d.ts.map +1 -0
- package/dist/core/nodes/ExpressionNode.js +180 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts +32 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -0
- package/dist/core/nodes/ExternalModuleNode.js +49 -0
- package/dist/core/nodes/ExternalStdioNode.d.ts +13 -6
- package/dist/core/nodes/ExternalStdioNode.d.ts.map +1 -1
- package/dist/core/nodes/ExternalStdioNode.js +15 -8
- package/dist/core/nodes/FunctionNode.d.ts +36 -0
- package/dist/core/nodes/FunctionNode.d.ts.map +1 -1
- package/dist/core/nodes/FunctionNode.js +80 -1
- package/dist/core/nodes/HttpRequestNode.d.ts +4 -4
- package/dist/core/nodes/HttpRequestNode.d.ts.map +1 -1
- package/dist/core/nodes/HttpRequestNode.js +7 -4
- package/dist/core/nodes/ImportNode.d.ts +28 -6
- package/dist/core/nodes/ImportNode.d.ts.map +1 -1
- package/dist/core/nodes/ImportNode.js +43 -8
- package/dist/core/nodes/InterfaceNode.d.ts +46 -0
- package/dist/core/nodes/InterfaceNode.d.ts.map +1 -0
- package/dist/core/nodes/InterfaceNode.js +57 -0
- package/dist/core/nodes/IssueNode.d.ts +73 -0
- package/dist/core/nodes/IssueNode.d.ts.map +1 -0
- package/dist/core/nodes/IssueNode.js +129 -0
- package/dist/core/nodes/LiteralNode.d.ts +2 -2
- package/dist/core/nodes/LiteralNode.d.ts.map +1 -1
- package/dist/core/nodes/LiteralNode.js +6 -4
- package/dist/core/nodes/MethodCallNode.d.ts +32 -2
- package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodCallNode.js +57 -4
- package/dist/core/nodes/MethodNode.d.ts +34 -2
- package/dist/core/nodes/MethodNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodNode.js +55 -3
- package/dist/core/nodes/ModuleNode.d.ts +31 -0
- package/dist/core/nodes/ModuleNode.d.ts.map +1 -1
- package/dist/core/nodes/ModuleNode.js +37 -0
- package/dist/core/nodes/NetworkRequestNode.d.ts +54 -0
- package/dist/core/nodes/NetworkRequestNode.d.ts.map +1 -0
- package/dist/core/nodes/NetworkRequestNode.js +65 -0
- package/dist/core/nodes/ObjectLiteralNode.d.ts +27 -0
- package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -0
- package/dist/core/nodes/ObjectLiteralNode.js +43 -0
- package/dist/core/nodes/ParameterNode.d.ts +2 -2
- package/dist/core/nodes/ParameterNode.d.ts.map +1 -1
- package/dist/core/nodes/ParameterNode.js +5 -3
- package/dist/core/nodes/ScopeNode.d.ts +31 -0
- package/dist/core/nodes/ScopeNode.d.ts.map +1 -1
- package/dist/core/nodes/ScopeNode.js +49 -0
- package/dist/core/nodes/TypeNode.d.ts +36 -0
- package/dist/core/nodes/TypeNode.d.ts.map +1 -0
- package/dist/core/nodes/TypeNode.js +55 -0
- package/dist/core/nodes/VariableDeclarationNode.d.ts +29 -2
- package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
- package/dist/core/nodes/VariableDeclarationNode.js +48 -4
- package/dist/core/nodes/index.d.ts +15 -1
- package/dist/core/nodes/index.d.ts.map +1 -1
- package/dist/core/nodes/index.js +17 -0
- package/dist/data/builtins/BuiltinRegistry.d.ts +78 -0
- package/dist/data/builtins/BuiltinRegistry.d.ts.map +1 -0
- package/dist/data/builtins/BuiltinRegistry.js +110 -0
- package/dist/data/builtins/definitions.d.ts +28 -0
- package/dist/data/builtins/definitions.d.ts.map +1 -0
- package/dist/data/builtins/definitions.js +250 -0
- package/dist/data/builtins/index.d.ts +10 -0
- package/dist/data/builtins/index.d.ts.map +1 -0
- package/dist/data/builtins/index.js +8 -0
- package/dist/data/builtins/jsGlobals.d.ts +18 -0
- package/dist/data/builtins/jsGlobals.d.ts.map +1 -0
- package/dist/data/builtins/jsGlobals.js +26 -0
- package/dist/data/builtins/types.d.ts +34 -0
- package/dist/data/builtins/types.d.ts.map +1 -0
- package/dist/data/builtins/types.js +7 -0
- package/dist/data/globals/definitions.d.ts +27 -0
- package/dist/data/globals/definitions.d.ts.map +1 -0
- package/dist/data/globals/definitions.js +117 -0
- package/dist/data/globals/index.d.ts +36 -0
- package/dist/data/globals/index.d.ts.map +1 -0
- package/dist/data/globals/index.js +52 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts +98 -0
- package/dist/diagnostics/DiagnosticCollector.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticCollector.js +129 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts +100 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticReporter.js +247 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts +31 -0
- package/dist/diagnostics/DiagnosticWriter.d.ts.map +1 -0
- package/dist/diagnostics/DiagnosticWriter.js +43 -0
- package/dist/diagnostics/index.d.ts +14 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +11 -0
- package/dist/errors/GrafemaError.d.ts +161 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -0
- package/dist/errors/GrafemaError.js +181 -0
- package/dist/index.d.ts +73 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -1
- package/dist/logging/Logger.d.ts +48 -0
- package/dist/logging/Logger.d.ts.map +1 -0
- package/dist/logging/Logger.js +134 -0
- package/dist/plugins/Plugin.d.ts +5 -1
- package/dist/plugins/Plugin.d.ts.map +1 -1
- package/dist/plugins/Plugin.js +33 -0
- package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.js +14 -6
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.js +29 -19
- package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts +148 -0
- package/dist/plugins/analysis/ExpressResponseAnalyzer.d.ts.map +1 -0
- package/dist/plugins/analysis/ExpressResponseAnalyzer.js +495 -0
- package/dist/plugins/analysis/ExpressRouteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressRouteAnalyzer.js +71 -29
- package/dist/plugins/analysis/FetchAnalyzer.d.ts +41 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.js +187 -19
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts +6 -3
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.d.ts.map +1 -1
- package/dist/plugins/analysis/IncrementalAnalysisPlugin.js +76 -80
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts +313 -19
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +3430 -503
- package/dist/plugins/analysis/ReactAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ReactAnalyzer.js +56 -57
- package/dist/plugins/analysis/RustAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/RustAnalyzer.js +16 -11
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.js +11 -7
- package/dist/plugins/analysis/ServiceLayerAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ServiceLayerAnalyzer.js +21 -9
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts +9 -0
- package/dist/plugins/analysis/SocketIOAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SocketIOAnalyzer.js +117 -21
- package/dist/plugins/analysis/SystemDbAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SystemDbAnalyzer.js +15 -5
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts +207 -4
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +1527 -316
- package/dist/plugins/analysis/ast/IdGenerator.d.ts +105 -0
- package/dist/plugins/analysis/ast/IdGenerator.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/IdGenerator.js +116 -0
- package/dist/plugins/analysis/ast/types.d.ts +470 -5
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts +33 -0
- package/dist/plugins/analysis/ast/utils/createParameterNodes.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/createParameterNodes.js +89 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts +6 -0
- package/dist/plugins/analysis/ast/utils/index.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/index.js +5 -0
- package/dist/plugins/analysis/ast/utils/location.d.ts +87 -0
- package/dist/plugins/analysis/ast/utils/location.d.ts.map +1 -0
- package/dist/plugins/analysis/ast/utils/location.js +78 -0
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +14 -5
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.js +6 -5
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +100 -9
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +674 -125
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts +4 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ClassVisitor.js +72 -32
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +14 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +190 -63
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts +4 -0
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ImportExportVisitor.js +112 -8
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts +12 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/TypeScriptVisitor.js +36 -14
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +20 -2
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +243 -45
- package/dist/plugins/discovery/MonorepoServiceDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/MonorepoServiceDiscovery.js +3 -2
- package/dist/plugins/discovery/SimpleProjectDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/SimpleProjectDiscovery.js +5 -1
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts +22 -0
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -0
- package/dist/plugins/discovery/WorkspaceDiscovery.js +141 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts +46 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.d.ts.map +1 -0
- package/dist/plugins/discovery/resolveSourceEntrypoint.js +86 -0
- package/dist/plugins/discovery/workspaces/detector.d.ts +21 -0
- package/dist/plugins/discovery/workspaces/detector.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/detector.js +49 -0
- package/dist/plugins/discovery/workspaces/globResolver.d.ts +35 -0
- package/dist/plugins/discovery/workspaces/globResolver.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/globResolver.js +184 -0
- package/dist/plugins/discovery/workspaces/index.d.ts +9 -0
- package/dist/plugins/discovery/workspaces/index.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/index.js +8 -0
- package/dist/plugins/discovery/workspaces/parsers.d.ts +38 -0
- package/dist/plugins/discovery/workspaces/parsers.d.ts.map +1 -0
- package/dist/plugins/discovery/workspaces/parsers.js +80 -0
- package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
- package/dist/plugins/enrichment/AliasTracker.js +29 -8
- package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts +32 -0
- package/dist/plugins/enrichment/ArgumentParameterLinker.d.ts.map +1 -0
- package/dist/plugins/enrichment/ArgumentParameterLinker.js +175 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts +51 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.d.ts.map +1 -0
- package/dist/plugins/enrichment/ClosureCaptureEnricher.js +205 -0
- package/dist/plugins/enrichment/ExternalCallResolver.d.ts +42 -0
- package/dist/plugins/enrichment/ExternalCallResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/ExternalCallResolver.js +213 -0
- package/dist/plugins/enrichment/FunctionCallResolver.d.ts +58 -0
- package/dist/plugins/enrichment/FunctionCallResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/FunctionCallResolver.js +340 -0
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts +16 -3
- package/dist/plugins/enrichment/HTTPConnectionEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/HTTPConnectionEnricher.js +78 -27
- package/dist/plugins/enrichment/ImportExportLinker.d.ts.map +1 -1
- package/dist/plugins/enrichment/ImportExportLinker.js +23 -6
- package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MethodCallResolver.js +33 -13
- package/dist/plugins/enrichment/MountPointResolver.d.ts +14 -12
- package/dist/plugins/enrichment/MountPointResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MountPointResolver.js +173 -147
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts +44 -0
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.d.ts.map +1 -0
- package/dist/plugins/enrichment/NodejsBuiltinsResolver.js +271 -0
- package/dist/plugins/enrichment/PrefixEvaluator.d.ts.map +1 -1
- package/dist/plugins/enrichment/PrefixEvaluator.js +16 -7
- package/dist/plugins/enrichment/RustFFIEnricher.d.ts.map +1 -1
- package/dist/plugins/enrichment/RustFFIEnricher.js +6 -5
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts +22 -27
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +185 -143
- package/dist/plugins/indexing/IncrementalModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/IncrementalModuleIndexer.js +23 -14
- package/dist/plugins/indexing/JSModuleIndexer.d.ts +15 -0
- package/dist/plugins/indexing/JSModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/JSModuleIndexer.js +121 -31
- package/dist/plugins/indexing/RustModuleIndexer.d.ts +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.d.ts.map +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.js +8 -7
- package/dist/plugins/indexing/ServiceDetector.d.ts +10 -0
- package/dist/plugins/indexing/ServiceDetector.d.ts.map +1 -1
- package/dist/plugins/indexing/ServiceDetector.js +28 -15
- package/dist/plugins/validation/BrokenImportValidator.d.ts +31 -0
- package/dist/plugins/validation/BrokenImportValidator.d.ts.map +1 -0
- package/dist/plugins/validation/BrokenImportValidator.js +249 -0
- package/dist/plugins/validation/CallResolverValidator.d.ts +21 -10
- package/dist/plugins/validation/CallResolverValidator.d.ts.map +1 -1
- package/dist/plugins/validation/CallResolverValidator.js +103 -77
- package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
- package/dist/plugins/validation/DataFlowValidator.js +62 -49
- package/dist/plugins/validation/EvalBanValidator.d.ts.map +1 -1
- package/dist/plugins/validation/EvalBanValidator.js +17 -16
- package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
- package/dist/plugins/validation/GraphConnectivityValidator.js +44 -24
- package/dist/plugins/validation/NodeCreationValidator.d.ts +85 -0
- package/dist/plugins/validation/NodeCreationValidator.d.ts.map +1 -0
- package/dist/plugins/validation/NodeCreationValidator.js +415 -0
- package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
- package/dist/plugins/validation/SQLInjectionValidator.js +61 -19
- package/dist/plugins/validation/ShadowingDetector.d.ts.map +1 -1
- package/dist/plugins/validation/ShadowingDetector.js +6 -5
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.d.ts.map +1 -1
- package/dist/plugins/validation/TypeScriptDeadCodeValidator.js +12 -11
- package/dist/plugins/vcs/GitPlugin.d.ts.map +1 -1
- package/dist/plugins/vcs/GitPlugin.js +10 -12
- package/dist/plugins/vcs/VCSPlugin.d.ts +3 -2
- package/dist/plugins/vcs/VCSPlugin.d.ts.map +1 -1
- package/dist/plugins/vcs/VCSPlugin.js +5 -5
- package/dist/queries/findCallsInFunction.d.ts +52 -0
- package/dist/queries/findCallsInFunction.d.ts.map +1 -0
- package/dist/queries/findCallsInFunction.js +135 -0
- package/dist/queries/findContainingFunction.d.ts +45 -0
- package/dist/queries/findContainingFunction.d.ts.map +1 -0
- package/dist/queries/findContainingFunction.js +54 -0
- package/dist/queries/index.d.ts +14 -0
- package/dist/queries/index.d.ts.map +1 -0
- package/dist/queries/index.js +11 -0
- package/dist/queries/traceValues.d.ts +70 -0
- package/dist/queries/traceValues.d.ts.map +1 -0
- package/dist/queries/traceValues.js +299 -0
- package/dist/queries/types.d.ts +163 -0
- package/dist/queries/types.d.ts.map +1 -0
- package/dist/queries/types.js +9 -0
- package/dist/schema/GraphSchemaExtractor.d.ts +53 -0
- package/dist/schema/GraphSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/GraphSchemaExtractor.js +124 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts +73 -0
- package/dist/schema/InterfaceSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/InterfaceSchemaExtractor.js +112 -0
- package/dist/schema/index.d.ts +5 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +2 -0
- package/dist/storage/backends/RFDBServerBackend.d.ts +21 -34
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +72 -62
- package/dist/storage/backends/typeValidation.d.ts.map +1 -1
- package/dist/storage/backends/typeValidation.js +1 -0
- package/dist/validation/PathValidator.d.ts +1 -2
- package/dist/validation/PathValidator.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/Orchestrator.ts +272 -27
- package/src/config/ConfigLoader.ts +354 -0
- package/src/config/index.ts +5 -0
- package/src/core/ASTWorker.ts +143 -139
- package/src/core/CoverageAnalyzer.ts +243 -0
- package/src/core/FileExplainer.ts +179 -0
- package/src/core/FileNodeManager.ts +100 -0
- package/src/core/GraphFreshnessChecker.ts +143 -0
- package/src/core/HashUtils.ts +48 -0
- package/src/core/IncrementalReanalyzer.ts +192 -0
- package/src/core/NodeFactory.ts +470 -23
- package/src/core/ScopeTracker.ts +154 -0
- package/src/core/SemanticId.ts +192 -0
- package/src/core/VersionManager.ts +3 -2
- package/src/core/nodes/ArgumentExpressionNode.ts +89 -0
- package/src/core/nodes/ArrayLiteralNode.ts +66 -0
- package/src/core/nodes/BranchNode.ts +113 -0
- package/src/core/nodes/CallSiteNode.ts +64 -4
- package/src/core/nodes/CaseNode.ts +123 -0
- package/src/core/nodes/ClassNode.ts +67 -4
- package/src/core/nodes/ConstantNode.ts +5 -4
- package/src/core/nodes/ConstructorCallNode.ts +217 -0
- package/src/core/nodes/DatabaseQueryNode.ts +5 -1
- package/src/core/nodes/DecoratorNode.ts +92 -0
- package/src/core/nodes/EnumNode.ts +87 -0
- package/src/core/nodes/EventListenerNode.ts +7 -4
- package/src/core/nodes/ExportNode.ts +74 -4
- package/src/core/nodes/ExpressionNode.ts +232 -0
- package/src/core/nodes/ExternalModuleNode.ts +65 -0
- package/src/core/nodes/ExternalStdioNode.ts +17 -9
- package/src/core/nodes/FunctionNode.ts +101 -1
- package/src/core/nodes/HttpRequestNode.ts +7 -4
- package/src/core/nodes/ImportNode.ts +62 -13
- package/src/core/nodes/InterfaceNode.ts +92 -0
- package/src/core/nodes/IssueNode.ts +177 -0
- package/src/core/nodes/LiteralNode.ts +5 -4
- package/src/core/nodes/MethodCallNode.ts +70 -4
- package/src/core/nodes/MethodNode.ts +68 -3
- package/src/core/nodes/ModuleNode.ts +50 -0
- package/src/core/nodes/NetworkRequestNode.ts +77 -0
- package/src/core/nodes/ObjectLiteralNode.ts +66 -0
- package/src/core/nodes/ParameterNode.ts +4 -3
- package/src/core/nodes/ScopeNode.ts +65 -0
- package/src/core/nodes/TypeNode.ts +79 -0
- package/src/core/nodes/VariableDeclarationNode.ts +58 -4
- package/src/core/nodes/index.ts +21 -1
- package/src/data/builtins/BuiltinRegistry.ts +124 -0
- package/src/data/builtins/definitions.ts +267 -0
- package/src/data/builtins/index.ts +10 -0
- package/src/data/builtins/jsGlobals.ts +28 -0
- package/src/data/builtins/types.ts +36 -0
- package/src/data/globals/definitions.ts +156 -0
- package/src/data/globals/index.ts +66 -0
- package/src/diagnostics/DiagnosticCollector.ts +163 -0
- package/src/diagnostics/DiagnosticReporter.ts +324 -0
- package/src/diagnostics/DiagnosticWriter.ts +50 -0
- package/src/diagnostics/index.ts +16 -0
- package/src/errors/GrafemaError.ts +239 -0
- package/src/index.ts +193 -1
- package/src/logging/Logger.ts +152 -0
- package/src/plugins/Plugin.ts +42 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +16 -8
- package/src/plugins/analysis/ExpressAnalyzer.ts +33 -19
- package/src/plugins/analysis/ExpressResponseAnalyzer.ts +636 -0
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +76 -36
- package/src/plugins/analysis/FetchAnalyzer.ts +232 -21
- package/src/plugins/analysis/IncrementalAnalysisPlugin.ts +84 -101
- package/src/plugins/analysis/JSASTAnalyzer.ts +4265 -587
- package/src/plugins/analysis/ReactAnalyzer.ts +57 -57
- package/src/plugins/analysis/RustAnalyzer.ts +16 -11
- package/src/plugins/analysis/SQLiteAnalyzer.ts +13 -7
- package/src/plugins/analysis/ServiceLayerAnalyzer.ts +22 -16
- package/src/plugins/analysis/SocketIOAnalyzer.ts +151 -28
- package/src/plugins/analysis/SystemDbAnalyzer.ts +16 -11
- package/src/plugins/analysis/ast/GraphBuilder.ts +1947 -327
- package/src/plugins/analysis/ast/IdGenerator.ts +177 -0
- package/src/plugins/analysis/ast/types.ts +596 -6
- package/src/plugins/analysis/ast/utils/createParameterNodes.ts +104 -0
- package/src/plugins/analysis/ast/utils/index.ts +12 -0
- package/src/plugins/analysis/ast/utils/location.ts +103 -0
- package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +19 -8
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +924 -83
- package/src/plugins/analysis/ast/visitors/ClassVisitor.ts +97 -44
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +234 -93
- package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +124 -9
- package/src/plugins/analysis/ast/visitors/TypeScriptVisitor.ts +41 -14
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +294 -49
- package/src/plugins/discovery/MonorepoServiceDiscovery.ts +3 -2
- package/src/plugins/discovery/SimpleProjectDiscovery.ts +6 -1
- package/src/plugins/discovery/WorkspaceDiscovery.ts +184 -0
- package/src/plugins/discovery/resolveSourceEntrypoint.ts +103 -0
- package/src/plugins/discovery/workspaces/detector.ts +63 -0
- package/src/plugins/discovery/workspaces/globResolver.ts +229 -0
- package/src/plugins/discovery/workspaces/index.ts +23 -0
- package/src/plugins/discovery/workspaces/parsers.ts +99 -0
- package/src/plugins/enrichment/AliasTracker.ts +35 -8
- package/src/plugins/enrichment/ArgumentParameterLinker.ts +240 -0
- package/src/plugins/enrichment/ClosureCaptureEnricher.ts +267 -0
- package/src/plugins/enrichment/ExternalCallResolver.ts +262 -0
- package/src/plugins/enrichment/FunctionCallResolver.ts +456 -0
- package/src/plugins/enrichment/HTTPConnectionEnricher.ts +84 -27
- package/src/plugins/enrichment/ImportExportLinker.ts +24 -6
- package/src/plugins/enrichment/MethodCallResolver.ts +39 -13
- package/src/plugins/enrichment/MountPointResolver.ts +208 -195
- package/src/plugins/enrichment/NodejsBuiltinsResolver.ts +365 -0
- package/src/plugins/enrichment/PrefixEvaluator.ts +16 -7
- package/src/plugins/enrichment/RustFFIEnricher.ts +6 -5
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +209 -189
- package/src/plugins/indexing/IncrementalModuleIndexer.ts +23 -14
- package/src/plugins/indexing/JSModuleIndexer.ts +140 -34
- package/src/plugins/indexing/RustModuleIndexer.ts +8 -7
- package/src/plugins/validation/BrokenImportValidator.ts +325 -0
- package/src/plugins/validation/CallResolverValidator.ts +131 -110
- package/src/plugins/validation/DataFlowValidator.ts +88 -67
- package/src/plugins/validation/EvalBanValidator.ts +17 -16
- package/src/plugins/validation/GraphConnectivityValidator.ts +58 -24
- package/src/plugins/validation/NodeCreationValidator.ts +554 -0
- package/src/plugins/validation/SQLInjectionValidator.ts +63 -20
- package/src/plugins/validation/ShadowingDetector.ts +6 -5
- package/src/plugins/validation/TypeScriptDeadCodeValidator.ts +12 -11
- package/src/plugins/vcs/GitPlugin.ts +40 -12
- package/src/plugins/vcs/VCSPlugin.ts +7 -5
- package/src/queries/README.md +46 -0
- package/src/queries/findCallsInFunction.ts +206 -0
- package/src/queries/findContainingFunction.ts +83 -0
- package/src/queries/index.ts +23 -0
- package/src/queries/traceValues.ts +398 -0
- package/src/queries/types.ts +187 -0
- package/src/schema/GraphSchemaExtractor.ts +177 -0
- package/src/schema/InterfaceSchemaExtractor.ts +173 -0
- package/src/schema/index.ts +5 -0
- package/src/storage/backends/RFDBServerBackend.ts +100 -98
- package/src/storage/backends/typeValidation.ts +1 -0
- package/src/validation/PathValidator.ts +1 -1
- package/dist/core/AnalysisWorker.d.ts +0 -14
- package/dist/core/AnalysisWorker.d.ts.map +0 -1
- package/dist/core/AnalysisWorker.js +0 -307
- package/dist/core/ParallelAnalyzer.d.ts +0 -120
- package/dist/core/ParallelAnalyzer.d.ts.map +0 -1
- package/dist/core/ParallelAnalyzer.js +0 -331
- package/dist/core/QueueWorker.d.ts +0 -12
- package/dist/core/QueueWorker.d.ts.map +0 -1
- package/dist/core/QueueWorker.js +0 -567
- package/dist/core/RFDBClient.d.ts +0 -179
- package/dist/core/RFDBClient.d.ts.map +0 -1
- package/dist/core/RFDBClient.js +0 -429
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts +0 -19
- package/dist/plugins/discovery/ZonServiceDiscovery.d.ts.map +0 -1
- package/dist/plugins/discovery/ZonServiceDiscovery.js +0 -204
- package/src/core/AnalysisWorker.ts +0 -410
- package/src/core/ParallelAnalyzer.ts +0 -476
- package/src/core/QueueWorker.ts +0 -780
- package/src/plugins/indexing/ServiceDetector.ts +0 -230
|
@@ -11,43 +11,29 @@ import type {
|
|
|
11
11
|
Function,
|
|
12
12
|
FunctionDeclaration,
|
|
13
13
|
ArrowFunctionExpression,
|
|
14
|
+
FunctionExpression,
|
|
14
15
|
Identifier,
|
|
15
16
|
AssignmentPattern,
|
|
16
17
|
RestElement,
|
|
17
|
-
VariableDeclarator
|
|
18
|
+
VariableDeclarator,
|
|
19
|
+
Comment,
|
|
20
|
+
NewExpression
|
|
18
21
|
} from '@babel/types';
|
|
19
22
|
import type { NodePath } from '@babel/traverse';
|
|
20
23
|
import { ASTVisitor, type VisitorModule, type VisitorCollections, type VisitorHandlers, type CounterRef } from './ASTVisitor.js';
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Parameter node info
|
|
32
|
-
*/
|
|
33
|
-
interface ParameterInfo {
|
|
34
|
-
id: string;
|
|
35
|
-
type: 'PARAMETER';
|
|
36
|
-
name: string;
|
|
37
|
-
file: string;
|
|
38
|
-
line: number;
|
|
39
|
-
index: number;
|
|
40
|
-
hasDefault?: boolean;
|
|
41
|
-
isRest?: boolean;
|
|
42
|
-
parentFunctionId: string;
|
|
43
|
-
}
|
|
24
|
+
import { typeNodeToString } from './TypeScriptVisitor.js';
|
|
25
|
+
import { ScopeTracker } from '../../../../core/ScopeTracker.js';
|
|
26
|
+
import { IdGenerator } from '../IdGenerator.js';
|
|
27
|
+
import { createParameterNodes } from '../utils/createParameterNodes.js';
|
|
28
|
+
import { getLine, getColumn } from '../utils/location.js';
|
|
29
|
+
import type { ParameterInfo, PromiseExecutorContext } from '../types.js';
|
|
30
|
+
import { ConstructorCallNode } from '../../../../core/nodes/ConstructorCallNode.js';
|
|
44
31
|
|
|
45
32
|
/**
|
|
46
33
|
* Function node info
|
|
47
34
|
*/
|
|
48
35
|
interface FunctionInfo {
|
|
49
36
|
id: string;
|
|
50
|
-
stableId: string;
|
|
51
37
|
type: 'FUNCTION';
|
|
52
38
|
name: string;
|
|
53
39
|
file: string;
|
|
@@ -56,6 +42,11 @@ interface FunctionInfo {
|
|
|
56
42
|
async: boolean;
|
|
57
43
|
generator?: boolean;
|
|
58
44
|
arrowFunction?: boolean;
|
|
45
|
+
params?: string[];
|
|
46
|
+
paramTypes?: string[];
|
|
47
|
+
returnType?: string;
|
|
48
|
+
signature?: string;
|
|
49
|
+
jsdocSummary?: string;
|
|
59
50
|
}
|
|
60
51
|
|
|
61
52
|
/**
|
|
@@ -84,19 +75,23 @@ export type AnalyzeFunctionBodyCallback = (
|
|
|
84
75
|
|
|
85
76
|
export class FunctionVisitor extends ASTVisitor {
|
|
86
77
|
private analyzeFunctionBody: AnalyzeFunctionBodyCallback;
|
|
78
|
+
private scopeTracker: ScopeTracker;
|
|
87
79
|
|
|
88
80
|
/**
|
|
89
81
|
* @param module - Current module being analyzed
|
|
90
82
|
* @param collections - Must contain arrays and counter refs
|
|
91
83
|
* @param analyzeFunctionBody - Callback to analyze function internals
|
|
84
|
+
* @param scopeTracker - REQUIRED for semantic ID generation
|
|
92
85
|
*/
|
|
93
86
|
constructor(
|
|
94
87
|
module: VisitorModule,
|
|
95
88
|
collections: VisitorCollections,
|
|
96
|
-
analyzeFunctionBody: AnalyzeFunctionBodyCallback
|
|
89
|
+
analyzeFunctionBody: AnalyzeFunctionBodyCallback,
|
|
90
|
+
scopeTracker: ScopeTracker
|
|
97
91
|
) {
|
|
98
92
|
super(module, collections);
|
|
99
93
|
this.analyzeFunctionBody = analyzeFunctionBody;
|
|
94
|
+
this.scopeTracker = scopeTracker;
|
|
100
95
|
}
|
|
101
96
|
|
|
102
97
|
getHandlers(): VisitorHandlers {
|
|
@@ -105,76 +100,109 @@ export class FunctionVisitor extends ASTVisitor {
|
|
|
105
100
|
const parameters = this.collections.parameters ?? [];
|
|
106
101
|
const scopes = this.collections.scopes ?? [];
|
|
107
102
|
const functionCounterRef = (this.collections.functionCounterRef ?? { value: 0 }) as CounterRef;
|
|
108
|
-
const
|
|
103
|
+
const scopeTracker = this.scopeTracker;
|
|
109
104
|
|
|
110
105
|
const analyzeFunctionBody = this.analyzeFunctionBody;
|
|
111
106
|
const collections = this.collections;
|
|
112
107
|
|
|
113
108
|
// Helper function to generate stable anonymous function name
|
|
114
109
|
const generateAnonymousName = (): string => {
|
|
115
|
-
|
|
116
|
-
const index = moduleScopeCtx.siblingCounters.get('anonymous') || 0;
|
|
117
|
-
moduleScopeCtx.siblingCounters.set('anonymous', index + 1);
|
|
110
|
+
const index = scopeTracker.getSiblingIndex('anonymous');
|
|
118
111
|
return `anonymous[${index}]`;
|
|
119
112
|
};
|
|
120
113
|
|
|
121
|
-
// Helper function to
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
): void => {
|
|
128
|
-
if (!parameters) return; // Guard for backward compatibility
|
|
129
|
-
|
|
130
|
-
params.forEach((param, index) => {
|
|
131
|
-
// Handle different parameter types
|
|
114
|
+
// Helper function to extract parameter names and types from function params
|
|
115
|
+
const extractParamInfo = (params: Node[]): { names: string[]; types: string[] } => {
|
|
116
|
+
const names: string[] = [];
|
|
117
|
+
const types: string[] = [];
|
|
118
|
+
|
|
119
|
+
params.forEach((param) => {
|
|
132
120
|
if (param.type === 'Identifier') {
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
file: file,
|
|
139
|
-
line: param.loc?.start.line || line,
|
|
140
|
-
index: index,
|
|
141
|
-
parentFunctionId: functionId
|
|
142
|
-
});
|
|
121
|
+
const id = param as Identifier;
|
|
122
|
+
names.push(id.name);
|
|
123
|
+
// Check for type annotation
|
|
124
|
+
const typeAnnotation = (id as any).typeAnnotation?.typeAnnotation;
|
|
125
|
+
types.push(typeAnnotation ? typeNodeToString(typeAnnotation) : 'any');
|
|
143
126
|
} else if (param.type === 'AssignmentPattern') {
|
|
144
|
-
// Default parameter: function(a = 1)
|
|
145
127
|
const assignmentParam = param as AssignmentPattern;
|
|
146
128
|
if (assignmentParam.left.type === 'Identifier') {
|
|
147
|
-
const
|
|
148
|
-
(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
name: assignmentParam.left.name,
|
|
152
|
-
file: file,
|
|
153
|
-
line: assignmentParam.left.loc?.start.line || line,
|
|
154
|
-
index: index,
|
|
155
|
-
hasDefault: true,
|
|
156
|
-
parentFunctionId: functionId
|
|
157
|
-
});
|
|
129
|
+
const id = assignmentParam.left as Identifier;
|
|
130
|
+
names.push(id.name + '?');
|
|
131
|
+
const typeAnnotation = (id as any).typeAnnotation?.typeAnnotation;
|
|
132
|
+
types.push(typeAnnotation ? typeNodeToString(typeAnnotation) : 'any');
|
|
158
133
|
}
|
|
159
|
-
} else if (
|
|
160
|
-
// Rest parameter: function(...args)
|
|
134
|
+
} else if (param.type === 'RestElement') {
|
|
161
135
|
const restParam = param as unknown as RestElement;
|
|
162
136
|
if (restParam.argument.type === 'Identifier') {
|
|
163
|
-
const
|
|
164
|
-
(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
name: restParam.argument.name,
|
|
168
|
-
file: file,
|
|
169
|
-
line: restParam.argument.loc?.start.line || line,
|
|
170
|
-
index: index,
|
|
171
|
-
isRest: true,
|
|
172
|
-
parentFunctionId: functionId
|
|
173
|
-
});
|
|
137
|
+
const id = restParam.argument as Identifier;
|
|
138
|
+
names.push('...' + id.name);
|
|
139
|
+
const typeAnnotation = (id as any).typeAnnotation?.typeAnnotation;
|
|
140
|
+
types.push(typeAnnotation ? typeNodeToString(typeAnnotation) : 'any[]');
|
|
174
141
|
}
|
|
175
142
|
}
|
|
176
|
-
// ObjectPattern and ArrayPattern (destructuring parameters) can be added later
|
|
177
143
|
});
|
|
144
|
+
|
|
145
|
+
return { names, types };
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// Helper function to extract return type from function
|
|
149
|
+
const extractReturnType = (node: Function): string => {
|
|
150
|
+
const returnTypeAnnotation = (node as any).returnType?.typeAnnotation;
|
|
151
|
+
if (returnTypeAnnotation) {
|
|
152
|
+
return typeNodeToString(returnTypeAnnotation);
|
|
153
|
+
}
|
|
154
|
+
return 'void';
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Helper function to extract JSDoc summary from leading comments
|
|
158
|
+
const extractJsdocSummary = (node: Node): string | undefined => {
|
|
159
|
+
const comments = node.leadingComments as Comment[] | null | undefined;
|
|
160
|
+
if (!comments || comments.length === 0) return undefined;
|
|
161
|
+
|
|
162
|
+
// Find the last block comment that looks like JSDoc
|
|
163
|
+
for (let i = comments.length - 1; i >= 0; i--) {
|
|
164
|
+
const comment = comments[i];
|
|
165
|
+
if (comment.type === 'CommentBlock' && comment.value.startsWith('*')) {
|
|
166
|
+
// Parse JSDoc - get first non-empty line after the opening
|
|
167
|
+
const lines = comment.value.split('\n');
|
|
168
|
+
for (const line of lines) {
|
|
169
|
+
const trimmed = line.replace(/^\s*\*\s?/, '').trim();
|
|
170
|
+
// Skip empty lines and @tags
|
|
171
|
+
if (trimmed && !trimmed.startsWith('@')) {
|
|
172
|
+
return trimmed.slice(0, 200); // Limit length
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return undefined;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Helper function to build function signature
|
|
181
|
+
const buildSignature = (
|
|
182
|
+
params: string[],
|
|
183
|
+
paramTypes: string[],
|
|
184
|
+
returnType: string,
|
|
185
|
+
isAsync: boolean
|
|
186
|
+
): string => {
|
|
187
|
+
const paramParts = params.map((name, i) => {
|
|
188
|
+
const type = paramTypes[i] || 'any';
|
|
189
|
+
// Handle rest params
|
|
190
|
+
if (name.startsWith('...')) {
|
|
191
|
+
return `${name}: ${type}`;
|
|
192
|
+
}
|
|
193
|
+
// Handle optional params (with ?)
|
|
194
|
+
if (name.endsWith('?')) {
|
|
195
|
+
return `${name}: ${type}`;
|
|
196
|
+
}
|
|
197
|
+
return `${name}: ${type}`;
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
const paramsStr = `(${paramParts.join(', ')})`;
|
|
201
|
+
const retStr = isAsync && !returnType.startsWith('Promise')
|
|
202
|
+
? `Promise<${returnType}>`
|
|
203
|
+
: returnType;
|
|
204
|
+
|
|
205
|
+
return `${paramsStr} => ${retStr}`;
|
|
178
206
|
};
|
|
179
207
|
|
|
180
208
|
return {
|
|
@@ -183,24 +211,43 @@ export class FunctionVisitor extends ASTVisitor {
|
|
|
183
211
|
const node = path.node as FunctionDeclaration;
|
|
184
212
|
if (!node.id) return; // Skip anonymous function declarations
|
|
185
213
|
|
|
186
|
-
const
|
|
214
|
+
const isAsync = node.async || false;
|
|
215
|
+
|
|
216
|
+
const line = getLine(node);
|
|
217
|
+
|
|
218
|
+
// Generate ID using centralized IdGenerator
|
|
219
|
+
const idGenerator = new IdGenerator(scopeTracker);
|
|
220
|
+
const functionId = idGenerator.generateSimple('FUNCTION', node.id.name, module.file, line);
|
|
221
|
+
|
|
222
|
+
// Extract type info
|
|
223
|
+
const { names: paramNames, types: paramTypes } = extractParamInfo(node.params);
|
|
224
|
+
const returnType = extractReturnType(node);
|
|
225
|
+
const jsdocSummary = extractJsdocSummary(node);
|
|
226
|
+
const signature = buildSignature(paramNames, paramTypes, returnType, isAsync);
|
|
187
227
|
|
|
188
228
|
(functions as FunctionInfo[]).push({
|
|
189
229
|
id: functionId,
|
|
190
|
-
stableId: functionId,
|
|
191
230
|
type: 'FUNCTION',
|
|
192
231
|
name: node.id.name,
|
|
193
232
|
file: module.file,
|
|
194
|
-
line
|
|
195
|
-
async:
|
|
196
|
-
generator: node.generator || false
|
|
233
|
+
line,
|
|
234
|
+
async: isAsync,
|
|
235
|
+
generator: node.generator || false,
|
|
236
|
+
params: paramNames,
|
|
237
|
+
paramTypes,
|
|
238
|
+
returnType,
|
|
239
|
+
signature,
|
|
240
|
+
jsdocSummary
|
|
197
241
|
});
|
|
198
242
|
|
|
243
|
+
// Enter function scope BEFORE creating parameters (semantic IDs need function context)
|
|
244
|
+
scopeTracker.enterScope(node.id.name, 'FUNCTION');
|
|
245
|
+
|
|
199
246
|
// Create PARAMETER nodes for function parameters
|
|
200
|
-
createParameterNodes(node.params, functionId, module.file, node
|
|
247
|
+
createParameterNodes(node.params, functionId, module.file, getLine(node), parameters as ParameterInfo[], scopeTracker);
|
|
201
248
|
|
|
202
249
|
// Create SCOPE for function body
|
|
203
|
-
const functionBodyScopeId =
|
|
250
|
+
const functionBodyScopeId = idGenerator.generateScope('body', `${node.id.name}:body`, module.file, line);
|
|
204
251
|
(scopes as ScopeInfo[]).push({
|
|
205
252
|
id: functionBodyScopeId,
|
|
206
253
|
type: 'SCOPE',
|
|
@@ -208,13 +255,16 @@ export class FunctionVisitor extends ASTVisitor {
|
|
|
208
255
|
name: `${node.id.name}:body`,
|
|
209
256
|
conditional: false,
|
|
210
257
|
file: module.file,
|
|
211
|
-
line
|
|
258
|
+
line,
|
|
212
259
|
parentFunctionId: functionId
|
|
213
260
|
});
|
|
214
261
|
|
|
215
262
|
// Analyze function body
|
|
216
263
|
analyzeFunctionBody(path as NodePath<FunctionDeclaration>, functionBodyScopeId, module, collections);
|
|
217
264
|
|
|
265
|
+
// Exit function scope
|
|
266
|
+
scopeTracker.exitScope();
|
|
267
|
+
|
|
218
268
|
// Stop traversal - analyzeFunctionBody already processed contents
|
|
219
269
|
path.skip();
|
|
220
270
|
},
|
|
@@ -222,8 +272,9 @@ export class FunctionVisitor extends ASTVisitor {
|
|
|
222
272
|
// Arrow functions (module-level, assigned to variables or as callbacks)
|
|
223
273
|
ArrowFunctionExpression: (path: NodePath) => {
|
|
224
274
|
const node = path.node as ArrowFunctionExpression;
|
|
225
|
-
const line = node
|
|
226
|
-
const column = node
|
|
275
|
+
const line = getLine(node);
|
|
276
|
+
const column = getColumn(node);
|
|
277
|
+
const isAsync = node.async || false;
|
|
227
278
|
|
|
228
279
|
// Determine arrow function name (use scope-level counter for stable semanticId)
|
|
229
280
|
let functionName = generateAnonymousName();
|
|
@@ -237,25 +288,40 @@ export class FunctionVisitor extends ASTVisitor {
|
|
|
237
288
|
}
|
|
238
289
|
}
|
|
239
290
|
|
|
240
|
-
|
|
291
|
+
// Generate ID using centralized IdGenerator
|
|
292
|
+
const idGenerator = new IdGenerator(scopeTracker);
|
|
293
|
+
const functionId = idGenerator.generate('FUNCTION', functionName, module.file, line, column, functionCounterRef);
|
|
294
|
+
|
|
295
|
+
// Extract type info
|
|
296
|
+
const { names: paramNames, types: paramTypes } = extractParamInfo(node.params);
|
|
297
|
+
const returnType = extractReturnType(node);
|
|
298
|
+
const jsdocSummary = extractJsdocSummary(node);
|
|
299
|
+
const signature = buildSignature(paramNames, paramTypes, returnType, isAsync);
|
|
241
300
|
|
|
242
301
|
(functions as FunctionInfo[]).push({
|
|
243
302
|
id: functionId,
|
|
244
|
-
stableId: functionId,
|
|
245
303
|
type: 'FUNCTION',
|
|
246
304
|
name: functionName,
|
|
247
305
|
file: module.file,
|
|
248
306
|
line,
|
|
249
307
|
column,
|
|
250
|
-
async:
|
|
251
|
-
arrowFunction: true
|
|
308
|
+
async: isAsync,
|
|
309
|
+
arrowFunction: true,
|
|
310
|
+
params: paramNames,
|
|
311
|
+
paramTypes,
|
|
312
|
+
returnType,
|
|
313
|
+
signature,
|
|
314
|
+
jsdocSummary
|
|
252
315
|
});
|
|
253
316
|
|
|
317
|
+
// Enter function scope BEFORE creating parameters (semantic IDs need function context)
|
|
318
|
+
scopeTracker.enterScope(functionName, 'FUNCTION');
|
|
319
|
+
|
|
254
320
|
// Create PARAMETER nodes for arrow function parameters
|
|
255
|
-
createParameterNodes(node.params, functionId, module.file, line);
|
|
321
|
+
createParameterNodes(node.params, functionId, module.file, line, parameters as ParameterInfo[], scopeTracker);
|
|
256
322
|
|
|
257
323
|
// Create SCOPE for arrow function body
|
|
258
|
-
const bodyScope =
|
|
324
|
+
const bodyScope = idGenerator.generateScope('body', `${functionName}:body`, module.file, line, column);
|
|
259
325
|
(scopes as ScopeInfo[]).push({
|
|
260
326
|
id: bodyScope,
|
|
261
327
|
type: 'SCOPE',
|
|
@@ -266,8 +332,83 @@ export class FunctionVisitor extends ASTVisitor {
|
|
|
266
332
|
parentFunctionId: functionId
|
|
267
333
|
});
|
|
268
334
|
|
|
335
|
+
// REG-334: Detect Promise executor context BEFORE analyzing body
|
|
336
|
+
// This must happen before analyzeFunctionBody so resolve/reject calls can be linked
|
|
337
|
+
this.detectPromiseExecutorContext(path, node, module, collections);
|
|
338
|
+
|
|
269
339
|
analyzeFunctionBody(path as NodePath<ArrowFunctionExpression>, bodyScope, module, collections);
|
|
340
|
+
|
|
341
|
+
// Exit function scope
|
|
342
|
+
scopeTracker.exitScope();
|
|
343
|
+
|
|
344
|
+
// Stop traversal - analyzeFunctionBody already processed contents
|
|
345
|
+
// Without this, babel traverse continues into arrow body and finds
|
|
346
|
+
// nested arrow functions, causing duplicate FUNCTION nodes
|
|
347
|
+
path.skip();
|
|
270
348
|
}
|
|
271
349
|
};
|
|
272
350
|
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* REG-334: Detect if this function is a Promise executor callback.
|
|
354
|
+
* If so, register the context so resolve/reject calls can be linked.
|
|
355
|
+
*
|
|
356
|
+
* Pattern: new Promise((resolve, reject) => { ... })
|
|
357
|
+
*
|
|
358
|
+
* Must be called BEFORE analyzeFunctionBody so the context is available
|
|
359
|
+
* when resolve/reject calls are processed.
|
|
360
|
+
*/
|
|
361
|
+
private detectPromiseExecutorContext(
|
|
362
|
+
path: NodePath,
|
|
363
|
+
node: ArrowFunctionExpression | FunctionExpression,
|
|
364
|
+
module: VisitorModule,
|
|
365
|
+
collections: VisitorCollections
|
|
366
|
+
): void {
|
|
367
|
+
// Check if this function is the first argument to new Promise()
|
|
368
|
+
const parent = path.parent;
|
|
369
|
+
if (parent?.type !== 'NewExpression') return;
|
|
370
|
+
|
|
371
|
+
const newExpr = parent as NewExpression;
|
|
372
|
+
|
|
373
|
+
// Check it's Promise constructor
|
|
374
|
+
if (newExpr.callee.type !== 'Identifier') return;
|
|
375
|
+
if ((newExpr.callee as Identifier).name !== 'Promise') return;
|
|
376
|
+
|
|
377
|
+
// Check this function is the first argument
|
|
378
|
+
if (newExpr.arguments.length === 0) return;
|
|
379
|
+
if (newExpr.arguments[0] !== node) return;
|
|
380
|
+
|
|
381
|
+
// Extract resolve/reject parameter names
|
|
382
|
+
let resolveName: string | undefined;
|
|
383
|
+
let rejectName: string | undefined;
|
|
384
|
+
|
|
385
|
+
if (node.params.length > 0 && node.params[0].type === 'Identifier') {
|
|
386
|
+
resolveName = (node.params[0] as Identifier).name;
|
|
387
|
+
}
|
|
388
|
+
if (node.params.length > 1 && node.params[1].type === 'Identifier') {
|
|
389
|
+
rejectName = (node.params[1] as Identifier).name;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (!resolveName) return; // No resolve parameter, nothing to track
|
|
393
|
+
|
|
394
|
+
// Generate the CONSTRUCTOR_CALL ID for linking
|
|
395
|
+
const line = getLine(newExpr);
|
|
396
|
+
const column = getColumn(newExpr);
|
|
397
|
+
const constructorCallId = ConstructorCallNode.generateId('Promise', module.file, line, column);
|
|
398
|
+
|
|
399
|
+
// Initialize promiseExecutorContexts if not exists
|
|
400
|
+
if (!collections.promiseExecutorContexts) {
|
|
401
|
+
collections.promiseExecutorContexts = new Map<string, PromiseExecutorContext>();
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Key by function node position to allow nested Promise detection
|
|
405
|
+
const funcKey = `${node.start}:${node.end}`;
|
|
406
|
+
(collections.promiseExecutorContexts as Map<string, PromiseExecutorContext>).set(funcKey, {
|
|
407
|
+
constructorCallId,
|
|
408
|
+
resolveName,
|
|
409
|
+
rejectName,
|
|
410
|
+
file: module.file,
|
|
411
|
+
line: getLine(node)
|
|
412
|
+
});
|
|
413
|
+
}
|
|
273
414
|
}
|
|
@@ -21,11 +21,14 @@ import type {
|
|
|
21
21
|
FunctionDeclaration,
|
|
22
22
|
ClassDeclaration,
|
|
23
23
|
Identifier,
|
|
24
|
-
Node
|
|
24
|
+
Node,
|
|
25
|
+
CallExpression,
|
|
26
|
+
TemplateLiteral
|
|
25
27
|
} from '@babel/types';
|
|
26
28
|
import type { NodePath } from '@babel/traverse';
|
|
27
29
|
import { ASTVisitor, type VisitorModule, type VisitorCollections, type VisitorHandlers } from './ASTVisitor.js';
|
|
28
30
|
import type { VariableInfo } from './VariableVisitor.js';
|
|
31
|
+
import { getLine, getColumn } from '../utils/location.js';
|
|
29
32
|
|
|
30
33
|
/**
|
|
31
34
|
* Callback type for extracting variable names from patterns
|
|
@@ -47,6 +50,10 @@ interface ImportInfo {
|
|
|
47
50
|
source: string;
|
|
48
51
|
specifiers: ImportSpecifierInfo[];
|
|
49
52
|
line: number;
|
|
53
|
+
column?: number;
|
|
54
|
+
isDynamic?: boolean; // true for dynamic import() expressions
|
|
55
|
+
isResolvable?: boolean; // true if path is a string literal (statically analyzable)
|
|
56
|
+
dynamicPath?: string; // original expression for template/variable paths
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
/**
|
|
@@ -127,12 +134,119 @@ export class ImportExportVisitor extends ASTVisitor {
|
|
|
127
134
|
(imports as ImportInfo[]).push({
|
|
128
135
|
source,
|
|
129
136
|
specifiers,
|
|
130
|
-
line: node
|
|
137
|
+
line: getLine(node),
|
|
138
|
+
column: getColumn(node)
|
|
139
|
+
});
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Handle dynamic import() expressions
|
|
144
|
+
* Examples:
|
|
145
|
+
* - import('./module.js') -> isResolvable: true
|
|
146
|
+
* - import(`./plugins/${name}.js`) -> isResolvable: false, source: './plugins/'
|
|
147
|
+
* - import(modulePath) -> isResolvable: false, source: '<dynamic>'
|
|
148
|
+
*/
|
|
149
|
+
CallExpression: (path: NodePath) => {
|
|
150
|
+
const node = path.node as CallExpression;
|
|
151
|
+
|
|
152
|
+
// Check if this is an import() call
|
|
153
|
+
if (node.callee.type !== 'Import') {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const arg = node.arguments[0];
|
|
158
|
+
if (!arg) return;
|
|
159
|
+
|
|
160
|
+
let source: string;
|
|
161
|
+
let isResolvable: boolean;
|
|
162
|
+
let dynamicPath: string | undefined;
|
|
163
|
+
|
|
164
|
+
if (arg.type === 'StringLiteral') {
|
|
165
|
+
// import('./module.js') - literal path, fully resolvable
|
|
166
|
+
source = arg.value;
|
|
167
|
+
isResolvable = true;
|
|
168
|
+
} else if (arg.type === 'TemplateLiteral') {
|
|
169
|
+
// import(`./plugins/${name}.js`) - template literal
|
|
170
|
+
const templateArg = arg as TemplateLiteral;
|
|
171
|
+
const firstQuasi = templateArg.quasis[0];
|
|
172
|
+
|
|
173
|
+
// Extract static prefix (part before first expression)
|
|
174
|
+
const prefix = firstQuasi?.value?.raw || '';
|
|
175
|
+
|
|
176
|
+
if (prefix) {
|
|
177
|
+
source = prefix;
|
|
178
|
+
} else {
|
|
179
|
+
// No static prefix - e.g., import(`${baseDir}/loader.js`)
|
|
180
|
+
source = '<dynamic>';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
isResolvable = false;
|
|
184
|
+
// Capture the original template for debugging/analysis
|
|
185
|
+
dynamicPath = this.templateLiteralToString(templateArg);
|
|
186
|
+
} else if (arg.type === 'Identifier') {
|
|
187
|
+
// import(modulePath) - variable path
|
|
188
|
+
source = '<dynamic>';
|
|
189
|
+
isResolvable = false;
|
|
190
|
+
dynamicPath = (arg as Identifier).name;
|
|
191
|
+
} else {
|
|
192
|
+
// Other expressions (e.g., function calls, member expressions)
|
|
193
|
+
source = '<dynamic>';
|
|
194
|
+
isResolvable = false;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Find the receiving variable name from parent
|
|
198
|
+
// Patterns: const mod = await import(...) or const mod = import(...)
|
|
199
|
+
let localName = '*'; // Default for side-effect imports
|
|
200
|
+
const parent = path.parent;
|
|
201
|
+
|
|
202
|
+
if (parent?.type === 'AwaitExpression') {
|
|
203
|
+
// const mod = await import(...)
|
|
204
|
+
const awaitParent = path.parentPath?.parent;
|
|
205
|
+
if (awaitParent?.type === 'VariableDeclarator' &&
|
|
206
|
+
awaitParent.id?.type === 'Identifier') {
|
|
207
|
+
localName = awaitParent.id.name;
|
|
208
|
+
}
|
|
209
|
+
} else if (parent?.type === 'VariableDeclarator' &&
|
|
210
|
+
parent.id?.type === 'Identifier') {
|
|
211
|
+
// const mod = import(...) (without await)
|
|
212
|
+
localName = parent.id.name;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
(imports as ImportInfo[]).push({
|
|
216
|
+
source,
|
|
217
|
+
specifiers: [{
|
|
218
|
+
imported: '*', // Dynamic imports are always namespace imports
|
|
219
|
+
local: localName
|
|
220
|
+
}],
|
|
221
|
+
line: getLine(node),
|
|
222
|
+
column: getColumn(node),
|
|
223
|
+
isDynamic: true,
|
|
224
|
+
isResolvable,
|
|
225
|
+
dynamicPath
|
|
131
226
|
});
|
|
132
227
|
}
|
|
133
228
|
};
|
|
134
229
|
}
|
|
135
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Convert a TemplateLiteral to a string representation for debugging
|
|
233
|
+
*/
|
|
234
|
+
private templateLiteralToString(template: TemplateLiteral): string {
|
|
235
|
+
let result = '';
|
|
236
|
+
for (let i = 0; i < template.quasis.length; i++) {
|
|
237
|
+
result += template.quasis[i].value.raw;
|
|
238
|
+
if (i < template.expressions.length) {
|
|
239
|
+
const expr = template.expressions[i];
|
|
240
|
+
if (expr.type === 'Identifier') {
|
|
241
|
+
result += `\${${expr.name}}`;
|
|
242
|
+
} else {
|
|
243
|
+
result += '${...}';
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
|
|
136
250
|
getExportHandlers(): VisitorHandlers {
|
|
137
251
|
const { exports } = this.collections;
|
|
138
252
|
const extractVariableNamesFromPattern = this.extractVariableNamesFromPattern;
|
|
@@ -143,13 +257,14 @@ export class ImportExportVisitor extends ASTVisitor {
|
|
|
143
257
|
|
|
144
258
|
(exports as ExportInfo[]).push({
|
|
145
259
|
type: 'default',
|
|
146
|
-
line: node
|
|
260
|
+
line: getLine(node),
|
|
147
261
|
declaration: node.declaration
|
|
148
262
|
});
|
|
149
263
|
},
|
|
150
264
|
|
|
151
265
|
ExportNamedDeclaration: (path: NodePath) => {
|
|
152
266
|
const node = path.node as ExportNamedDeclaration;
|
|
267
|
+
const exportLine = getLine(node);
|
|
153
268
|
|
|
154
269
|
// export { foo, bar } from './module'
|
|
155
270
|
if (node.source) {
|
|
@@ -169,7 +284,7 @@ export class ImportExportVisitor extends ASTVisitor {
|
|
|
169
284
|
|
|
170
285
|
(exports as ExportInfo[]).push({
|
|
171
286
|
type: 'named',
|
|
172
|
-
line:
|
|
287
|
+
line: exportLine,
|
|
173
288
|
specifiers,
|
|
174
289
|
source: node.source.value
|
|
175
290
|
});
|
|
@@ -189,7 +304,7 @@ export class ImportExportVisitor extends ASTVisitor {
|
|
|
189
304
|
|
|
190
305
|
(exports as ExportInfo[]).push({
|
|
191
306
|
type: 'named',
|
|
192
|
-
line:
|
|
307
|
+
line: exportLine,
|
|
193
308
|
specifiers
|
|
194
309
|
});
|
|
195
310
|
}
|
|
@@ -203,7 +318,7 @@ export class ImportExportVisitor extends ASTVisitor {
|
|
|
203
318
|
if (funcDecl.id) {
|
|
204
319
|
(exports as ExportInfo[]).push({
|
|
205
320
|
type: 'named',
|
|
206
|
-
line:
|
|
321
|
+
line: exportLine,
|
|
207
322
|
name: funcDecl.id.name
|
|
208
323
|
});
|
|
209
324
|
}
|
|
@@ -217,7 +332,7 @@ export class ImportExportVisitor extends ASTVisitor {
|
|
|
217
332
|
variables.forEach((varInfo: VariableInfo) => {
|
|
218
333
|
(exports as ExportInfo[]).push({
|
|
219
334
|
type: 'named',
|
|
220
|
-
line:
|
|
335
|
+
line: exportLine,
|
|
221
336
|
name: varInfo.name
|
|
222
337
|
});
|
|
223
338
|
});
|
|
@@ -229,7 +344,7 @@ export class ImportExportVisitor extends ASTVisitor {
|
|
|
229
344
|
if (classDecl.id) {
|
|
230
345
|
(exports as ExportInfo[]).push({
|
|
231
346
|
type: 'named',
|
|
232
|
-
line:
|
|
347
|
+
line: exportLine,
|
|
233
348
|
name: classDecl.id.name
|
|
234
349
|
});
|
|
235
350
|
}
|
|
@@ -243,7 +358,7 @@ export class ImportExportVisitor extends ASTVisitor {
|
|
|
243
358
|
// export * from './module'
|
|
244
359
|
(exports as ExportInfo[]).push({
|
|
245
360
|
type: 'all',
|
|
246
|
-
line: node
|
|
361
|
+
line: getLine(node),
|
|
247
362
|
source: node.source.value
|
|
248
363
|
});
|
|
249
364
|
}
|