@robinpath/robinpath 0.30.0

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.
Files changed (65) hide show
  1. package/README.md +856 -0
  2. package/bin/robinpath.js +374 -0
  3. package/dist/classes/ASTSerializer.d.ts +45 -0
  4. package/dist/classes/ExecutionStateTracker.d.ts +30 -0
  5. package/dist/classes/Executor.d.ts +193 -0
  6. package/dist/classes/ExpressionEvaluator.d.ts +20 -0
  7. package/dist/classes/Lexer.d.ts +86 -0
  8. package/dist/classes/Parser.d.ts +71 -0
  9. package/dist/classes/RobinPathThread.d.ts +146 -0
  10. package/dist/classes/TokenStream.d.ts +217 -0
  11. package/dist/classes/code-converter/ASTToCodeConverter.d.ts +178 -0
  12. package/dist/classes/code-converter/LineIndex.d.ts +54 -0
  13. package/dist/classes/code-converter/Printer.d.ts +117 -0
  14. package/dist/classes/code-converter/Writer.d.ts +42 -0
  15. package/dist/classes/code-converter/index.d.ts +8 -0
  16. package/dist/classes/code-converter/types.d.ts +29 -0
  17. package/dist/classes/exceptions.d.ts +26 -0
  18. package/dist/classes/index.d.ts +16 -0
  19. package/dist/index.d.ts +485 -0
  20. package/dist/index.js +13808 -0
  21. package/dist/modules/Array.d.ts +10 -0
  22. package/dist/modules/Core.d.ts +10 -0
  23. package/dist/modules/Dom.d.ts +10 -0
  24. package/dist/modules/Fetch.d.ts +6 -0
  25. package/dist/modules/Json.d.ts +10 -0
  26. package/dist/modules/Math.d.ts +10 -0
  27. package/dist/modules/Object.d.ts +10 -0
  28. package/dist/modules/Random.d.ts +6 -0
  29. package/dist/modules/String.d.ts +10 -0
  30. package/dist/modules/Test.d.ts +10 -0
  31. package/dist/modules/Time.d.ts +10 -0
  32. package/dist/parsers/ArrayLiteralParser.d.ts +17 -0
  33. package/dist/parsers/AssignmentParser.d.ts +37 -0
  34. package/dist/parsers/BracketParser.d.ts +31 -0
  35. package/dist/parsers/BreakParser.d.ts +15 -0
  36. package/dist/parsers/CellBlockParser.d.ts +11 -0
  37. package/dist/parsers/ChunkMarkerParser.d.ts +12 -0
  38. package/dist/parsers/CommandParser.d.ts +56 -0
  39. package/dist/parsers/CommentParser.d.ts +37 -0
  40. package/dist/parsers/ContinueParser.d.ts +15 -0
  41. package/dist/parsers/DecoratorParser.d.ts +29 -0
  42. package/dist/parsers/DefineParser.d.ts +18 -0
  43. package/dist/parsers/EventParser.d.ts +17 -0
  44. package/dist/parsers/ExpressionParser.d.ts +3 -0
  45. package/dist/parsers/FenceClassifier.d.ts +29 -0
  46. package/dist/parsers/ForLoopParser.d.ts +17 -0
  47. package/dist/parsers/IfBlockParser.d.ts +17 -0
  48. package/dist/parsers/ObjectLiteralParser.d.ts +17 -0
  49. package/dist/parsers/ParserUtils.d.ts +15 -0
  50. package/dist/parsers/PromptBlockParser.d.ts +10 -0
  51. package/dist/parsers/ReturnParser.d.ts +16 -0
  52. package/dist/parsers/ScopeParser.d.ts +24 -0
  53. package/dist/parsers/StringTemplateParser.d.ts +31 -0
  54. package/dist/parsers/SubexpressionParser.d.ts +33 -0
  55. package/dist/parsers/TogetherBlockParser.d.ts +18 -0
  56. package/dist/parsers/WithScopeParser.d.ts +24 -0
  57. package/dist/types/Ast.type.d.ts +455 -0
  58. package/dist/types/Environment.type.d.ts +53 -0
  59. package/dist/utils/args.d.ts +24 -0
  60. package/dist/utils/errorFormatter.d.ts +22 -0
  61. package/dist/utils/index.d.ts +8 -0
  62. package/dist/utils/stringParsing.d.ts +41 -0
  63. package/dist/utils/types.d.ts +15 -0
  64. package/dist/utils/valueConversion.d.ts +25 -0
  65. package/package.json +50 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Lexer class for tokenizing RobinPath code
