@grafema/core 0.1.1-alpha → 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/dist/Orchestrator.d.ts +7 -0
- package/dist/Orchestrator.d.ts.map +1 -1
- package/dist/Orchestrator.js +25 -3
- package/dist/config/ConfigLoader.d.ts +18 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -1
- package/dist/config/ConfigLoader.js +65 -3
- 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/NodeFactory.d.ts +44 -5
- package/dist/core/NodeFactory.d.ts.map +1 -1
- package/dist/core/NodeFactory.js +52 -7
- package/dist/core/nodes/ArrayLiteralNode.d.ts.map +1 -1
- package/dist/core/nodes/ArrayLiteralNode.js +4 -2
- 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 +2 -2
- package/dist/core/nodes/CallSiteNode.d.ts.map +1 -1
- package/dist/core/nodes/CallSiteNode.js +9 -5
- 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 +2 -2
- package/dist/core/nodes/ClassNode.d.ts.map +1 -1
- package/dist/core/nodes/ClassNode.js +8 -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 +2 -2
- package/dist/core/nodes/DecoratorNode.d.ts.map +1 -1
- package/dist/core/nodes/DecoratorNode.js +5 -3
- package/dist/core/nodes/EnumNode.d.ts +2 -2
- package/dist/core/nodes/EnumNode.d.ts.map +1 -1
- package/dist/core/nodes/EnumNode.js +5 -3
- 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 +2 -2
- package/dist/core/nodes/ExportNode.d.ts.map +1 -1
- package/dist/core/nodes/ExportNode.js +8 -4
- package/dist/core/nodes/ExpressionNode.d.ts +2 -2
- package/dist/core/nodes/ExpressionNode.d.ts.map +1 -1
- package/dist/core/nodes/ExpressionNode.js +6 -4
- package/dist/core/nodes/ExternalModuleNode.d.ts +4 -0
- package/dist/core/nodes/ExternalModuleNode.d.ts.map +1 -1
- package/dist/core/nodes/ExternalModuleNode.js +10 -2
- 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 +10 -2
- package/dist/core/nodes/ImportNode.d.ts.map +1 -1
- package/dist/core/nodes/ImportNode.js +21 -4
- package/dist/core/nodes/InterfaceNode.d.ts +2 -2
- package/dist/core/nodes/InterfaceNode.d.ts.map +1 -1
- package/dist/core/nodes/InterfaceNode.js +5 -3
- 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 +2 -2
- package/dist/core/nodes/MethodCallNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodCallNode.js +9 -5
- package/dist/core/nodes/MethodNode.d.ts +2 -2
- package/dist/core/nodes/MethodNode.d.ts.map +1 -1
- package/dist/core/nodes/MethodNode.js +8 -4
- package/dist/core/nodes/ObjectLiteralNode.d.ts.map +1 -1
- package/dist/core/nodes/ObjectLiteralNode.js +4 -2
- 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/TypeNode.d.ts +2 -2
- package/dist/core/nodes/TypeNode.d.ts.map +1 -1
- package/dist/core/nodes/TypeNode.js +5 -3
- package/dist/core/nodes/VariableDeclarationNode.d.ts +2 -2
- package/dist/core/nodes/VariableDeclarationNode.d.ts.map +1 -1
- package/dist/core/nodes/VariableDeclarationNode.js +9 -5
- package/dist/core/nodes/index.d.ts +3 -0
- package/dist/core/nodes/index.d.ts.map +1 -1
- package/dist/core/nodes/index.js +3 -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/DiagnosticReporter.d.ts +23 -0
- package/dist/diagnostics/DiagnosticReporter.d.ts.map +1 -1
- package/dist/diagnostics/DiagnosticReporter.js +88 -0
- package/dist/diagnostics/index.d.ts +1 -1
- package/dist/diagnostics/index.d.ts.map +1 -1
- package/dist/errors/GrafemaError.d.ts +43 -0
- package/dist/errors/GrafemaError.d.ts.map +1 -1
- package/dist/errors/GrafemaError.js +50 -0
- package/dist/index.d.ts +17 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/DatabaseAnalyzer.js +3 -2
- package/dist/plugins/analysis/ExpressAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/ExpressAnalyzer.js +3 -1
- 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 +53 -18
- package/dist/plugins/analysis/FetchAnalyzer.d.ts +40 -0
- package/dist/plugins/analysis/FetchAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/FetchAnalyzer.js +163 -15
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts +157 -26
- package/dist/plugins/analysis/JSASTAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/JSASTAnalyzer.js +2418 -191
- package/dist/plugins/analysis/RustAnalyzer.js +4 -4
- package/dist/plugins/analysis/SQLiteAnalyzer.d.ts.map +1 -1
- package/dist/plugins/analysis/SQLiteAnalyzer.js +4 -2
- 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 +91 -7
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts +173 -0
- package/dist/plugins/analysis/ast/GraphBuilder.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/GraphBuilder.js +1256 -65
- package/dist/plugins/analysis/ast/types.d.ts +294 -0
- package/dist/plugins/analysis/ast/types.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts +5 -1
- package/dist/plugins/analysis/ast/visitors/ASTVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts +1 -0
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/CallExpressionVisitor.js +12 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts +10 -0
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/FunctionVisitor.js +62 -0
- 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 +101 -0
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts +16 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.d.ts.map +1 -1
- package/dist/plugins/analysis/ast/visitors/VariableVisitor.js +233 -39
- package/dist/plugins/discovery/WorkspaceDiscovery.d.ts.map +1 -1
- package/dist/plugins/discovery/WorkspaceDiscovery.js +9 -4
- package/dist/plugins/enrichment/AliasTracker.d.ts.map +1 -1
- package/dist/plugins/enrichment/AliasTracker.js +16 -1
- 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 +64 -20
- package/dist/plugins/enrichment/MethodCallResolver.d.ts.map +1 -1
- package/dist/plugins/enrichment/MethodCallResolver.js +15 -1
- 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 +172 -151
- 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/ValueDomainAnalyzer.d.ts +5 -27
- package/dist/plugins/enrichment/ValueDomainAnalyzer.d.ts.map +1 -1
- package/dist/plugins/enrichment/ValueDomainAnalyzer.js +62 -139
- 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 +58 -0
- package/dist/plugins/indexing/RustModuleIndexer.d.ts +1 -1
- package/dist/plugins/indexing/RustModuleIndexer.js +4 -4
- 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 +101 -76
- package/dist/plugins/validation/DataFlowValidator.d.ts.map +1 -1
- package/dist/plugins/validation/DataFlowValidator.js +49 -41
- package/dist/plugins/validation/GraphConnectivityValidator.d.ts.map +1 -1
- package/dist/plugins/validation/GraphConnectivityValidator.js +25 -1
- package/dist/plugins/validation/SQLInjectionValidator.d.ts.map +1 -1
- package/dist/plugins/validation/SQLInjectionValidator.js +2 -3
- 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 +12 -18
- package/dist/storage/backends/RFDBServerBackend.d.ts.map +1 -1
- package/dist/storage/backends/RFDBServerBackend.js +41 -52
- package/dist/storage/backends/typeValidation.d.ts.map +1 -1
- package/dist/storage/backends/typeValidation.js +1 -0
- package/package.json +3 -3
- package/src/Orchestrator.ts +35 -3
- package/src/config/ConfigLoader.ts +94 -3
- package/src/core/FileExplainer.ts +179 -0
- package/src/core/NodeFactory.ts +72 -8
- package/src/core/nodes/ArrayLiteralNode.ts +3 -2
- package/src/core/nodes/BranchNode.ts +113 -0
- package/src/core/nodes/CallSiteNode.ts +7 -5
- package/src/core/nodes/CaseNode.ts +123 -0
- package/src/core/nodes/ClassNode.ts +6 -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 +4 -3
- package/src/core/nodes/EnumNode.ts +4 -3
- package/src/core/nodes/EventListenerNode.ts +7 -4
- package/src/core/nodes/ExportNode.ts +6 -4
- package/src/core/nodes/ExpressionNode.ts +5 -4
- package/src/core/nodes/ExternalModuleNode.ts +11 -2
- package/src/core/nodes/HttpRequestNode.ts +7 -4
- package/src/core/nodes/ImportNode.ts +31 -4
- package/src/core/nodes/InterfaceNode.ts +4 -3
- package/src/core/nodes/LiteralNode.ts +5 -4
- package/src/core/nodes/MethodCallNode.ts +7 -5
- package/src/core/nodes/MethodNode.ts +6 -4
- package/src/core/nodes/ObjectLiteralNode.ts +3 -2
- package/src/core/nodes/ParameterNode.ts +4 -3
- package/src/core/nodes/TypeNode.ts +4 -3
- package/src/core/nodes/VariableDeclarationNode.ts +7 -5
- package/src/core/nodes/index.ts +3 -0
- 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/DiagnosticReporter.ts +120 -0
- package/src/diagnostics/index.ts +1 -1
- package/src/errors/GrafemaError.ts +65 -0
- package/src/index.ts +45 -0
- package/src/plugins/analysis/DatabaseAnalyzer.ts +4 -2
- package/src/plugins/analysis/ExpressAnalyzer.ts +5 -1
- package/src/plugins/analysis/ExpressResponseAnalyzer.ts +636 -0
- package/src/plugins/analysis/ExpressRouteAnalyzer.ts +57 -18
- package/src/plugins/analysis/FetchAnalyzer.ts +204 -16
- package/src/plugins/analysis/JSASTAnalyzer.ts +2958 -260
- package/src/plugins/analysis/RustAnalyzer.ts +4 -4
- package/src/plugins/analysis/SQLiteAnalyzer.ts +5 -2
- package/src/plugins/analysis/SocketIOAnalyzer.ts +121 -7
- package/src/plugins/analysis/ast/GraphBuilder.ts +1578 -70
- package/src/plugins/analysis/ast/types.ts +387 -0
- package/src/plugins/analysis/ast/visitors/ASTVisitor.ts +8 -0
- package/src/plugins/analysis/ast/visitors/CallExpressionVisitor.ts +16 -1
- package/src/plugins/analysis/ast/visitors/FunctionVisitor.ts +77 -2
- package/src/plugins/analysis/ast/visitors/ImportExportVisitor.ts +112 -1
- package/src/plugins/analysis/ast/visitors/VariableVisitor.ts +272 -47
- package/src/plugins/discovery/WorkspaceDiscovery.ts +11 -4
- package/src/plugins/enrichment/AliasTracker.ts +22 -1
- 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 +70 -20
- package/src/plugins/enrichment/MethodCallResolver.ts +21 -1
- package/src/plugins/enrichment/MountPointResolver.ts +206 -198
- package/src/plugins/enrichment/NodejsBuiltinsResolver.ts +365 -0
- package/src/plugins/enrichment/ValueDomainAnalyzer.ts +67 -184
- package/src/plugins/indexing/JSModuleIndexer.ts +66 -0
- package/src/plugins/indexing/RustModuleIndexer.ts +4 -4
- package/src/plugins/validation/BrokenImportValidator.ts +325 -0
- package/src/plugins/validation/CallResolverValidator.ts +129 -109
- package/src/plugins/validation/DataFlowValidator.ts +75 -58
- package/src/plugins/validation/GraphConnectivityValidator.ts +39 -1
- package/src/plugins/validation/SQLInjectionValidator.ts +2 -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 +58 -70
- package/src/storage/backends/typeValidation.ts +1 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BranchNode - contract for BRANCH node
|
|
3
|
+
*
|
|
4
|
+
* Represents control flow branching (switch statements).
|
|
5
|
+
* Future: if statements, ternary expressions.
|
|
6
|
+
*
|
|
7
|
+
* ID format (legacy): {file}:BRANCH:{branchType}:{line}:{counter}
|
|
8
|
+
* Semantic ID format: {file}->{scope_path}->BRANCH->switch#N
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { BaseNodeRecord } from '@grafema/types';
|
|
12
|
+
import { computeSemanticId, type ScopeContext, type Location } from '../SemanticId.js';
|
|
13
|
+
|
|
14
|
+
interface BranchNodeRecord extends BaseNodeRecord {
|
|
15
|
+
type: 'BRANCH';
|
|
16
|
+
column: number;
|
|
17
|
+
branchType: 'switch' | 'if' | 'ternary';
|
|
18
|
+
parentScopeId?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface BranchNodeOptions {
|
|
22
|
+
parentScopeId?: string;
|
|
23
|
+
counter?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface BranchContextOptions {
|
|
27
|
+
discriminator: number;
|
|
28
|
+
parentScopeId?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class BranchNode {
|
|
32
|
+
static readonly TYPE = 'BRANCH' as const;
|
|
33
|
+
static readonly REQUIRED = ['branchType', 'file', 'line', 'column'] as const;
|
|
34
|
+
static readonly OPTIONAL = ['parentScopeId'] as const;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Create BRANCH node (legacy ID)
|
|
38
|
+
*/
|
|
39
|
+
static create(
|
|
40
|
+
branchType: 'switch' | 'if' | 'ternary',
|
|
41
|
+
file: string,
|
|
42
|
+
line: number,
|
|
43
|
+
column: number,
|
|
44
|
+
options: BranchNodeOptions = {}
|
|
45
|
+
): BranchNodeRecord {
|
|
46
|
+
// Validation
|
|
47
|
+
if (!branchType) throw new Error('BranchNode.create: branchType is required');
|
|
48
|
+
if (!file) throw new Error('BranchNode.create: file is required');
|
|
49
|
+
if (line === undefined) throw new Error('BranchNode.create: line is required');
|
|
50
|
+
if (column === undefined) throw new Error('BranchNode.create: column is required');
|
|
51
|
+
|
|
52
|
+
const counter = options.counter !== undefined ? `:${options.counter}` : '';
|
|
53
|
+
const id = `${file}:BRANCH:${branchType}:${line}${counter}`;
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
id,
|
|
57
|
+
type: this.TYPE,
|
|
58
|
+
name: branchType,
|
|
59
|
+
file,
|
|
60
|
+
line,
|
|
61
|
+
column,
|
|
62
|
+
branchType,
|
|
63
|
+
parentScopeId: options.parentScopeId
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Create BRANCH node with semantic ID (NEW API)
|
|
69
|
+
*/
|
|
70
|
+
static createWithContext(
|
|
71
|
+
branchType: 'switch' | 'if' | 'ternary',
|
|
72
|
+
context: ScopeContext,
|
|
73
|
+
location: Partial<Location>,
|
|
74
|
+
options: BranchContextOptions
|
|
75
|
+
): BranchNodeRecord {
|
|
76
|
+
if (!branchType) throw new Error('BranchNode.createWithContext: branchType is required');
|
|
77
|
+
if (!context.file) throw new Error('BranchNode.createWithContext: file is required');
|
|
78
|
+
if (location.line === undefined) throw new Error('BranchNode.createWithContext: line is required');
|
|
79
|
+
if (location.column === undefined) throw new Error('BranchNode.createWithContext: column is required');
|
|
80
|
+
if (options.discriminator === undefined) throw new Error('BranchNode.createWithContext: discriminator is required');
|
|
81
|
+
|
|
82
|
+
const id = computeSemanticId('BRANCH', branchType, context, {
|
|
83
|
+
discriminator: options.discriminator
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
id,
|
|
88
|
+
type: this.TYPE,
|
|
89
|
+
name: `${branchType}#${options.discriminator}`,
|
|
90
|
+
file: context.file,
|
|
91
|
+
line: location.line,
|
|
92
|
+
column: location.column,
|
|
93
|
+
branchType,
|
|
94
|
+
parentScopeId: options.parentScopeId
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static validate(node: BranchNodeRecord): string[] {
|
|
99
|
+
const errors: string[] = [];
|
|
100
|
+
if (node.type !== this.TYPE) {
|
|
101
|
+
errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
|
|
102
|
+
}
|
|
103
|
+
if (!node.branchType) {
|
|
104
|
+
errors.push('Missing required field: branchType');
|
|
105
|
+
}
|
|
106
|
+
if (!node.file) {
|
|
107
|
+
errors.push('Missing required field: file');
|
|
108
|
+
}
|
|
109
|
+
return errors;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type { BranchNodeRecord };
|
|
@@ -35,8 +35,8 @@ interface CallSiteContextOptions {
|
|
|
35
35
|
export class CallSiteNode {
|
|
36
36
|
static readonly TYPE = 'CALL_SITE' as const;
|
|
37
37
|
|
|
38
|
-
static readonly REQUIRED = ['name', 'file', 'line'] as const;
|
|
39
|
-
static readonly OPTIONAL = ['
|
|
38
|
+
static readonly REQUIRED = ['name', 'file', 'line', 'column'] as const;
|
|
39
|
+
static readonly OPTIONAL = ['parentScopeId', 'targetFunctionName'] as const;
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* Create CALL_SITE node
|
|
@@ -51,9 +51,10 @@ export class CallSiteNode {
|
|
|
51
51
|
if (!targetName) throw new Error('CallSiteNode.create: targetName is required');
|
|
52
52
|
if (!file) throw new Error('CallSiteNode.create: file is required');
|
|
53
53
|
if (line === undefined) throw new Error('CallSiteNode.create: line is required');
|
|
54
|
+
if (column === undefined) throw new Error('CallSiteNode.create: column is required');
|
|
54
55
|
|
|
55
56
|
const counter = options.counter !== undefined ? `:${options.counter}` : '';
|
|
56
|
-
const id = `${file}:CALL_SITE:${targetName}:${line}:${column
|
|
57
|
+
const id = `${file}:CALL_SITE:${targetName}:${line}:${column}${counter}`;
|
|
57
58
|
|
|
58
59
|
return {
|
|
59
60
|
id,
|
|
@@ -61,7 +62,7 @@ export class CallSiteNode {
|
|
|
61
62
|
name: targetName,
|
|
62
63
|
file,
|
|
63
64
|
line,
|
|
64
|
-
column
|
|
65
|
+
column,
|
|
65
66
|
parentScopeId: options.parentScopeId,
|
|
66
67
|
targetFunctionName: targetName
|
|
67
68
|
};
|
|
@@ -89,6 +90,7 @@ export class CallSiteNode {
|
|
|
89
90
|
if (!targetName) throw new Error('CallSiteNode.createWithContext: targetName is required');
|
|
90
91
|
if (!context.file) throw new Error('CallSiteNode.createWithContext: file is required');
|
|
91
92
|
if (location.line === undefined) throw new Error('CallSiteNode.createWithContext: line is required');
|
|
93
|
+
if (location.column === undefined) throw new Error('CallSiteNode.createWithContext: column is required');
|
|
92
94
|
if (options.discriminator === undefined) throw new Error('CallSiteNode.createWithContext: discriminator is required');
|
|
93
95
|
|
|
94
96
|
// Compute semantic ID with discriminator
|
|
@@ -103,7 +105,7 @@ export class CallSiteNode {
|
|
|
103
105
|
name: targetName,
|
|
104
106
|
file: context.file,
|
|
105
107
|
line: location.line,
|
|
106
|
-
column: location.column
|
|
108
|
+
column: location.column,
|
|
107
109
|
parentScopeId: options.parentScopeId,
|
|
108
110
|
targetFunctionName: targetName
|
|
109
111
|
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CaseNode - contract for CASE node
|
|
3
|
+
*
|
|
4
|
+
* Represents a case clause in a switch statement.
|
|
5
|
+
*
|
|
6
|
+
* ID format (legacy): {file}:CASE:{value}:{line}:{counter}
|
|
7
|
+
* Semantic ID format: {file}->{scope_path}->CASE->{value}#N
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { BaseNodeRecord } from '@grafema/types';
|
|
11
|
+
import { computeSemanticId, type ScopeContext, type Location } from '../SemanticId.js';
|
|
12
|
+
|
|
13
|
+
interface CaseNodeRecord extends BaseNodeRecord {
|
|
14
|
+
type: 'CASE';
|
|
15
|
+
column: number;
|
|
16
|
+
value: unknown;
|
|
17
|
+
isDefault: boolean;
|
|
18
|
+
fallsThrough: boolean;
|
|
19
|
+
isEmpty: boolean;
|
|
20
|
+
parentBranchId?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface CaseNodeOptions {
|
|
24
|
+
parentBranchId?: string;
|
|
25
|
+
counter?: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface CaseContextOptions {
|
|
29
|
+
discriminator: number;
|
|
30
|
+
parentBranchId?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class CaseNode {
|
|
34
|
+
static readonly TYPE = 'CASE' as const;
|
|
35
|
+
static readonly REQUIRED = ['file', 'line', 'column'] as const;
|
|
36
|
+
static readonly OPTIONAL = ['value', 'isDefault', 'fallsThrough', 'isEmpty', 'parentBranchId'] as const;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Create CASE node (legacy ID)
|
|
40
|
+
*/
|
|
41
|
+
static create(
|
|
42
|
+
value: unknown,
|
|
43
|
+
isDefault: boolean,
|
|
44
|
+
fallsThrough: boolean,
|
|
45
|
+
isEmpty: boolean,
|
|
46
|
+
file: string,
|
|
47
|
+
line: number,
|
|
48
|
+
column: number,
|
|
49
|
+
options: CaseNodeOptions = {}
|
|
50
|
+
): CaseNodeRecord {
|
|
51
|
+
if (!file) throw new Error('CaseNode.create: file is required');
|
|
52
|
+
if (line === undefined) throw new Error('CaseNode.create: line is required');
|
|
53
|
+
if (column === undefined) throw new Error('CaseNode.create: column is required');
|
|
54
|
+
|
|
55
|
+
const valueName = isDefault ? 'default' : String(value);
|
|
56
|
+
const counter = options.counter !== undefined ? `:${options.counter}` : '';
|
|
57
|
+
const id = `${file}:CASE:${valueName}:${line}${counter}`;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
id,
|
|
61
|
+
type: this.TYPE,
|
|
62
|
+
name: isDefault ? 'default' : `case ${String(value)}`,
|
|
63
|
+
file,
|
|
64
|
+
line,
|
|
65
|
+
column,
|
|
66
|
+
value,
|
|
67
|
+
isDefault,
|
|
68
|
+
fallsThrough,
|
|
69
|
+
isEmpty,
|
|
70
|
+
parentBranchId: options.parentBranchId
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Create CASE node with semantic ID (NEW API)
|
|
76
|
+
*/
|
|
77
|
+
static createWithContext(
|
|
78
|
+
value: unknown,
|
|
79
|
+
isDefault: boolean,
|
|
80
|
+
fallsThrough: boolean,
|
|
81
|
+
isEmpty: boolean,
|
|
82
|
+
context: ScopeContext,
|
|
83
|
+
location: Partial<Location>,
|
|
84
|
+
options: CaseContextOptions
|
|
85
|
+
): CaseNodeRecord {
|
|
86
|
+
if (!context.file) throw new Error('CaseNode.createWithContext: file is required');
|
|
87
|
+
if (location.line === undefined) throw new Error('CaseNode.createWithContext: line is required');
|
|
88
|
+
if (location.column === undefined) throw new Error('CaseNode.createWithContext: column is required');
|
|
89
|
+
if (options.discriminator === undefined) throw new Error('CaseNode.createWithContext: discriminator is required');
|
|
90
|
+
|
|
91
|
+
const valueName = isDefault ? 'default' : String(value);
|
|
92
|
+
const id = computeSemanticId('CASE', valueName, context, {
|
|
93
|
+
discriminator: options.discriminator
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
id,
|
|
98
|
+
type: this.TYPE,
|
|
99
|
+
name: isDefault ? 'default' : `case ${String(value)}`,
|
|
100
|
+
file: context.file,
|
|
101
|
+
line: location.line,
|
|
102
|
+
column: location.column,
|
|
103
|
+
value,
|
|
104
|
+
isDefault,
|
|
105
|
+
fallsThrough,
|
|
106
|
+
isEmpty,
|
|
107
|
+
parentBranchId: options.parentBranchId
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static validate(node: CaseNodeRecord): string[] {
|
|
112
|
+
const errors: string[] = [];
|
|
113
|
+
if (node.type !== this.TYPE) {
|
|
114
|
+
errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
|
|
115
|
+
}
|
|
116
|
+
if (!node.file) {
|
|
117
|
+
errors.push('Missing required field: file');
|
|
118
|
+
}
|
|
119
|
+
return errors;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export type { CaseNodeRecord };
|
|
@@ -41,8 +41,8 @@ interface ClassContextOptions {
|
|
|
41
41
|
export class ClassNode {
|
|
42
42
|
static readonly TYPE = 'CLASS' as const;
|
|
43
43
|
|
|
44
|
-
static readonly REQUIRED = ['name', 'file', 'line'] as const;
|
|
45
|
-
static readonly OPTIONAL = ['
|
|
44
|
+
static readonly REQUIRED = ['name', 'file', 'line', 'column'] as const;
|
|
45
|
+
static readonly OPTIONAL = ['exported', 'superClass', 'methods', 'isInstantiationRef'] as const;
|
|
46
46
|
|
|
47
47
|
static create(
|
|
48
48
|
name: string,
|
|
@@ -54,6 +54,7 @@ export class ClassNode {
|
|
|
54
54
|
if (!name) throw new Error('ClassNode.create: name is required');
|
|
55
55
|
if (!file) throw new Error('ClassNode.create: file is required');
|
|
56
56
|
if (!line) throw new Error('ClassNode.create: line is required');
|
|
57
|
+
if (column === undefined) throw new Error('ClassNode.create: column is required');
|
|
57
58
|
|
|
58
59
|
return {
|
|
59
60
|
id: `${file}:CLASS:${name}:${line}`,
|
|
@@ -61,7 +62,7 @@ export class ClassNode {
|
|
|
61
62
|
name,
|
|
62
63
|
file,
|
|
63
64
|
line,
|
|
64
|
-
column
|
|
65
|
+
column,
|
|
65
66
|
exported: options.exported || false,
|
|
66
67
|
superClass: options.superClass,
|
|
67
68
|
methods: options.methods || [],
|
|
@@ -91,6 +92,7 @@ export class ClassNode {
|
|
|
91
92
|
if (!name) throw new Error('ClassNode.createWithContext: name is required');
|
|
92
93
|
if (!context.file) throw new Error('ClassNode.createWithContext: file is required');
|
|
93
94
|
if (location.line === undefined) throw new Error('ClassNode.createWithContext: line is required');
|
|
95
|
+
if (location.column === undefined) throw new Error('ClassNode.createWithContext: column is required');
|
|
94
96
|
|
|
95
97
|
// Compute semantic ID
|
|
96
98
|
const id = computeSemanticId(this.TYPE, name, context);
|
|
@@ -101,7 +103,7 @@ export class ClassNode {
|
|
|
101
103
|
name,
|
|
102
104
|
file: context.file,
|
|
103
105
|
line: location.line,
|
|
104
|
-
column: location.column
|
|
106
|
+
column: location.column,
|
|
105
107
|
exported: options.exported || false,
|
|
106
108
|
superClass: options.superClass,
|
|
107
109
|
methods: options.methods || [],
|
|
@@ -20,8 +20,8 @@ interface ConstantNodeOptions {
|
|
|
20
20
|
export class ConstantNode {
|
|
21
21
|
static readonly TYPE = 'CONSTANT' as const;
|
|
22
22
|
|
|
23
|
-
static readonly REQUIRED = ['name', 'file', 'line'] as const;
|
|
24
|
-
static readonly OPTIONAL = ['
|
|
23
|
+
static readonly REQUIRED = ['name', 'file', 'line', 'column'] as const;
|
|
24
|
+
static readonly OPTIONAL = ['value', 'parentScopeId'] as const;
|
|
25
25
|
|
|
26
26
|
static create(
|
|
27
27
|
name: string,
|
|
@@ -33,9 +33,10 @@ export class ConstantNode {
|
|
|
33
33
|
if (!name) throw new Error('ConstantNode.create: name is required');
|
|
34
34
|
if (!file) throw new Error('ConstantNode.create: file is required');
|
|
35
35
|
if (line === undefined) throw new Error('ConstantNode.create: line is required');
|
|
36
|
+
if (column === undefined) throw new Error('ConstantNode.create: column is required');
|
|
36
37
|
|
|
37
38
|
const counter = options.counter !== undefined ? `:${options.counter}` : '';
|
|
38
|
-
const id = `${file}:CONSTANT:${name}:${line}:${column
|
|
39
|
+
const id = `${file}:CONSTANT:${name}:${line}:${column}${counter}`;
|
|
39
40
|
|
|
40
41
|
return {
|
|
41
42
|
id,
|
|
@@ -43,7 +44,7 @@ export class ConstantNode {
|
|
|
43
44
|
name,
|
|
44
45
|
file,
|
|
45
46
|
line,
|
|
46
|
-
column
|
|
47
|
+
column,
|
|
47
48
|
value: options.value,
|
|
48
49
|
parentScopeId: options.parentScopeId
|
|
49
50
|
};
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConstructorCallNode - contract for CONSTRUCTOR_CALL node
|
|
3
|
+
*
|
|
4
|
+
* Represents a `new ClassName()` expression in code.
|
|
5
|
+
* Used for data flow: VARIABLE --ASSIGNED_FROM--> CONSTRUCTOR_CALL
|
|
6
|
+
*
|
|
7
|
+
* ID format: {file}:CONSTRUCTOR_CALL:{className}:{line}:{column}
|
|
8
|
+
* Example: src/app.js:CONSTRUCTOR_CALL:Date:42:10
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { BaseNodeRecord } from '@grafema/types';
|
|
12
|
+
|
|
13
|
+
interface ConstructorCallNodeRecord extends BaseNodeRecord {
|
|
14
|
+
type: 'CONSTRUCTOR_CALL';
|
|
15
|
+
className: string;
|
|
16
|
+
isBuiltin: boolean;
|
|
17
|
+
column: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface ConstructorCallNodeOptions {
|
|
21
|
+
counter?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* List of built-in JavaScript constructors
|
|
26
|
+
* These are globally available and don't require imports
|
|
27
|
+
*/
|
|
28
|
+
const BUILTIN_CONSTRUCTORS = new Set([
|
|
29
|
+
// Fundamental objects
|
|
30
|
+
'Object',
|
|
31
|
+
'Function',
|
|
32
|
+
'Boolean',
|
|
33
|
+
'Symbol',
|
|
34
|
+
|
|
35
|
+
// Error types
|
|
36
|
+
'Error',
|
|
37
|
+
'EvalError',
|
|
38
|
+
'RangeError',
|
|
39
|
+
'ReferenceError',
|
|
40
|
+
'SyntaxError',
|
|
41
|
+
'TypeError',
|
|
42
|
+
'URIError',
|
|
43
|
+
'AggregateError',
|
|
44
|
+
|
|
45
|
+
// Numbers and dates
|
|
46
|
+
'Number',
|
|
47
|
+
'BigInt',
|
|
48
|
+
'Math',
|
|
49
|
+
'Date',
|
|
50
|
+
|
|
51
|
+
// Text processing
|
|
52
|
+
'String',
|
|
53
|
+
'RegExp',
|
|
54
|
+
|
|
55
|
+
// Indexed collections
|
|
56
|
+
'Array',
|
|
57
|
+
'Int8Array',
|
|
58
|
+
'Uint8Array',
|
|
59
|
+
'Uint8ClampedArray',
|
|
60
|
+
'Int16Array',
|
|
61
|
+
'Uint16Array',
|
|
62
|
+
'Int32Array',
|
|
63
|
+
'Uint32Array',
|
|
64
|
+
'Float32Array',
|
|
65
|
+
'Float64Array',
|
|
66
|
+
'BigInt64Array',
|
|
67
|
+
'BigUint64Array',
|
|
68
|
+
|
|
69
|
+
// Keyed collections
|
|
70
|
+
'Map',
|
|
71
|
+
'Set',
|
|
72
|
+
'WeakMap',
|
|
73
|
+
'WeakSet',
|
|
74
|
+
'WeakRef',
|
|
75
|
+
|
|
76
|
+
// Structured data
|
|
77
|
+
'ArrayBuffer',
|
|
78
|
+
'SharedArrayBuffer',
|
|
79
|
+
'DataView',
|
|
80
|
+
'Atomics',
|
|
81
|
+
'JSON',
|
|
82
|
+
|
|
83
|
+
// Control abstraction
|
|
84
|
+
'Promise',
|
|
85
|
+
'Generator',
|
|
86
|
+
'GeneratorFunction',
|
|
87
|
+
'AsyncFunction',
|
|
88
|
+
'AsyncGenerator',
|
|
89
|
+
'AsyncGeneratorFunction',
|
|
90
|
+
|
|
91
|
+
// Reflection
|
|
92
|
+
'Reflect',
|
|
93
|
+
'Proxy',
|
|
94
|
+
|
|
95
|
+
// Internationalization
|
|
96
|
+
'Intl',
|
|
97
|
+
|
|
98
|
+
// Web APIs (commonly used)
|
|
99
|
+
'URL',
|
|
100
|
+
'URLSearchParams',
|
|
101
|
+
'Headers',
|
|
102
|
+
'Request',
|
|
103
|
+
'Response',
|
|
104
|
+
'FormData',
|
|
105
|
+
'Blob',
|
|
106
|
+
'File',
|
|
107
|
+
'FileReader',
|
|
108
|
+
'AbortController',
|
|
109
|
+
'TextEncoder',
|
|
110
|
+
'TextDecoder',
|
|
111
|
+
'Event',
|
|
112
|
+
'CustomEvent',
|
|
113
|
+
'EventTarget',
|
|
114
|
+
'WebSocket',
|
|
115
|
+
'Worker',
|
|
116
|
+
'MessageChannel',
|
|
117
|
+
'MessagePort',
|
|
118
|
+
'BroadcastChannel',
|
|
119
|
+
'ReadableStream',
|
|
120
|
+
'WritableStream',
|
|
121
|
+
'TransformStream',
|
|
122
|
+
'CompressionStream',
|
|
123
|
+
'DecompressionStream',
|
|
124
|
+
]);
|
|
125
|
+
|
|
126
|
+
export class ConstructorCallNode {
|
|
127
|
+
static readonly TYPE = 'CONSTRUCTOR_CALL' as const;
|
|
128
|
+
|
|
129
|
+
static readonly REQUIRED = ['name', 'file', 'line', 'column', 'className', 'isBuiltin'] as const;
|
|
130
|
+
static readonly OPTIONAL = [] as const;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Check if a class name is a built-in JavaScript constructor
|
|
134
|
+
*/
|
|
135
|
+
static isBuiltinConstructor(className: string): boolean {
|
|
136
|
+
return BUILTIN_CONSTRUCTORS.has(className);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Generate ID for CONSTRUCTOR_CALL node
|
|
141
|
+
*
|
|
142
|
+
* @param className - Name of the constructor
|
|
143
|
+
* @param file - File path
|
|
144
|
+
* @param line - Line number
|
|
145
|
+
* @param column - Column position
|
|
146
|
+
* @param options - Optional counter for disambiguation
|
|
147
|
+
*/
|
|
148
|
+
static generateId(
|
|
149
|
+
className: string,
|
|
150
|
+
file: string,
|
|
151
|
+
line: number,
|
|
152
|
+
column: number,
|
|
153
|
+
options: ConstructorCallNodeOptions = {}
|
|
154
|
+
): string {
|
|
155
|
+
const counter = options.counter !== undefined ? `:${options.counter}` : '';
|
|
156
|
+
return `${file}:CONSTRUCTOR_CALL:${className}:${line}:${column}${counter}`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Create CONSTRUCTOR_CALL node
|
|
161
|
+
*
|
|
162
|
+
* @param className - Name of the constructor (e.g., 'Date', 'MyClass')
|
|
163
|
+
* @param file - File path
|
|
164
|
+
* @param line - Line number
|
|
165
|
+
* @param column - Column position
|
|
166
|
+
* @param options - Optional counter for disambiguation
|
|
167
|
+
*/
|
|
168
|
+
static create(
|
|
169
|
+
className: string,
|
|
170
|
+
file: string,
|
|
171
|
+
line: number,
|
|
172
|
+
column: number,
|
|
173
|
+
options: ConstructorCallNodeOptions = {}
|
|
174
|
+
): ConstructorCallNodeRecord {
|
|
175
|
+
if (!className) throw new Error('ConstructorCallNode.create: className is required');
|
|
176
|
+
if (!file) throw new Error('ConstructorCallNode.create: file is required');
|
|
177
|
+
if (line === undefined) throw new Error('ConstructorCallNode.create: line is required');
|
|
178
|
+
if (column === undefined) throw new Error('ConstructorCallNode.create: column is required');
|
|
179
|
+
|
|
180
|
+
const id = this.generateId(className, file, line, column, options);
|
|
181
|
+
const isBuiltin = this.isBuiltinConstructor(className);
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
id,
|
|
185
|
+
type: this.TYPE,
|
|
186
|
+
name: `new ${className}()`,
|
|
187
|
+
className,
|
|
188
|
+
isBuiltin,
|
|
189
|
+
file,
|
|
190
|
+
line,
|
|
191
|
+
column
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
static validate(node: ConstructorCallNodeRecord): string[] {
|
|
196
|
+
const errors: string[] = [];
|
|
197
|
+
|
|
198
|
+
if (node.type !== this.TYPE) {
|
|
199
|
+
errors.push(`Expected type ${this.TYPE}, got ${node.type}`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const nodeRecord = node as unknown as Record<string, unknown>;
|
|
203
|
+
for (const field of this.REQUIRED) {
|
|
204
|
+
if (nodeRecord[field] === undefined || nodeRecord[field] === null) {
|
|
205
|
+
errors.push(`Missing required field: ${field}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (typeof node.isBuiltin !== 'boolean') {
|
|
210
|
+
errors.push('isBuiltin must be a boolean');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return errors;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export type { ConstructorCallNodeRecord };
|
|
@@ -6,6 +6,7 @@ import type { BaseNodeRecord } from '@grafema/types';
|
|
|
6
6
|
|
|
7
7
|
interface DatabaseQueryNodeRecord extends BaseNodeRecord {
|
|
8
8
|
type: 'DATABASE_QUERY';
|
|
9
|
+
column: number;
|
|
9
10
|
query?: string;
|
|
10
11
|
operation: string;
|
|
11
12
|
parentScopeId?: string;
|
|
@@ -18,7 +19,7 @@ interface DatabaseQueryNodeOptions {
|
|
|
18
19
|
export class DatabaseQueryNode {
|
|
19
20
|
static readonly TYPE = 'DATABASE_QUERY' as const;
|
|
20
21
|
|
|
21
|
-
static readonly REQUIRED = ['name', 'file', 'line'] as const;
|
|
22
|
+
static readonly REQUIRED = ['name', 'file', 'line', 'column'] as const;
|
|
22
23
|
static readonly OPTIONAL = ['query', 'operation', 'parentScopeId'] as const;
|
|
23
24
|
|
|
24
25
|
static create(
|
|
@@ -26,10 +27,12 @@ export class DatabaseQueryNode {
|
|
|
26
27
|
operation: string | undefined,
|
|
27
28
|
file: string,
|
|
28
29
|
line: number,
|
|
30
|
+
column: number,
|
|
29
31
|
options: DatabaseQueryNodeOptions = {}
|
|
30
32
|
): DatabaseQueryNodeRecord {
|
|
31
33
|
if (!file) throw new Error('DatabaseQueryNode.create: file is required');
|
|
32
34
|
if (line === undefined) throw new Error('DatabaseQueryNode.create: line is required');
|
|
35
|
+
if (column === undefined) throw new Error('DatabaseQueryNode.create: column is required');
|
|
33
36
|
|
|
34
37
|
const name = query || `${operation || 'QUERY'}`;
|
|
35
38
|
const id = `${file}:DATABASE_QUERY:${name}:${line}`;
|
|
@@ -42,6 +45,7 @@ export class DatabaseQueryNode {
|
|
|
42
45
|
operation: operation || 'UNKNOWN',
|
|
43
46
|
file,
|
|
44
47
|
line,
|
|
48
|
+
column,
|
|
45
49
|
parentScopeId: options.parentScopeId
|
|
46
50
|
};
|
|
47
51
|
}
|
|
@@ -27,8 +27,8 @@ interface DecoratorNodeOptions {
|
|
|
27
27
|
export class DecoratorNode {
|
|
28
28
|
static readonly TYPE = 'DECORATOR' as const;
|
|
29
29
|
|
|
30
|
-
static readonly REQUIRED = ['name', 'file', 'line', 'targetId', 'targetType'] as const;
|
|
31
|
-
static readonly OPTIONAL = ['
|
|
30
|
+
static readonly REQUIRED = ['name', 'file', 'line', 'column', 'targetId', 'targetType'] as const;
|
|
31
|
+
static readonly OPTIONAL = ['arguments'] as const;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Create DECORATOR node
|
|
@@ -54,6 +54,7 @@ export class DecoratorNode {
|
|
|
54
54
|
if (!name) throw new Error('DecoratorNode.create: name is required');
|
|
55
55
|
if (!file) throw new Error('DecoratorNode.create: file is required');
|
|
56
56
|
if (!line) throw new Error('DecoratorNode.create: line is required');
|
|
57
|
+
if (column === undefined) throw new Error('DecoratorNode.create: column is required');
|
|
57
58
|
if (!targetId) throw new Error('DecoratorNode.create: targetId is required');
|
|
58
59
|
if (!targetType) throw new Error('DecoratorNode.create: targetType is required');
|
|
59
60
|
|
|
@@ -63,7 +64,7 @@ export class DecoratorNode {
|
|
|
63
64
|
name,
|
|
64
65
|
file,
|
|
65
66
|
line,
|
|
66
|
-
column
|
|
67
|
+
column,
|
|
67
68
|
arguments: options.arguments || [],
|
|
68
69
|
targetId,
|
|
69
70
|
targetType
|
|
@@ -29,8 +29,8 @@ interface EnumNodeOptions {
|
|
|
29
29
|
export class EnumNode {
|
|
30
30
|
static readonly TYPE = 'ENUM' as const;
|
|
31
31
|
|
|
32
|
-
static readonly REQUIRED = ['name', 'file', 'line'] as const;
|
|
33
|
-
static readonly OPTIONAL = ['
|
|
32
|
+
static readonly REQUIRED = ['name', 'file', 'line', 'column'] as const;
|
|
33
|
+
static readonly OPTIONAL = ['isConst', 'members'] as const;
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Create ENUM node
|
|
@@ -52,6 +52,7 @@ export class EnumNode {
|
|
|
52
52
|
if (!name) throw new Error('EnumNode.create: name is required');
|
|
53
53
|
if (!file) throw new Error('EnumNode.create: file is required');
|
|
54
54
|
if (!line) throw new Error('EnumNode.create: line is required');
|
|
55
|
+
if (column === undefined) throw new Error('EnumNode.create: column is required');
|
|
55
56
|
|
|
56
57
|
return {
|
|
57
58
|
id: `${file}:ENUM:${name}:${line}`,
|
|
@@ -59,7 +60,7 @@ export class EnumNode {
|
|
|
59
60
|
name,
|
|
60
61
|
file,
|
|
61
62
|
line,
|
|
62
|
-
column
|
|
63
|
+
column,
|
|
63
64
|
isConst: options.isConst || false,
|
|
64
65
|
members: options.members || []
|
|
65
66
|
};
|