sf-agentpmd 0.1.0 → 0.1.2

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 (100) hide show
  1. package/NOTICE +7 -5
  2. package/dist/commands/agentpmd/analyze.js +4141 -109
  3. package/dist/commands/agentpmd/analyze.js.map +7 -1
  4. package/dist/commands/agentpmd/install-skill.js +42 -31
  5. package/dist/commands/agentpmd/install-skill.js.map +7 -1
  6. package/dist/index.js +4155 -3
  7. package/dist/index.js.map +7 -1
  8. package/oclif.manifest.json +2 -2
  9. package/package.json +7 -8
  10. package/dist/analyzer/action-references.d.ts +0 -21
  11. package/dist/analyzer/action-references.js +0 -130
  12. package/dist/analyzer/action-references.js.map +0 -1
  13. package/dist/analyzer/analyze.d.ts +0 -43
  14. package/dist/analyzer/analyze.js +0 -222
  15. package/dist/analyzer/analyze.js.map +0 -1
  16. package/dist/analyzer/apex-analyze.d.ts +0 -14
  17. package/dist/analyzer/apex-analyze.js +0 -60
  18. package/dist/analyzer/apex-analyze.js.map +0 -1
  19. package/dist/analyzer/apex-complexity.d.ts +0 -27
  20. package/dist/analyzer/apex-complexity.js +0 -133
  21. package/dist/analyzer/apex-complexity.js.map +0 -1
  22. package/dist/analyzer/apex-parse.d.ts +0 -39
  23. package/dist/analyzer/apex-parse.js +0 -32
  24. package/dist/analyzer/apex-parse.js.map +0 -1
  25. package/dist/analyzer/apex-resolve.d.ts +0 -32
  26. package/dist/analyzer/apex-resolve.js +0 -59
  27. package/dist/analyzer/apex-resolve.js.map +0 -1
  28. package/dist/analyzer/complexity.d.ts +0 -30
  29. package/dist/analyzer/complexity.js +0 -126
  30. package/dist/analyzer/complexity.js.map +0 -1
  31. package/dist/analyzer/parse.d.ts +0 -51
  32. package/dist/analyzer/parse.js +0 -143
  33. package/dist/analyzer/parse.js.map +0 -1
  34. package/dist/analyzer/project.d.ts +0 -12
  35. package/dist/analyzer/project.js +0 -51
  36. package/dist/analyzer/project.js.map +0 -1
  37. package/dist/analyzer/types.d.ts +0 -76
  38. package/dist/analyzer/types.js +0 -2
  39. package/dist/analyzer/types.js.map +0 -1
  40. package/dist/commands/agentpmd/analyze.d.ts +0 -20
  41. package/dist/commands/agentpmd/install-skill.d.ts +0 -11
  42. package/dist/index.d.ts +0 -3
  43. package/dist/renderers/csv.d.ts +0 -6
  44. package/dist/renderers/csv.js +0 -78
  45. package/dist/renderers/csv.js.map +0 -1
  46. package/dist/renderers/index.d.ts +0 -8
  47. package/dist/renderers/index.js +0 -25
  48. package/dist/renderers/index.js.map +0 -1
  49. package/dist/renderers/markdown.d.ts +0 -12
  50. package/dist/renderers/markdown.js +0 -233
  51. package/dist/renderers/markdown.js.map +0 -1
  52. package/dist/renderers/options.d.ts +0 -20
  53. package/dist/renderers/options.js +0 -2
  54. package/dist/renderers/options.js.map +0 -1
  55. package/dist/renderers/sarif.d.ts +0 -3
  56. package/dist/renderers/sarif.js +0 -131
  57. package/dist/renderers/sarif.js.map +0 -1
  58. package/dist/renderers/text.d.ts +0 -3
  59. package/dist/renderers/text.js +0 -243
  60. package/dist/renderers/text.js.map +0 -1
  61. package/vendor/agentscript-parser-javascript/dist/cst-node.d.ts +0 -83
  62. package/vendor/agentscript-parser-javascript/dist/cst-node.js +0 -238
  63. package/vendor/agentscript-parser-javascript/dist/errors.d.ts +0 -34
  64. package/vendor/agentscript-parser-javascript/dist/errors.js +0 -74
  65. package/vendor/agentscript-parser-javascript/dist/expressions.d.ts +0 -36
  66. package/vendor/agentscript-parser-javascript/dist/expressions.js +0 -682
  67. package/vendor/agentscript-parser-javascript/dist/highlighter.d.ts +0 -24
  68. package/vendor/agentscript-parser-javascript/dist/highlighter.js +0 -260
  69. package/vendor/agentscript-parser-javascript/dist/index.d.ts +0 -29
  70. package/vendor/agentscript-parser-javascript/dist/index.js +0 -35
  71. package/vendor/agentscript-parser-javascript/dist/lexer.d.ts +0 -60
  72. package/vendor/agentscript-parser-javascript/dist/lexer.js +0 -630
  73. package/vendor/agentscript-parser-javascript/dist/parse-mapping.d.ts +0 -46
  74. package/vendor/agentscript-parser-javascript/dist/parse-mapping.js +0 -549
  75. package/vendor/agentscript-parser-javascript/dist/parse-sequence.d.ts +0 -10
  76. package/vendor/agentscript-parser-javascript/dist/parse-sequence.js +0 -118
  77. package/vendor/agentscript-parser-javascript/dist/parse-statements.d.ts +0 -15
  78. package/vendor/agentscript-parser-javascript/dist/parse-statements.js +0 -519
  79. package/vendor/agentscript-parser-javascript/dist/parse-templates.d.ts +0 -15
  80. package/vendor/agentscript-parser-javascript/dist/parse-templates.js +0 -323
  81. package/vendor/agentscript-parser-javascript/dist/parser.d.ts +0 -65
  82. package/vendor/agentscript-parser-javascript/dist/parser.js +0 -163
  83. package/vendor/agentscript-parser-javascript/dist/recovery.d.ts +0 -51
  84. package/vendor/agentscript-parser-javascript/dist/recovery.js +0 -199
  85. package/vendor/agentscript-parser-javascript/dist/token.d.ts +0 -58
  86. package/vendor/agentscript-parser-javascript/dist/token.js +0 -62
  87. package/vendor/agentscript-parser-javascript/package.json +0 -19
  88. package/vendor/agentscript-types/dist/comment.d.ts +0 -11
  89. package/vendor/agentscript-types/dist/comment.js +0 -10
  90. package/vendor/agentscript-types/dist/cst.d.ts +0 -7
  91. package/vendor/agentscript-types/dist/cst.js +0 -8
  92. package/vendor/agentscript-types/dist/diagnostic.d.ts +0 -34
  93. package/vendor/agentscript-types/dist/diagnostic.js +0 -23
  94. package/vendor/agentscript-types/dist/index.d.ts +0 -9
  95. package/vendor/agentscript-types/dist/index.js +0 -10
  96. package/vendor/agentscript-types/dist/position.d.ts +0 -11
  97. package/vendor/agentscript-types/dist/position.js +0 -16
  98. package/vendor/agentscript-types/dist/syntax-node.d.ts +0 -39
  99. package/vendor/agentscript-types/dist/syntax-node.js +0 -8
  100. package/vendor/agentscript-types/package.json +0 -15