3
+ */
4
+ /**
5
+ * Token kinds for RobinPath language
6
+ * Using const object instead of enum for better compatibility
7
+ */
8
+ export declare const TokenKind: {
9
+ readonly STRING: "STRING";
10
+ readonly NUMBER: "NUMBER";
11
+ readonly BOOLEAN: "BOOLEAN";
12
+ readonly NULL: "NULL";
13
+ readonly IDENTIFIER: "IDENTIFIER";
14
+ readonly VARIABLE: "VARIABLE";
15
+ readonly KEYWORD: "KEYWORD";
16
+ readonly ASSIGN: "ASSIGN";
17
+ readonly PLUS: "PLUS";
18
+ readonly MINUS: "MINUS";
19
+ readonly MULTIPLY: "MULTIPLY";
20
+ readonly DIVIDE: "DIVIDE";
21
+ readonly MODULO: "MODULO";
22
+ readonly EQ: "EQ";
23
+ readonly NE: "NE";
24
+ readonly GT: "GT";
25
+ readonly LT: "LT";
26
+ readonly GTE: "GTE";
27
+ readonly LTE: "LTE";
28
+ readonly AND: "AND";
29
+ readonly OR: "OR";
30
+ readonly NOT: "NOT";
31
+ readonly LPAREN: "LPAREN";
32
+ readonly RPAREN: "RPAREN";
33
+ readonly LBRACKET: "LBRACKET";
34
+ readonly RBRACKET: "RBRACKET";
35
+ readonly LBRACE: "LBRACE";
36
+ readonly RBRACE: "RBRACE";
37
+ readonly COMMA: "COMMA";
38
+ readonly COLON: "COLON";
39
+ readonly DOT: "DOT";
40
+ readonly DECORATOR: "DECORATOR";
41
+ readonly COMMENT: "COMMENT";
42
+ readonly NEWLINE: "NEWLINE";
43
+ readonly EOF: "EOF";
44
+ readonly SUBEXPRESSION_OPEN: "SUBEXPRESSION_OPEN";
45
+ };
46
+ export type TokenKind = typeof TokenKind[keyof typeof TokenKind];
47
+ /**
48
+ * List of RobinPath keywords
49
+ */
50
+ export declare const KEYWORDS: Set<string>;
51
+ /**
52
+ * A single token in the source code
53
+ */
54
+ export interface Token {
55
+ kind: TokenKind;
56
+ text: string;
57
+ line: number;
58
+ column: number;
59
+ value?: any;
60
+ isContinuation?: boolean;
61
+ }
62
+ /**
63
+ * Position information for error reporting
64
+ */
65
+ export interface SourcePosition {
66
+ line: number;
67
+ column: number;
68
+ }
69
+ export declare class Lexer {
70
+ /**
71
+ * Tokenize entire source code into Token objects
72
+ * This is the new token-stream based approach
73
+ *
74
+ * @param source - Full source code (multi-line)
75
+ * @returns Array of tokens with position information
76
+ */
77
+ static tokenizeFull(source: string): Token[];
78
+ /**
79
+ * Legacy tokenize method - kept for backward compatibility
80
+ * Tokenizes a single line into string tokens
81
+ *
82
+ * @param line - A single line of code
83
+ * @returns Array of string tokens
84
+ */
85
+ static tokenize(line: string): string[];
86
+ }
@@ -0,0 +1,71 @@
1
+ import { Statement, CodePosition, DefineFunction, OnBlock } from '../types/Ast.type';
2
+ import { Environment } from '../index';
3
+ export interface ExtractedVariable {
4
+ name: string;
5
+ description?: string;
6
+ initialValue?: any;
7
+ codePos: CodePosition;
8
+ }
9
+ export declare class Parser {
10
+ private tokens;
11
+ private stream;
12
+ private source;
13
+ private extractedFunctions;
14
+ private extractedEventHandlers;
15
+ private extractedVariables;
16
+ private environment;
17
+ private decoratorBuffer;
18
+ private pendingComments;
19
+ /**
20
+ * Maximum number of iterations allowed before detecting an infinite loop
21
+ */
22
+ static readonly MAX_STUCK_ITERATIONS = 100;
23
+ /**
24
+ * Debug mode flag - set to true to enable logging
25
+ * Can be controlled via VITE_DEBUG environment variable or set programmatically
26
+ */
27
+ static debug: boolean;
28
+ /**
29
+ * Create a new Parser
30
+ * @param source - Full source code as a single string
31
+ * @param environment - Optional environment for executing parse decorators
32
+ */
33
+ constructor(source: string, environment?: Environment | null);
34
+ /**
35
+ * Parse the source code into an AST
36
+ * @returns Array of statements
37
+ */
38
+ parse(): Promise<Statement[]>;
39
+ /**
40
+ * Parse a statement from a stream with hierarchical nodeKey support
41
+ */
42
+ private parseStatementFromStream;
43
+ /**
44
+ * Get extracted function definitions (def/enddef blocks)
45
+ */
46
+ getExtractedFunctions(): DefineFunction[];
47
+ /**
48
+ * Get extracted event handlers (on/endon blocks)
49
+ */
50
+ getExtractedEventHandlers(): OnBlock[];
51
+ /**
52
+ * Get extracted variables (from assignments)
53
+ */
54
+ getExtractedVariables(): ExtractedVariable[];
55
+ /**
56
+ * Track a variable from an assignment statement
57
+ */
58
+ private trackVariable;
59
+ /**
60
+ * Parse a single statement
61
+ */
62
+ private parseStatement;
63
+ private parseCommentFromStream;
64
+ private attachInlineComments;
65
+ private countTrailingBlankLines;
66
+ /**
67
+ * Recursively assign nodeKeys to body statements
68
+ * This ensures all nested statements have hierarchical nodeKeys for execution tracking
69
+ */
70
+ private assignBodyNodeKeys;
71
+ }
@@ -0,0 +1,146 @@
1
+ import { Value } from '../utils';
2
+ import { Environment, OnBlock, RobinPath } from '../index';
3
+ export declare class RobinPathThread {
4
+ private environment;
5
+ private executor;
6
+ readonly id: string;
7
+ private parent;
8
+ private serializer;
9
+ constructor(baseEnvironment: Environment, id: string, parent?: RobinPath);
10
+ /**
11
+ * Check if a script needs more input (incomplete block)
12
+ * Returns { needsMore: true, waitingFor: 'endif' | 'enddef' | 'endfor' | 'enddo' | 'subexpr' | 'paren' | 'object' | 'array' } if incomplete,
13
+ * or { needsMore: false } if complete.
14
+ */
15
+ needsMoreInput(script: string): Promise<{
16
+ needsMore: boolean;
17
+ waitingFor?: 'endif' | 'enddef' | 'endfor' | 'enddo' | 'subexpr' | 'paren' | 'object' | 'array';
18
+ }>;
19
+ /**
20
+ * Execute a RobinPath script in this thread
21
+ */
22
+ executeScript(script: string): Promise<Value>;
23
+ /**
24
+ * Execute a single line in this thread (for REPL)
25
+ */
26
+ executeLine(line: string): Promise<Value>;
27
+ /**
28
+ * Get the last value ($) from this thread
29
+ */
30
+ getLastValue(): Value;
31
+ /**
32
+ * Get a variable value from this thread
33
+ */
34
+ getVariable(name: string): Value;
35
+ /**
36
+ * Set a variable value in this thread
37
+ */
38
+ setVariable(name: string, value: Value): void;
39
+ /**
40
+ * Get all variables in this thread as a plain object
41
+ */
42
+ getVariableState(): Record<string, Value>;
43
+ /**
44
+ * Get the current module name (set by "use" command)
45
+ * Returns null if no module is currently in use
46
+ */
47
+ getCurrentModule(): string | null;
48
+ /**
49
+ * Get the parent RobinPath instance
50
+ */
51
+ getParent(): RobinPath | null;
52
+ /**
53
+ * Get the environment for this thread (for CLI access to metadata)
54
+ */
55
+ getEnvironment(): Environment;
56
+ /**
57
+ * Get the AST without execution state
58
+ * Returns a JSON-serializable AST array
59
+ *
60
+ * Note: This method only parses the script, it does not execute it.
61
+ */
62
+ getAST(script: string): Promise<any[]>;
63
+ /**
64
+ * Get extracted function definitions (def/enddef blocks) from a script
65
+ * Returns a JSON-serializable array of function definitions
66
+ *
67
+ * Note: This method only parses the script, it does not execute it.
68
+ */
69
+ getExtractedFunctions(script: string): Promise<any[]>;
70
+ /**
71
+ * Get all event handlers as a flat array
72
+ * @returns Array of all OnBlock handlers
73
+ */
74
+ getAllEventHandlers(): OnBlock[];
75
+ /**
76
+ * Get event handlers as serialized AST
77
+ * @returns Array of serialized event handler AST nodes
78
+ */
79
+ getEventAST(): any[];
80
+ /**
81
+ * Get the AST with execution state for the current thread
82
+ * Returns a JSON-serializable object with:
83
+ * - AST nodes with execution state ($ lastValue at each node)
84
+ * - Available variables (thread-local and global)
85
+ * - Organized for UI representation
86
+ *
87
+ * Note: This method executes the script to capture execution state at each node.
88
+ */
89
+ getASTWithState(script: string): Promise<{
90
+ ast: any[];
91
+ variables: {
92
+ thread: Record<string, Value>;
93
+ global: Record<string, Value>;
94
+ };
95
+ lastValue: Value;
96
+ callStack: Array<{
97
+ locals: Record<string, Value>;
98
+ lastValue: Value;
99
+ }>;
100
+ }>;
101
+ /**
102
+ * Execute statements with state tracking
103
+ */
104
+ private executeWithStateTracking;
105
+ /**
106
+ * Get all available commands, modules, and functions for this thread
107
+ * Includes thread-local user-defined functions in addition to shared builtins and modules
108
+ *
109
+ * @param context Optional syntax context to filter commands based on what's valid next
110
+ */
111
+ getAvailableCommands(context?: {
112
+ inIfBlock?: boolean;
113
+ inDefBlock?: boolean;
114
+ afterIf?: boolean;
115
+ afterDef?: boolean;
116
+ afterElseif?: boolean;
117
+ }): {
118
+ native: Array<{
119
+ name: string;
120
+ type: string;
121
+ description: string;
122
+ }>;
123
+ builtin: Array<{
124
+ name: string;
125
+ type: string;
126
+ description: string;
127
+ }>;
128
+ modules: Array<{
129
+ name: string;
130
+ type: string;
131
+ description: string;
132
+ author?: string;
133
+ category?: string;
134
+ }>;
135
+ moduleFunctions: Array<{
136
+ name: string;
137
+ type: string;
138
+ description: string;
139
+ }>;
140
+ userFunctions: Array<{
141
+ name: string;
142
+ type: string;
143
+ description: string;
144
+ }>;
145
+ };
146
+ }
@@ -0,0 +1,217 @@
1
+ import { TokenKind, Token } from './Lexer';
2
+ /**
3
+ * Parsing context types that the TokenStream can track
4
+ */
5
+ export declare const ParsingContext: {
6
+ readonly NONE: "none";
7
+ readonly ARRAY_LITERAL: "array_literal";
8
+ readonly OBJECT_LITERAL: "object_literal";
9
+ readonly FUNCTION_CALL: "function_call";
10
+ readonly SUBEXPRESSION: "subexpression";
11
+ readonly BLOCK: "block";
12
+ readonly FUNCTION_DEFINITION: "function_definition";
13
+ readonly STRING_LITERAL: "string_literal";
14
+ };
15
+ export type ParsingContext = typeof ParsingContext[keyof typeof ParsingContext];
16
+ export declare class TokenStream {
17
+ private tokens;
18
+ private position;
19
+ private contextStack;
20
+ private lastNextPosition;
21
+ private consecutiveNextCalls;
22
+ private positionHistory;
23
+ private operationsSinceLastAdvance;
24
+ private lastPositionValue;
25
+ /**
26
+ * Maximum number of consecutive next() calls allowed at the same position before throwing
27
+ */
28
+ static readonly MAX_CONSECUTIVE_NEXT_AT_SAME_POSITION = 3;
29
+ /**
30
+ * Maximum number of operations without position advancement before detecting stuck
31
+ * Only counts operations that should advance (next, match, expect, etc.)
32
+ */
33
+ static readonly MAX_OPERATIONS_WITHOUT_ADVANCE = 100;
34
+ /**
35
+ * Debug mode flag - set to true to enable logging
36
+ * Can be controlled via VITE_DEBUG environment variable or set programmatically
37
+ * Usage: TokenStream.debug = true;
38
+ */
39
+ static debug: boolean;
40
+ /**
41
+ * Create a new TokenStream
42
+ * @param tokens - Array of tokens to stream
43
+ * @param startIndex - Optional starting index (default 0)
44
+ */
45
+ constructor(tokens: Token[], startIndex?: number);
46
+ /**
47
+ * Create a new TokenStream starting from the given index
48
+ * Useful for sub-parsing operations that need to start from a specific position
49
+ * @param index - Starting index in the token array
50
+ * @returns New TokenStream instance starting at the given index
51
+ */
52
+ cloneFrom(index: number): TokenStream;
53
+ /**
54
+ * Reset stuck detection counters (useful when manually advancing position)
55
+ */
56
+ resetStuckDetection(): void;
57
+ /**
58
+ * Set the current position directly
59
+ * @param position - New position
60
+ */
61
+ setPosition(position: number): void;
62
+ /**
63
+ * Get the current token without consuming it
64
+ * @returns The current token, or null if at end
65
+ */
66
+ current(): Token | null;
67
+ /**
68
+ * Look ahead at a token without consuming it
69
+ * @param offset - Number of tokens to look ahead (default 0 = current token)
70
+ * @returns The token at the given offset, or null if beyond end
71
+ */
72
+ peek(offset?: number): Token | null;
73
+ /**
74
+ * Consume and return the current token
75
+ * @returns The current token, or null if at end
76
+ * @throws Error if called multiple times at the same position (indicates infinite loop)
77
+ */
78
+ next(): Token | null;
79
+ /**
80
+ * Check if the stream appears to be stuck (no position advancement)
81
+ * @param operation - Name of the operation being performed
82
+ * @throws Error if stuck condition detected
83
+ */
84
+ private checkStuckCondition;
85
+ /**
86
+ * Check if we're at the end of the token stream
87
+ * @returns True if at EOF or beyond
88
+ */
89
+ isAtEnd(): boolean;
90
+ /**
91
+ * Check if the current token matches the given kind or text, without consuming it
92
+ * @param kindOrText - TokenKind enum or string text to match
93
+ * @returns True if the current token matches
94
+ */
95
+ check(kindOrText: TokenKind | string): boolean;
96
+ /**
97
+ * If the current token matches, consume it and return true
98
+ * Otherwise, return false without consuming
99
+ *
100
+ * @param kindOrText - TokenKind enum or string text to match
101
+ * @returns True if matched and consumed, false otherwise
102
+ */
103
+ match(kindOrText: TokenKind | string): boolean;
104
+ /**
105
+ * Expect the current token to match, consume it, and return it
106
+ * If it doesn't match, throw an error
107
+ *
108
+ * @param kindOrText - TokenKind enum or string text to expect
109
+ * @param message - Optional custom error message
110
+ * @returns The consumed token
111
+ * @throws Error if token doesn't match
112
+ */
113
+ expect(kindOrText: TokenKind | string, message?: string): Token;
114
+ /**
115
+ * Save the current position for potential backtracking
116
+ * @returns The current position index
117
+ */
118
+ save(): number;
119
+ /**
120
+ * Restore a previously saved position (backtrack)
121
+ * @param pos - The position to restore to
122
+ */
123
+ restore(pos: number): void;
124
+ /**
125
+ * Skip tokens of a specific kind (useful for skipping newlines, comments, etc.)
126
+ * @param kind - The TokenKind to skip
127
+ * @returns Number of tokens skipped
128
+ */
129
+ skip(kind: TokenKind): number;
130
+ /**
131
+ * Skip all newline tokens
132
+ * @returns Number of newlines skipped
133
+ */
134
+ skipNewlines(): number;
135
+ /**
136
+ * Consume tokens until a specific kind or text is found (exclusive)
137
+ * @param kindOrText - The kind or text to stop at
138
+ * @returns Array of consumed tokens (not including the stop token)
139
+ */
140
+ consumeUntil(kindOrText: TokenKind | string): Token[];
141
+ /**
142
+ * Collect all tokens on the current line (until NEWLINE or EOF)
143
+ * @returns Array of tokens on the current line
144
+ */
145
+ collectLine(): Token[];
146
+ /**
147
+ * Get the current position in the stream
148
+ * @returns Current position index
149
+ */
150
+ getPosition(): number;
151
+ /**
152
+ * Get the total number of tokens in the stream
153
+ * @returns Total token count
154
+ */
155
+ getLength(): number;
156
+ /**
157
+ * Get all remaining tokens without consuming them
158
+ * @returns Array of remaining tokens
159
+ */
160
+ remaining(): Token[];
161
+ /**
162
+ * Create a sub-stream from a range of tokens
163
+ * Useful for parsing sub-expressions or blocks
164
+ *
165
+ * @param start - Start position (inclusive)
166
+ * @param end - End position (exclusive), defaults to current position
167
+ * @returns New TokenStream instance
168
+ */
169
+ slice(start: number, end?: number): TokenStream;
170
+ /**
171
+ * Format current position for error messages
172
+ * @returns String like "line 10, column 5"
173
+ */
174
+ formatPosition(): string;
175
+ /**
176
+ * Push a parsing context onto the context stack
177
+ * @param context - The parsing context to enter
178
+ */
179
+ pushContext(context: ParsingContext): void;
180
+ /**
181
+ * Pop the most recent parsing context from the stack
182
+ * @returns The context that was removed, or NONE if stack was empty
183
+ */
184
+ popContext(): ParsingContext;
185
+ /**
186
+ * Get the current parsing context (top of the stack)
187
+ * @returns The current parsing context, or NONE if no context is active
188
+ */
189
+ getCurrentContext(): ParsingContext;
190
+ /**
191
+ * Check if we're currently in a specific parsing context
192
+ * @param context - The context to check for
193
+ * @returns True if we're in the given context (at any level)
194
+ */
195
+ isInContext(context: ParsingContext): boolean;
196
+ /**
197
+ * Get all active contexts (the entire stack)
198
+ * @returns Array of contexts from bottom to top
199
+ */
200
+ getContextStack(): ParsingContext[];
201
+ /**
202
+ * Clear all parsing contexts
203
+ */
204
+ clearContexts(): void;
205
+ /**
206
+ * Create a new TokenStream with the same tokens and contexts
207
+ * Useful for sub-parsing that should inherit context
208
+ * @param startIndex - Optional starting index (defaults to current position)
209
+ * @returns New TokenStream instance with copied context
210
+ */
211
+ cloneWithContext(startIndex?: number): TokenStream;
212
+ /**
213
+ * Skip whitespace (newlines) and comments
214
+ * Advances the stream past any consecutive newline or comment tokens
215
+ */
216
+ skipWhitespaceAndComments(): void;
217
+ }
@@ -0,0 +1,178 @@
1
+ import { Statement, CommentWithPosition } from '../../types/Ast.type';
2
+ import { Writer } from './Writer';
3
+ import { LineIndex } from './LineIndex';
4
+ import { Patch, CommentLayout, PrintContext } from './types';
5
+ export type { CommentWithPosition, LineIndex, PrintContext };
6
+ export { Writer };
7
+ /**
8
+ * CommentLayout - Normalize comment ownership
9
+ *
10
+ * Decides, per statement:
11
+ * - leadingComments: Comment[] (non-inline)
12
+ * - inlineComment: Comment | null
13
+ * - leadingGapLines: number (blank lines between last leading comment and statement)
14
+ * - trailingBlankLinesAfterStandaloneComment: number (only for standalone comment nodes)
15
+ */
16
+ export declare class CommentLayoutNormalizer {
17
+ /**
18
+ * Normalize comment layout for a statement
19
+ */
20
+ static normalize(node: Statement, lineIndex: LineIndex): CommentLayout;
21
+ }
22
+ /**
23
+ * PatchApplier - Apply patches to source code
24
+ *
25
+ * Sort patches descending (as you do now) and apply.
26
+ * Optional: validate overlaps and throw in dev mode.
27
+ */
28
+ export declare class PatchApplier {
29
+ /**
30
+ * Apply patches to source code
31
+ * Patches are sorted descending by startOffset and applied from end to start
32
+ * to prevent character position shifts from affecting subsequent replacements
33
+ */
34
+ static apply(originalScript: string, patches: Patch[]): string;
35
+ /**
36
+ * Validate that patches don't overlap
37
+ * @internal This method is kept for potential future use or manual invocation
38
+ */
39
+ static validatePatches(patches: Patch[]): void;
40
+ }
41
+ /**
42
+ * PatchPlanner - Collect edit operations
43
+ *
44
+ * Produces Patch[] = { startOffset, endOffset, replacement }.
45
+ * Responsible for "range selection" (including blank lines, inline comment removal, etc.)
46
+ * Must guarantee patches don't overlap (or resolve overlaps deterministically).
47
+ */
48
+ export declare class PatchPlanner {
49
+ private lineIndex;
50
+ private patches;
51
+ private originalScript;
52
+ private originalAST;
53
+ /**
54
+ * Enable defensive validation of extracted code.
55
+ * When true, extracted code is validated before use and falls back to regeneration if invalid.
56
+ * Set via ROBINPATH_DEBUG environment variable or constructor option.
57
+ */
58
+ private debugMode;
59
+ constructor(originalScript: string, options?: {
60
+ debugMode?: boolean;
61
+ });
62
+ /**
63
+ * Plan patches for all nodes in the AST
64
+ * This includes patches for:
65
+ * - Updated nodes (in modified AST)
66
+ * - New nodes (in modified AST but not in original)
67
+ * - Deleted nodes (in original AST but not in modified)
68
+ */
69
+ planPatches(ast: Statement[]): Promise<Patch[]>;
70
+ /**
71
+ * Plan a patch for a deleted node
72
+ */
73
+ private planPatchForDeletedNode;
74
+ /**
75
+ * Plan a patch for a single node
76
+ */
77
+ private planPatchForNode;
78
+ /**
79
+ * Plan a patch for a new node (insertion)
80
+ */
81
+ private planPatchForNewNode;
82
+ /**
83
+ * Plan patch for leading comments (non-overlapping case)
84
+ */
85
+ private planPatchForLeadingComments;
86
+ /**
87
+ * Generate replacement without leading comments (for non-overlapping case)
88
+ */
89
+ private generateReplacementWithoutLeadingComments;
90
+ /**
91
+ * Plan patch for a standalone comment node
92
+ */
93
+ private planPatchForCommentNode;
94
+ /**
95
+ * Find the stop row for comment blank line inclusion
96
+ */
97
+ private findStopRowForComment;
98
+ /**
99
+ * Plan patch to remove existing comments
100
+ */
101
+ private planPatchToRemoveComments;
102
+ /**
103
+ * Compute the range for a statement region
104
+ */
105
+ private computeStatementRange;
106
+ /**
107
+ * Generate replacement text for a node
108
+ */
109
+ private generateReplacement;
110
+ /**
111
+ * Preserve blank lines that were included in the range after the statement
112
+ */
113
+ private preserveBlankLinesInRange;
114
+ /**
115
+ * Extract original code from the script if the node hasn't changed
116
+ * Returns null if the node has changed and needs regeneration
117
+ *
118
+ * This preserves all original formatting including:
119
+ * - Indentation (spaces and tabs)
120
+ * - Spacing within statements
121
+ * - Blank lines
122
+ */
123
+ private extractOriginalCode;
124
+ /**
125
+ * Validate extracted code by checking if it parses correctly and matches expected type.
126
+ * Used in debug mode to detect extraction corruption.
127
+ */
128
+ private validateExtractedCode;
129
+ /**
130
+ * Find the original node that corresponds to the modified node
131
+ */
132
+ private findOriginalNode;
133
+ /**
134
+ * Compare two nodes to see if they're equal (ignoring codePos and metadata)
135
+ */
136
+ private nodesAreEqual;
137
+ /**
138
+ * Generate code with preserved indentation and spacing from original
139
+ * This is used when we must regenerate code but want to preserve formatting
140
+ */
141
+ private generateCodeWithPreservedIndentation;
142
+ }
143
+ /**
144
+ * ASTToCodeConverter - Converts AST nodes back to source code
145
+ *
146
+ * This class handles the conversion of AST (Abstract Syntax Tree) nodes
147
+ * back into RobinPath source code strings. It provides methods for:
148
+ * - Updating source code based on AST changes
149
+ * - Reconstructing code from individual AST nodes
150
+ * - Handling comments, indentation, and code positioning
151
+ */
152
+ export declare class ASTToCodeConverter {
153
+ /**
154
+ * Validate that AST node positions are within bounds of the source code.
155
+ * This helps detect stale AST data from external source modifications.
156
+ *
157
+ * @param source The current source code
158
+ * @param ast The AST to validate
159
+ * @returns Object with isValid flag and optional error details
160
+ */
161
+ private validateASTPositions;
162
+ /**
163
+ * Update source code based on AST changes
164
+ * Uses precise character-level positions (codePos.startRow/startCol/endRow/endCol) to update code
165
+ * Nested nodes are reconstructed as part of their parent's code
166
+ * @param originalScript The original source code
167
+ * @param ast The modified AST array (top-level nodes only)
168
+ * @returns Updated source code
169
+ */
170
+ updateCodeFromAST(originalScript: string, ast: Statement[]): Promise<string>;
171
+ /**
172
+ * Reconstruct code string from an AST node
173
+ * @param node The AST node (serialized)
174
+ * @param indentLevel Indentation level for nested code
175
+ * @returns Reconstructed code string, or null if cannot be reconstructed
176
+ */
177
+ reconstructCodeFromASTNode(node: Statement, indentLevel?: number): string | null;
178
+ }