@@ -1,15 +0,0 @@
1
- import { CSTNode } from './cst-node.js';
2
- import type { ParserContext } from './parser.js';
3
- export declare function isStatementStart(ctx: ParserContext): boolean;
4
- export declare function parseProcedure(ctx: ParserContext, parseTemplate?: (ctx: ParserContext) => CSTNode): CSTNode;
5
- export declare function parseStatement(ctx: ParserContext, parseTemplate?: (ctx: ParserContext) => CSTNode): CSTNode | null;
6
- export declare function parseIfStatement(ctx: ParserContext, parseTemplate?: (ctx: ParserContext) => CSTNode): CSTNode;
7
- export declare function parseRunStatement(ctx: ParserContext, parseTemplate?: (ctx: ParserContext) => CSTNode): CSTNode;
8
- export declare function parseSetStatement(ctx: ParserContext): CSTNode;
9
- export declare function parseTransitionStatement(ctx: ParserContext): CSTNode;
10
- export declare function parseWithStatement(ctx: ParserContext): CSTNode;
11
- export declare function parseAvailableWhenStatement(ctx: ParserContext): CSTNode;
12
- export declare function tryParseWithToStatementList(ctx: ParserContext): CSTNode | null;
13
- export declare function parseInlineWithStatement(ctx: ParserContext): CSTNode;
14
- export declare function parseToStatement(ctx: ParserContext): CSTNode;
15
- //# sourceMappingURL=parse-statements.d.ts.map
@@ -1,519 +0,0 @@
1
- /*
2
- * Copyright (c) 2026, Salesforce, Inc.
3
- * All rights reserved.
4
- * SPDX-License-Identifier: Apache-2.0
5
- * For full license text, see the LICENSE file in the repo root or https://www.apache.org/licenses/LICENSE-2.0
6
- */
7
- /**
8
- * Statement-parsing functions extracted from Parser class.
9
- *
10
- * Each function takes a ParserContext as its first parameter, following
11
- * the same free-function pattern as recovery.ts and expressions.ts.
12
- *
13
- * Functions that call parseProcedure (which in turn calls parseStatement,
14
- * which may delegate to parseTemplate) accept an optional parseTemplate
15
- * callback to avoid circular dependency with parser.ts.
16
- */
17
- import { isTokenKind, TokenKind } from './token.js';
18
- import { CSTNode } from './cst-node.js';
19
- import { makeErrorNode, tokenToAutoLeaf } from './errors.js';
20
- import { makeEmptyError, addMissingTarget, makeMissing, synchronize, synchronizeRow, synchronizeRowUntilColon, consumeCommentsAndSkipNewlines, skipNewlines, isAtEnd, isTrailingCommentOnly, parseOrphanBlock, } from './recovery.js';
21
- import { parseExpression, wrapExpression, parseString } from './expressions.js';
22
- // ---------------------------------------------------------------------------
23
- // Statement detection
24
- // ---------------------------------------------------------------------------
25
- export function isStatementStart(ctx) {
26
- const tok = ctx.peek();
27
- if (tok.kind !== TokenKind.ID)
28
- return false;
29
- switch (tok.text) {
30
- case 'if':
31
- case 'run':
32
- case 'set':
33
- case 'transition':
34
- return true;
35
- case 'with':
36
- // "with" is a statement only if not followed by colon (which would make it a key)
37
- return ctx.peekAt(1).kind !== TokenKind.COLON;
38
- case 'available':
39
- return (ctx.peekAt(1).kind === TokenKind.ID && ctx.peekAt(1).text === 'when');
40
- default:
41
- return false;
42
- }
43
- }
44
- // ---------------------------------------------------------------------------
45
- // Procedure & statement dispatch
46
- // ---------------------------------------------------------------------------
47
- export function parseProcedure(ctx, parseTemplate) {
48
- const startTok = ctx.peek();
49
- const node = ctx.startNode('procedure');
50
- while (!isAtEnd(ctx) && ctx.peekKind() !== TokenKind.DEDENT) {
51
- skipNewlines(ctx);
52
- if (isAtEnd(ctx) || ctx.peekKind() === TokenKind.DEDENT)
53
- break;
54
- // Don't consume trailing comments that belong to the parent scope
55
- // (tree-sitter parity: extras at block boundaries attach to the parent).
56
- if (ctx.peekKind() === TokenKind.COMMENT && isTrailingCommentOnly(ctx)) {
57
- break;
58
- }
59
- const stmt = parseStatement(ctx, parseTemplate);
60
- if (stmt) {
61
- node.appendChild(stmt);
62
- }
63
- else {
64
- const err = synchronize(ctx);
65
- if (err) {
66
- node.appendChild(err);
67
- }
68
- else if (!isAtEnd(ctx) && ctx.peekKind() !== TokenKind.DEDENT) {
69
- ctx.consume();
70
- }
71
- }
72
- }
73
- // If the procedure is empty, add an ERROR node (Error 07, 34)
74
- if (node.namedChildren.length === 0) {
75
- node.appendChild(makeEmptyError(ctx));
76
- }
77
- ctx.finishNode(node, startTok);
78
- return node;
79
- }
80
- export function parseStatement(ctx, parseTemplate) {
81
- const tok = ctx.peek();
82
- if (tok.kind === TokenKind.ID) {
83
- switch (tok.text) {
84
- case 'if':
85
- return parseIfStatement(ctx, parseTemplate);
86
- case 'run':
87
- return parseRunStatement(ctx, parseTemplate);
88
- case 'set':
89
- return parseSetStatement(ctx);
90
- case 'transition':
91
- return parseTransitionStatement(ctx);
92
- case 'with':
93
- return parseWithStatement(ctx);
94
- case 'available': {
95
- if (ctx.peekAt(1).kind === TokenKind.ID &&
96
- ctx.peekAt(1).text === 'when') {
97
- return parseAvailableWhenStatement(ctx);
98
- }
99
- break;
100
- }
101
- case 'else':
102
- case 'elif':
103
- case 'for':
104
- // Orphan else/elif (without if) or unsupported for → wrap in ERROR
105
- return parseOrphanBlock(ctx, c => parseProcedure(c, parseTemplate));
106
- }
107
- }
108
- if (tok.kind === TokenKind.PIPE && parseTemplate) {
109
- return parseTemplate(ctx);
110
- }
111
- if (tok.kind === TokenKind.COMMENT) {
112
- const comment = ctx.consumeNamed('comment');
113
- if (ctx.peekKind() === TokenKind.NEWLINE)
114
- ctx.consume();
115
- return comment;
116
- }
117
- // Fallback: try parsing as a bare expression (e.g., `...` inside a procedure)
118
- // This keeps expressions as proper expression nodes instead of ERROR-wrapped tokens.
119
- const expr = parseExpression(ctx, 0);
120
- if (expr) {
121
- const wrapped = wrapExpression(ctx, expr);
122
- if (ctx.peekKind() === TokenKind.NEWLINE)
123
- ctx.consume();
124
- return wrapped;
125
- }
126
- return null;
127
- }
128
- // ---------------------------------------------------------------------------
129
- // Shared colon → procedure body
130
- // ---------------------------------------------------------------------------
131
- /**
132
- * Shared colon → procedure body sequence for if/elif/else.
133
- * Consumes colon (with recovery), inline comment, extra inline tokens,
134
- * then INDENT → procedure → DEDENT, and trailing NEWLINE.
135
- *
136
- * @param errorOnMissingBody - if true, insert ERROR when colon has no
137
- * indented body (used by `if`; elif/else silently accept missing body).
138
- */
139
- function parseColonAndProcedureBody(ctx, node, row, errorOnMissingBody, parseTemplate) {
140
- // Colon (or recovery)
141
- if (ctx.peekKind() === TokenKind.COLON) {
142
- ctx.addAnonymousChild(node, ctx.consume());
143
- }
144
- else if (errorOnMissingBody) {
145
- node.appendChild(makeEmptyError(ctx));
146
- }
147
- // Inline comment after colon
148
- if (ctx.peekKind() === TokenKind.COMMENT) {
149
- node.appendChild(ctx.consumeNamed('comment'));
150
- }
151
- // Absorb extra inline tokens after colon on the same row
152
- const inlineErr = synchronizeRow(ctx, row);
153
- if (inlineErr)
154
- node.appendChild(inlineErr);
155
- // Consequence block
156
- if (ctx.peekKind() === TokenKind.INDENT) {
157
- ctx.consume();
158
- const proc = parseProcedure(ctx, parseTemplate);
159
- if (proc)
160
- node.appendChild(proc, 'consequence');
161
- consumeCommentsAndSkipNewlines(ctx, node);
162
- if (ctx.peekKind() === TokenKind.DEDENT)
163
- ctx.consume();
164
- }
165
- else if (errorOnMissingBody &&
166
- (ctx.peekKind() === TokenKind.NEWLINE || ctx.isAtSyncPoint())) {
167
- node.appendChild(makeEmptyError(ctx));
168
- }
169
- if (ctx.peekKind() === TokenKind.NEWLINE)
170
- ctx.consume();
171
- }
172
- // ---------------------------------------------------------------------------
173
- // Individual statement parsers
174
- // ---------------------------------------------------------------------------
175
- export function parseIfStatement(ctx, parseTemplate) {
176
- const startTok = ctx.peek();
177
- const node = ctx.startNode('if_statement');
178
- ctx.addAnonymousChild(node, ctx.consume()); // if
179
- // Condition
180
- let condition = parseExpression(ctx, 0);
181
- // Handle single `=` typo (should be `==`): wrap `=` in ERROR,
182
- // build comparison_expression, then continue parsing normally
183
- if (condition && ctx.peekKind() === TokenKind.EQ) {
184
- const eqTok = ctx.consume(); // =
185
- const right = parseExpression(ctx, 5); // parse right side above comparison
186
- if (right) {
187
- // Build: (comparison_expression (expr left) (ERROR =) (expr right))
188
- const cmp = ctx.startNodeAt('comparison_expression', condition);
189
- cmp.appendChild(wrapExpression(ctx, condition));
190
- // Wrap `=` in ERROR
191
- const eqChild = new CSTNode('=', ctx.source, eqTok.startOffset, eqTok.startOffset + 1, eqTok.start, eqTok.end, false);
192
- const eqErr = makeErrorNode(ctx.source, [eqChild], eqTok.startOffset, eqTok.startOffset + 1, eqTok.start, eqTok.end);
193
- cmp.appendChild(eqErr);
194
- cmp.appendChild(wrapExpression(ctx, right));
195
- cmp.finalize();
196
- condition = cmp;
197
- }
198
- }
199
- if (condition)
200
- node.appendChild(wrapExpression(ctx, condition), 'condition');
201
- // Absorb extra tokens between condition and colon on the same row.
202
- if (condition &&
203
- ctx.peekKind() !== TokenKind.COLON &&
204
- !ctx.isAtSyncPoint() &&
205
- ctx.peekKind() !== TokenKind.INDENT) {
206
- const condRow = startTok.start.row;
207
- const err = synchronizeRowUntilColon(ctx, condRow);
208
- if (err)
209
- node.appendChild(err);
210
- }
211
- parseColonAndProcedureBody(ctx, node, startTok.start.row, true, parseTemplate);
212
- // elif clauses (including misspelled 'elseif')
213
- while (ctx.peekKind() === TokenKind.ID &&
214
- (ctx.peek().text === 'elif' || ctx.peek().text === 'elseif')) {
215
- const elif = parseElifClause(ctx, parseTemplate);
216
- if (elif)
217
- node.appendChild(elif, 'alternative');
218
- }
219
- // else clause
220
- if (ctx.peekKind() === TokenKind.ID && ctx.peek().text === 'else') {
221
- const elseClause = parseElseClause(ctx, parseTemplate);
222
- if (elseClause)
223
- node.appendChild(elseClause, 'alternative');
224
- }
225
- ctx.finishNode(node, startTok);
226
- return node;
227
- }
228
- function parseElifClause(ctx, parseTemplate) {
229
- const startTok = ctx.peek();
230
- const node = ctx.startNode('elif_clause');
231
- const kw = ctx.consume(); // elif or elseif
232
- if (kw.text === 'elseif') {
233
- // Wrap misspelled keyword in ERROR
234
- const kwEnd = kw.startOffset + kw.text.length;
235
- const leaf = tokenToAutoLeaf(kw, ctx.source, kw.startOffset);
236
- const errNode = makeErrorNode(ctx.source, [leaf], kw.startOffset, kwEnd, kw.start, kw.end);
237
- node.appendChild(errNode);
238
- }
239
- else {
240
- ctx.addAnonymousChild(node, kw);
241
- }
242
- const condition = parseExpression(ctx, 0);
243
- if (condition)
244
- node.appendChild(wrapExpression(ctx, condition), 'condition');
245
- // Absorb extra tokens between condition and colon (same as if)
246
- if (condition &&
247
- ctx.peekKind() !== TokenKind.COLON &&
248
- !ctx.isAtSyncPoint() &&
249
- ctx.peekKind() !== TokenKind.INDENT) {
250
- const condRow = startTok.start.row;
251
- const err = synchronizeRowUntilColon(ctx, condRow);
252
- if (err)
253
- node.appendChild(err);
254
- }
255
- parseColonAndProcedureBody(ctx, node, startTok.start.row, false, parseTemplate);
256
- ctx.finishNode(node, startTok);
257
- return node;
258
- }
259
- function parseElseClause(ctx, parseTemplate) {
260
- const startTok = ctx.peek();
261
- const node = ctx.startNode('else_clause');
262
- ctx.addAnonymousChild(node, ctx.consume()); // else
263
- parseColonAndProcedureBody(ctx, node, startTok.start.row, false, parseTemplate);
264
- ctx.finishNode(node, startTok);
265
- return node;
266
- }
267
- export function parseRunStatement(ctx, parseTemplate) {
268
- const startTok = ctx.peek();
269
- const node = ctx.startNode('run_statement');
270
- ctx.addAnonymousChild(node, ctx.consume()); // run
271
- // Target expression
272
- if (!ctx.isAtSyncPoint()) {
273
- const target = parseExpression(ctx, 0);
274
- if (target) {
275
- node.appendChild(wrapExpression(ctx, target), 'target');
276
- }
277
- else {
278
- addMissingTarget(ctx, node);
279
- }
280
- }
281
- else {
282
- // `run` with no target at all → insert ERROR placeholder
283
- addMissingTarget(ctx, node);
284
- }
285
- // Optional indented block (procedure)
286
- if (ctx.peekKind() === TokenKind.INDENT) {
287
- ctx.consume();
288
- // Comments before procedure body attach to run_statement
289
- consumeCommentsAndSkipNewlines(ctx, node);
290
- const proc = parseProcedure(ctx, parseTemplate);
291
- if (proc) {
292
- // If procedure contains an ERROR with `with` keyword (invalid with clause),
293
- // attach children directly to run_statement so the dialect's
294
- // error recovery can find them (it looks at run_statement.children).
295
- const hasWithError = proc.namedChildren.some(c => c.isError && c.children.some(cc => cc.type === 'with'));
296
- if (hasWithError) {
297
- for (const child of proc.namedChildren) {
298
- node.appendChild(child);
299
- }
300
- }
301
- else {
302
- node.appendChild(proc, 'block_value');
303
- }
304
- }
305
- consumeCommentsAndSkipNewlines(ctx, node);
306
- if (ctx.peekKind() === TokenKind.DEDENT)
307
- ctx.consume();
308
- }
309
- if (ctx.peekKind() === TokenKind.NEWLINE)
310
- ctx.consume();
311
- ctx.finishNode(node, startTok);
312
- return node;
313
- }
314
- export function parseSetStatement(ctx) {
315
- const startTok = ctx.peek();
316
- const node = ctx.startNode('set_statement');
317
- ctx.addAnonymousChild(node, ctx.consume()); // set
318
- // Parse target at precedence 5 (above comparison/=) so = and == aren't consumed
319
- const target = parseExpression(ctx, 5);
320
- if (ctx.peekKind() === TokenKind.EQEQ) {
321
- // set @var == "value" → ERROR: == instead of =
322
- // Build comparison_expression(target, ==, rhs) and wrap in ERROR
323
- // Don't add target to node — we're returning an ERROR node instead
324
- const eqTok = ctx.consume(); // ==
325
- const rhs = parseExpression(ctx, 0);
326
- if (target && rhs) {
327
- const cmp = ctx.startNodeAt('comparison_expression', wrapExpression(ctx, target));
328
- cmp.appendChild(wrapExpression(ctx, target));
329
- cmp.appendChild(new CSTNode(eqTok.text, ctx.source, eqTok.startOffset, eqTok.startOffset + 2, eqTok.start, eqTok.end, false));
330
- cmp.appendChild(wrapExpression(ctx, rhs));
331
- cmp.finalize();
332
- const wrappedCmp = wrapExpression(ctx, cmp);
333
- if (ctx.peekKind() === TokenKind.NEWLINE)
334
- ctx.consume();
335
- // Return ERROR instead of set_statement
336
- return makeErrorNode(ctx.source, [wrappedCmp], wrappedCmp.startOffset, wrappedCmp.endOffset, wrappedCmp.startPosition, wrappedCmp.endPosition);
337
- }
338
- }
339
- // Add target to node only after ruling out the == error case
340
- if (target)
341
- node.appendChild(wrapExpression(ctx, target), 'target');
342
- if (ctx.peekKind() === TokenKind.EQ) {
343
- ctx.addAnonymousChild(node, ctx.consume()); // =
344
- const value = parseExpression(ctx, 0);
345
- if (value)
346
- node.appendChild(wrapExpression(ctx, value), 'value');
347
- }
348
- if (ctx.peekKind() === TokenKind.NEWLINE)
349
- ctx.consume();
350
- ctx.finishNode(node, startTok);
351
- return node;
352
- }
353
- export function parseTransitionStatement(ctx) {
354
- const startTok = ctx.peek();
355
- const node = ctx.startNode('transition_statement');
356
- ctx.addAnonymousChild(node, ctx.consume()); // transition
357
- // Optional with/to statement list
358
- const withToList = tryParseWithToStatementList(ctx);
359
- if (withToList) {
360
- node.appendChild(withToList, 'with_to_statement_list');
361
- }
362
- else if (!ctx.isAtSyncPoint() &&
363
- ctx.peekKind() !== TokenKind.NEWLINE &&
364
- ctx.peekKind() !== TokenKind.EOF) {
365
- // No with/to list found but there are tokens remaining on the same line —
366
- // likely a missing 'to' keyword (e.g. "transition @topic.greeting").
367
- // Insert a synthetic with_to_statement_list containing a to_statement
368
- // with a MISSING 'to' node.
369
- const listNode = ctx.startNode('with_to_statement_list');
370
- const toNode = ctx.startNode('to_statement');
371
- toNode.appendChild(makeMissing(ctx, 'to'));
372
- const target = parseExpression(ctx, 0);
373
- if (target)
374
- toNode.appendChild(wrapExpression(ctx, target), 'target');
375
- toNode.finalize();
376
- listNode.appendChild(toNode);
377
- listNode.finalize();
378
- node.appendChild(listNode, 'with_to_statement_list');
379
- }
380
- if (ctx.peekKind() === TokenKind.NEWLINE)
381
- ctx.consume();
382
- ctx.finishNode(node, startTok);
383
- return node;
384
- }
385
- export function parseWithStatement(ctx) {
386
- const startTok = ctx.peek();
387
- // Check if `with` is followed by a valid param (ID/STRING).
388
- // If not (e.g., `with ...`), create ERROR containing `with` keyword.
389
- // The remaining tokens (e.g. `...`) stay unconsumed for the caller.
390
- if (ctx.peekAt(1).kind !== TokenKind.ID &&
391
- ctx.peekAt(1).kind !== TokenKind.STRING) {
392
- const withTok = ctx.consume();
393
- const kwOffset = ctx.currentOffset();
394
- const withChild = new CSTNode('with', ctx.source, kwOffset, kwOffset + 4, withTok.start, withTok.end, false);
395
- return makeErrorNode(ctx.source, [withChild], kwOffset, kwOffset + 4, withTok.start, withTok.end);
396
- }
397
- const node = ctx.startNode('with_statement');
398
- ctx.addAnonymousChild(node, ctx.consume()); // with
399
- // Parse param=value pairs
400
- parseWithParams(ctx, node);
401
- // Inline comment on the with line (e.g. `with city=x # comment`)
402
- if (ctx.peekKind() === TokenKind.COMMENT) {
403
- node.appendChild(ctx.consumeNamed('comment'));
404
- }
405
- if (ctx.peekKind() === TokenKind.NEWLINE)
406
- ctx.consume();
407
- ctx.finishNode(node, startTok);
408
- return node;
409
- }
410
- function parseWithParams(ctx, node) {
411
- while (!ctx.isAtSyncPoint()) {
412
- // param
413
- if (ctx.peekKind() === TokenKind.ID ||
414
- ctx.peekKind() === TokenKind.STRING) {
415
- if (ctx.peekKind() === TokenKind.STRING) {
416
- node.appendChild(parseString(ctx), 'param');
417
- }
418
- else {
419
- node.appendChild(ctx.consumeNamed('id'), 'param');
420
- }
421
- }
422
- else {
423
- // Not a valid param — wrap remaining tokens in ERROR inside with_statement
424
- const err = synchronize(ctx);
425
- if (err)
426
- node.appendChild(err);
427
- return;
428
- }
429
- // =
430
- if (ctx.peekKind() === TokenKind.EQ) {
431
- ctx.addAnonymousChild(node, ctx.consume());
432
- }
433
- else {
434
- // Missing = → insert MISSING
435
- node.appendChild(makeMissing(ctx, '='));
436
- }
437
- // value
438
- const value = parseExpression(ctx, 0);
439
- if (value)
440
- node.appendChild(wrapExpression(ctx, value), 'value');
441
- // comma
442
- if (ctx.peekKind() === TokenKind.COMMA) {
443
- ctx.addAnonymousChild(node, ctx.consume());
444
- }
445
- else {
446
- break;
447
- }
448
- }
449
- }
450
- export function parseAvailableWhenStatement(ctx) {
451
- const startTok = ctx.peek();
452
- const node = ctx.startNode('available_when_statement');
453
- ctx.addAnonymousChild(node, ctx.consume()); // available
454
- ctx.addAnonymousChild(node, ctx.consume()); // when
455
- const condition = parseExpression(ctx, 0);
456
- if (condition)
457
- node.appendChild(wrapExpression(ctx, condition), 'condition');
458
- if (ctx.peekKind() === TokenKind.NEWLINE)
459
- ctx.consume();
460
- ctx.finishNode(node, startTok);
461
- return node;
462
- }
463
- // ---------------------------------------------------------------------------
464
- // With/To statement list
465
- // ---------------------------------------------------------------------------
466
- export function tryParseWithToStatementList(ctx) {
467
- const tok = ctx.peek();
468
- if (!isTokenKind(tok, TokenKind.ID))
469
- return null;
470
- if (!['with', 'to'].includes(tok.text))
471
- return null;
472
- const startTok = tok;
473
- const node = ctx.startNode('with_to_statement_list');
474
- while (!ctx.isAtSyncPoint()) {
475
- if (ctx.peekKind() === TokenKind.ID && ctx.peek().text === 'with') {
476
- node.appendChild(parseInlineWithStatement(ctx));
477
- }
478
- else if (ctx.peekKind() === TokenKind.ID && ctx.peek().text === 'to') {
479
- node.appendChild(parseToStatement(ctx));
480
- }
481
- else {
482
- break;
483
- }
484
- if (ctx.peekKind() === TokenKind.COMMA) {
485
- ctx.addAnonymousChild(node, ctx.consume());
486
- }
487
- else {
488
- break;
489
- }
490
- }
491
- if (node.children.length === 0)
492
- return null;
493
- ctx.finishNode(node, startTok);
494
- return node;
495
- }
496
- export function parseInlineWithStatement(ctx) {
497
- const startTok = ctx.peek();
498
- const node = ctx.startNode('with_statement');
499
- ctx.addAnonymousChild(node, ctx.consume()); // with
500
- parseWithParams(ctx, node);
501
- ctx.finishNode(node, startTok);
502
- return node;
503
- }
504
- export function parseToStatement(ctx) {
505
- const startTok = ctx.peek();
506
- const node = ctx.startNode('to_statement');
507
- ctx.addAnonymousChild(node, ctx.consume()); // to
508
- const target = parseExpression(ctx, 0);
509
- if (target) {
510
- node.appendChild(wrapExpression(ctx, target), 'target');
511
- }
512
- else {
513
- // Missing target → ERROR
514
- node.appendChild(makeEmptyError(ctx));
515
- }
516
- ctx.finishNode(node, startTok);
517
- return node;
518
- }
519
- //# sourceMappingURL=parse-statements.js.map
@@ -1,15 +0,0 @@
1
- import { CSTNode } from './cst-node.js';
2
- import type { ParserContext } from './parser.js';
3
- /**
4
- * Parse a template starting with `|`.
5
- * Consumes tokens from the lexer stream, treating everything as template content
6
- * except `{!...}` breaks which are parsed as template expressions.
7
- */
8
- export declare function parseTemplate(ctx: ParserContext): CSTNode;
9
- /**
10
- * Parse a template in colinear position (after a colon on the same line).
11
- * Currently identical to parseTemplate; kept as a separate entry point
12
- * for semantic clarity and potential future divergence.
13
- */
14
- export declare function parseTemplateAsColinear(ctx: ParserContext): CSTNode;
15
- //# sourceMappingURL=parse-templates.d.ts.map