UNPKG

242 kBTypeScriptView Raw
1import { Dict, Nullable, PresentArray, Core, GetContextualFreeOpcode } from "@glimmer/interfaces";
2import { EntityParser, EventedTokenizer } from "simple-html-tokenizer";
3declare namespace HBS {
4 interface CommonNode {
5 loc: SourceLocation;
6 }
7 interface NodeMap {
8 Program: {
9 input: Program;
10 output: ASTv1.Block;
11 };
12 MustacheStatement: {
13 input: MustacheStatement;
14 output: ASTv1.MustacheStatement | void;
15 };
16 Decorator: {
17 input: Decorator;
18 output: never;
19 };
20 BlockStatement: {
21 input: BlockStatement;
22 output: ASTv1.BlockStatement | void;
23 };
24 DecoratorBlock: {
25 input: DecoratorBlock;
26 output: never;
27 };
28 PartialStatement: {
29 input: PartialStatement;
30 output: never;
31 };
32 PartialBlockStatement: {
33 input: PartialBlockStatement;
34 output: never;
35 };
36 ContentStatement: {
37 input: ContentStatement;
38 output: void;
39 };
40 CommentStatement: {
41 input: CommentStatement;
42 output: ASTv1.MustacheCommentStatement | null;
43 };
44 SubExpression: {
45 input: SubExpression;
46 output: ASTv1.SubExpression;
47 };
48 PathExpression: {
49 input: PathExpression;
50 output: ASTv1.PathExpression;
51 };
52 StringLiteral: {
53 input: StringLiteral;
54 output: ASTv1.StringLiteral;
55 };
56 BooleanLiteral: {
57 input: BooleanLiteral;
58 output: ASTv1.BooleanLiteral;
59 };
60 NumberLiteral: {
61 input: NumberLiteral;
62 output: ASTv1.NumberLiteral;
63 };
64 UndefinedLiteral: {
65 input: UndefinedLiteral;
66 output: ASTv1.UndefinedLiteral;
67 };
68 NullLiteral: {
69 input: NullLiteral;
70 output: ASTv1.NullLiteral;
71 };
72 }
73 type NodeType = keyof NodeMap;
74 type Node<T extends NodeType = NodeType> = NodeMap[T]["input"];
75 type Output<T extends NodeType> = NodeMap[T]["output"];
76 interface SourceLocation {
77 source: string;
78 start: Position;
79 end: Position;
80 }
81 interface Position {
82 line: number;
83 column: number;
84 }
85 interface Program extends CommonNode {
86 type: "Program";
87 body: Statement[];
88 blockParams?: string[];
89 chained?: boolean;
90 }
91 type Statement = MustacheStatement | BlockStatement | DecoratorBlock | PartialStatement | PartialBlockStatement | ContentStatement | CommentStatement;
92 interface CommonMustache extends CommonNode {
93 path: Expression;
94 params: Expression[];
95 hash: Hash;
96 escaped: boolean;
97 strip: StripFlags;
98 }
99 interface MustacheStatement extends CommonMustache {
100 type: "MustacheStatement";
101 }
102 interface Decorator extends CommonMustache {
103 type: "DecoratorStatement";
104 }
105 interface CommonBlock extends CommonNode {
106 chained: boolean;
107 path: PathExpression | SubExpression;
108 params: Expression[];
109 hash: Hash;
110 program: Program;
111 inverse: Program;
112 openStrip?: StripFlags;
113 inverseStrip?: StripFlags;
114 closeStrip?: StripFlags;
115 }
116 interface BlockStatement extends CommonBlock {
117 type: "BlockStatement";
118 }
119 interface DecoratorBlock extends CommonBlock {
120 type: "DecoratorBlock";
121 }
122 interface PartialStatement extends CommonNode {
123 type: "PartialStatement";
124 name: PathExpression | SubExpression;
125 params: Expression[];
126 hash: Hash;
127 indent: string;
128 strip: StripFlags;
129 }
130 interface PartialBlockStatement extends CommonNode {
131 type: "PartialBlockStatement";
132 name: PathExpression | SubExpression;
133 params: Expression[];
134 hash: Hash;
135 program: Program;
136 openStrip: StripFlags;
137 closeStrip: StripFlags;
138 }
139 interface ContentStatement extends CommonNode {
140 type: "ContentStatement";
141 value: string;
142 original: StripFlags;
143 }
144 interface CommentStatement extends CommonNode {
145 type: "CommentStatement";
146 value: string;
147 strip: StripFlags;
148 }
149 type Expression = SubExpression | PathExpression | Literal;
150 interface SubExpression extends CommonNode {
151 type: "SubExpression";
152 path: PathExpression | SubExpression;
153 params: Expression[];
154 hash: Hash;
155 }
156 interface PathExpression extends CommonNode {
157 type: "PathExpression";
158 data: boolean;
159 depth: number;
160 parts: string[];
161 original: string;
162 }
163 type Literal = StringLiteral | BooleanLiteral | NumberLiteral | UndefinedLiteral | NullLiteral;
164 interface StringLiteral extends CommonNode {
165 type: "StringLiteral";
166 value: string;
167 original: string;
168 }
169 interface BooleanLiteral extends CommonNode {
170 type: "BooleanLiteral";
171 value: boolean;
172 original: boolean;
173 }
174 interface NumberLiteral extends CommonNode {
175 type: "NumberLiteral";
176 value: number;
177 original: number;
178 }
179 interface UndefinedLiteral extends CommonNode {
180 type: "UndefinedLiteral";
181 }
182 interface NullLiteral extends CommonNode {
183 type: "NullLiteral";
184 }
185 interface Hash extends CommonNode {
186 pairs: HashPair[];
187 }
188 interface HashPair extends CommonNode {
189 key: string;
190 value: Expression;
191 }
192 interface StripFlags {
193 open: boolean;
194 close: boolean;
195 }
196}
197declare namespace src {
198 type ParserNodeBuilder<N extends {
199 loc: src.SourceSpan;
200 }> = Omit<N, "loc"> & {
201 start: src.SourceOffset;
202 };
203 interface StartTag {
204 readonly type: "StartTag";
205 name: string;
206 nameStart: Nullable<src.SourceOffset>;
207 nameEnd: Nullable<src.SourceOffset>;
208 readonly attributes: ASTv1.AttrNode[];
209 readonly modifiers: ASTv1.ElementModifierStatement[];
210 readonly comments: ASTv1.MustacheCommentStatement[];
211 readonly params: ASTv1.VarHead[];
212 selfClosing: boolean;
213 readonly loc: src.SourceSpan;
214 }
215 interface EndTag {
216 readonly type: "EndTag";
217 name: string;
218 readonly loc: src.SourceSpan;
219 }
220 interface Attribute {
221 name: string;
222 currentPart: ASTv1.TextNode | null;
223 parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[];
224 isQuoted: boolean;
225 isDynamic: boolean;
226 start: src.SourceOffset;
227 valueSpan: src.SourceSpan;
228 }
229 abstract class Parser {
230 protected elementStack: ASTv1.ParentNode[];
231 private lines;
232 readonly source: src.Source;
233 currentAttribute: Nullable<Attribute>;
234 currentNode: Nullable<Readonly<ParserNodeBuilder<ASTv1.CommentStatement> | ParserNodeBuilder<ASTv1.TextNode> | ParserNodeBuilder<StartTag> | ParserNodeBuilder<EndTag>>>;
235 tokenizer: EventedTokenizer;
236 constructor(source: src.Source, entityParser?: EntityParser, mode?: "precompile" | "codemod");
237 offset(): src.SourceOffset;
238 pos({ line, column }: src.SourcePosition): src.SourceOffset;
239 finish<T extends {
240 loc: src.SourceSpan;
241 }>(node: ParserNodeBuilder<T>): T;
242 abstract parse(node: HBS.Program, locals: string[]): ASTv1.Template;
243 abstract Program(node: HBS.Program): HBS.Output<"Program">;
244 abstract MustacheStatement(node: HBS.MustacheStatement): HBS.Output<"MustacheStatement">;
245 abstract Decorator(node: HBS.Decorator): HBS.Output<"Decorator">;
246 abstract BlockStatement(node: HBS.BlockStatement): HBS.Output<"BlockStatement">;
247 abstract DecoratorBlock(node: HBS.DecoratorBlock): HBS.Output<"DecoratorBlock">;
248 abstract PartialStatement(node: HBS.PartialStatement): HBS.Output<"PartialStatement">;
249 abstract PartialBlockStatement(node: HBS.PartialBlockStatement): HBS.Output<"PartialBlockStatement">;
250 abstract ContentStatement(node: HBS.ContentStatement): HBS.Output<"ContentStatement">;
251 abstract CommentStatement(node: HBS.CommentStatement): HBS.Output<"CommentStatement">;
252 abstract SubExpression(node: HBS.SubExpression): HBS.Output<"SubExpression">;
253 abstract PathExpression(node: HBS.PathExpression): HBS.Output<"PathExpression">;
254 abstract StringLiteral(node: HBS.StringLiteral): HBS.Output<"StringLiteral">;
255 abstract BooleanLiteral(node: HBS.BooleanLiteral): HBS.Output<"BooleanLiteral">;
256 abstract NumberLiteral(node: HBS.NumberLiteral): HBS.Output<"NumberLiteral">;
257 abstract UndefinedLiteral(node: HBS.UndefinedLiteral): HBS.Output<"UndefinedLiteral">;
258 abstract NullLiteral(node: HBS.NullLiteral): HBS.Output<"NullLiteral">;
259 abstract reset(): void;
260 abstract finishData(): void;
261 abstract tagOpen(): void;
262 abstract beginData(): void;
263 abstract appendToData(char: string): void;
264 abstract beginStartTag(): void;
265 abstract appendToTagName(char: string): void;
266 abstract beginAttribute(): void;
267 abstract appendToAttributeName(char: string): void;
268 abstract beginAttributeValue(quoted: boolean): void;
269 abstract appendToAttributeValue(char: string): void;
270 abstract finishAttributeValue(): void;
271 abstract markTagAsSelfClosing(): void;
272 abstract beginEndTag(): void;
273 abstract finishTag(): void;
274 abstract beginComment(): void;
275 abstract appendToCommentData(char: string): void;
276 abstract finishComment(): void;
277 abstract reportSyntaxError(error: string): void;
278 get currentAttr(): Attribute;
279 get currentTag(): ParserNodeBuilder<StartTag> | ParserNodeBuilder<EndTag>;
280 get currentStartTag(): ParserNodeBuilder<StartTag>;
281 get currentEndTag(): ParserNodeBuilder<EndTag>;
282 get currentComment(): ParserNodeBuilder<ASTv1.CommentStatement>;
283 get currentData(): ParserNodeBuilder<ASTv1.TextNode>;
284 acceptNode<T extends HBS.NodeType>(node: HBS.Node<T>): HBS.Output<T>;
285 currentElement(): ASTv1.ParentNode;
286 sourceForNode(node: HBS.Node, endNode?: {
287 loc: HBS.SourceLocation;
288 }): string;
289 }
290 // ensure stays in sync with typing
291 // ParentNode and ChildKey types are derived from VisitorKeysMap
292 const visitorKeys: {
293 readonly Template: readonly [
294 "body"
295 ];
296 readonly Block: readonly [
297 "body"
298 ];
299 readonly MustacheStatement: readonly [
300 "path",
301 "params",
302 "hash"
303 ];
304 readonly BlockStatement: readonly [
305 "path",
306 "params",
307 "hash",
308 "program",
309 "inverse"
310 ];
311 readonly ElementModifierStatement: readonly [
312 "path",
313 "params",
314 "hash"
315 ];
316 readonly CommentStatement: readonly [
317 ];
318 readonly MustacheCommentStatement: readonly [
319 ];
320 readonly ElementNode: readonly [
321 "attributes",
322 "modifiers",
323 "children",
324 "comments"
325 ];
326 readonly AttrNode: readonly [
327 "value"
328 ];
329 readonly TextNode: readonly [
330 ];
331 readonly ConcatStatement: readonly [
332 "parts"
333 ];
334 readonly SubExpression: readonly [
335 "path",
336 "params",
337 "hash"
338 ];
339 readonly PathExpression: readonly [
340 ];
341 readonly StringLiteral: readonly [
342 ];
343 readonly BooleanLiteral: readonly [
344 ];
345 readonly NumberLiteral: readonly [
346 ];
347 readonly NullLiteral: readonly [
348 ];
349 readonly UndefinedLiteral: readonly [
350 ];
351 readonly Hash: readonly [
352 "pairs"
353 ];
354 readonly HashPair: readonly [
355 "value"
356 ];
357 };
358 type VisitorKeysMap = typeof visitorKeys;
359 type VisitorKeys = {
360 [P in keyof VisitorKeysMap]: VisitorKeysMap[P][number];
361 };
362 type VisitorKey<N extends ASTv1.Node> = VisitorKeys[N["type"]] & keyof N;
363 class WalkerPath<N extends ASTv1.Node> {
364 node: N;
365 parent: WalkerPath<ASTv1.Node> | null;
366 parentKey: string | null;
367 constructor(node: N, parent?: WalkerPath<ASTv1.Node> | null, parentKey?: string | null);
368 get parentNode(): ASTv1.Node | null;
369 parents(): Iterable<WalkerPath<ASTv1.Node> | null>;
370 }
371 interface FullNodeTraversal<N extends ASTv1.Node> {
372 enter?(node: N, path: WalkerPath<N>): void;
373 exit?(node: N, path: WalkerPath<N>): void;
374 keys?: KeysVisitor<N>;
375 }
376 type NodeHandler<N extends ASTv1.Node> = (node: N, path: WalkerPath<N>) => void;
377 type NodeTraversal<N extends ASTv1.Node> = FullNodeTraversal<N> | NodeHandler<N>;
378 type NodeVisitor = {
379 [P in keyof ASTv1.Nodes]?: NodeTraversal<ASTv1.Nodes[P]>;
380 } & {
381 All?: NodeTraversal<ASTv1.Node>;
382 /**
383 * @deprecated use Template or Block instead
384 */
385 Program?: NodeTraversal<ASTv1.Template | ASTv1.Block>;
386 };
387 interface FullKeyTraversal<N extends ASTv1.Node, K extends string> {
388 enter?(node: N, key: K): void;
389 exit?(node: N, key: K): void;
390 }
391 type KeyHandler<N extends ASTv1.Node, K extends VisitorKey<N>> = (node: N, key: K) => void;
392 type KeyTraversal<N extends ASTv1.Node, K extends VisitorKey<N>> = FullKeyTraversal<N, K> | KeyHandler<N, K>;
393 type KeysVisitor<N extends ASTv1.Node> = {
394 [P in VisitorKey<N>]?: KeyTraversal<N, P>;
395 } & {
396 All?: KeyTraversal<N, VisitorKey<N>>;
397 /**
398 * @deprecated use Template or Block instead
399 */
400 Program?: KeyTraversal<ASTv1.Template | ASTv1.Block, "body">;
401 };
402 const voidMap: Set<string>;
403 function getVoidTags(): string[];
404 interface PrinterOptions {
405 entityEncoding: ASTv1.EntityEncodingState;
406 /**
407 * Used to override the mechanism of printing a given AST.Node.
408 *
409 * This will generally only be useful to source -> source codemods
410 * where you would like to specialize/override the way a given node is
411 * printed (e.g. you would like to preserve as much of the original
412 * formatting as possible).
413 *
414 * When the provided override returns undefined, the default built in printing
415 * will be done for the AST.Node.
416 *
417 * @param ast the ast node to be printed
418 * @param options the options specified during the print() invocation
419 */
420 override?(ast: ASTv1.Node, options: PrinterOptions): void | string;
421 }
422 /**
423 * Examples when true:
424 * - link
425 * - liNK
426 *
427 * Examples when false:
428 * - Link (component)
429 */
430 function isVoidTag(tag: string): boolean;
431 class Printer {
432 private buffer;
433 private options;
434 constructor(options: PrinterOptions);
435 /*
436 This is used by _all_ methods on this Printer class that add to `this.buffer`,
437 it allows consumers of the printer to use alternate string representations for
438 a given node.
439
440 The primary use case for this are things like source -> source codemod utilities.
441 For example, ember-template-recast attempts to always preserve the original string
442 formatting in each AST node if no modifications are made to it.
443 */
444 handledByOverride(node: ASTv1.Node, ensureLeadingWhitespace?: boolean): boolean;
445 Node(node: ASTv1.Node): void;
446 Expression(expression: ASTv1.Expression): void;
447 Literal(literal: ASTv1.Literal): void;
448 TopLevelStatement(statement: ASTv1.TopLevelStatement | ASTv1.Template | ASTv1.AttrNode): void;
449 Template(template: ASTv1.Template): void;
450 Block(block: ASTv1.Block): void;
451 TopLevelStatements(statements: ASTv1.TopLevelStatement[]): void;
452 ElementNode(el: ASTv1.ElementNode): void;
453 OpenElementNode(el: ASTv1.ElementNode): void;
454 CloseElementNode(el: ASTv1.ElementNode): void;
455 AttrNode(attr: ASTv1.AttrNode): void;
456 AttrNodeValue(value: ASTv1.AttrNode["value"]): void;
457 TextNode(text: ASTv1.TextNode, isAttr?: boolean): void;
458 MustacheStatement(mustache: ASTv1.MustacheStatement): void;
459 BlockStatement(block: ASTv1.BlockStatement): void;
460 BlockParams(blockParams: string[]): void;
461 ConcatStatement(concat: ASTv1.ConcatStatement): void;
462 MustacheCommentStatement(comment: ASTv1.MustacheCommentStatement): void;
463 ElementModifierStatement(mod: ASTv1.ElementModifierStatement): void;
464 CommentStatement(comment: ASTv1.CommentStatement): void;
465 PathExpression(path: ASTv1.PathExpression): void;
466 SubExpression(sexp: ASTv1.SubExpression): void;
467 Params(params: ASTv1.Expression[]): void;
468 Hash(hash: ASTv1.Hash): void;
469 HashPair(pair: ASTv1.HashPair): void;
470 StringLiteral(str: ASTv1.StringLiteral): void;
471 BooleanLiteral(bool: ASTv1.BooleanLiteral): void;
472 NumberLiteral(number: ASTv1.NumberLiteral): void;
473 UndefinedLiteral(node: ASTv1.UndefinedLiteral): void;
474 NullLiteral(node: ASTv1.NullLiteral): void;
475 print(node: ASTv1.Node): string;
476 }
477 function build(ast: ASTv1.Node, options?: PrinterOptions): string;
478 const print: typeof build;
479 function traverse(node: ASTv1.Node, visitor: NodeVisitor): void;
480 type NodeCallback<N extends ASTv1.Node> = (node: N, walker: Walker) => void;
481 class Walker {
482 order?: unknown;
483 stack: unknown[];
484 constructor(order?: unknown);
485 visit<N extends ASTv1.Node>(node: Nullable<N>, visitor: NodeCallback<N>): void;
486 children<N extends ASTv1.Node>(node: N & ASTv1.Node, callback: NodeCallback<N & ASTv1.Node>): void;
487 }
488 // const SOURCE = new Source('', '(tests)');
489 // Statements
490 type BuilderHead = string | ASTv1.CallableExpression;
491 type TagDescriptor = string | ASTv1.PathExpression | {
492 path: ASTv1.PathExpression;
493 selfClosing?: boolean;
494 } | {
495 name: string;
496 selfClosing?: boolean;
497 };
498 function buildMustache(path: BuilderHead | ASTv1.Literal, params?: ASTv1.Expression[], hash?: ASTv1.Hash, trusting?: boolean, loc?: SourceLocation, strip?: ASTv1.StripFlags): ASTv1.MustacheStatement;
499 type PossiblyDeprecatedBlock = ASTv1.Block | ASTv1.Template;
500 function buildBlock(path: BuilderHead, params: Nullable<ASTv1.Expression[]>, hash: Nullable<ASTv1.Hash>, _defaultBlock: PossiblyDeprecatedBlock, _elseBlock?: Nullable<PossiblyDeprecatedBlock>, loc?: SourceLocation, openStrip?: ASTv1.StripFlags, inverseStrip?: ASTv1.StripFlags, closeStrip?: ASTv1.StripFlags): ASTv1.BlockStatement;
501 function buildElementModifier(path: BuilderHead, params?: ASTv1.Expression[], hash?: ASTv1.Hash, loc?: Nullable<SourceLocation>): ASTv1.ElementModifierStatement;
502 function buildComment(value: string, loc?: SourceLocation): ASTv1.CommentStatement;
503 function buildMustacheComment(value: string, loc?: SourceLocation): ASTv1.MustacheCommentStatement;
504 function buildConcat(parts: (ASTv1.TextNode | ASTv1.MustacheStatement)[], loc?: SourceLocation): ASTv1.ConcatStatement;
505 // Nodes
506 type ElementParts = [
507 "attrs",
508 ...AttrSexp[]
509 ] | [
510 "modifiers",
511 ...ModifierSexp[]
512 ] | [
513 "body",
514 ...ASTv1.Statement[]
515 ] | [
516 "comments",
517 ...ElementComment[]
518 ] | [
519 "as",
520 ...string[]
521 ] | [
522 "loc",
523 SourceLocation
524 ];
525 type PathSexp = string | [
526 "path",
527 string,
528 LocSexp?
529 ];
530 type ModifierSexp = string | [
531 PathSexp,
532 LocSexp?
533 ] | [
534 PathSexp,
535 ASTv1.Expression[],
536 LocSexp?
537 ] | [
538 PathSexp,
539 ASTv1.Expression[],
540 Dict<ASTv1.Expression>,
541 LocSexp?
542 ];
543 type AttrSexp = [
544 string,
545 ASTv1.AttrNode["value"] | string,
546 LocSexp?
547 ];
548 type LocSexp = [
549 "loc",
550 SourceLocation
551 ];
552 type ElementComment = ASTv1.MustacheCommentStatement | SourceLocation | string;
553 type SexpValue = string | ASTv1.Expression[] | Dict<ASTv1.Expression> | LocSexp | PathSexp | undefined;
554 interface BuildElementOptions {
555 attrs?: ASTv1.AttrNode[];
556 modifiers?: ASTv1.ElementModifierStatement[];
557 children?: ASTv1.Statement[];
558 comments?: ASTv1.MustacheCommentStatement[];
559 blockParams?: ASTv1.VarHead[] | string[];
560 openTag?: SourceLocation;
561 closeTag?: Nullable<SourceLocation>;
562 loc?: SourceLocation;
563 }
564 function buildElement(tag: TagDescriptor, options?: BuildElementOptions): ASTv1.ElementNode;
565 function buildAttr(name: string, value: ASTv1.AttrValue, loc?: SourceLocation): ASTv1.AttrNode;
566 function buildText(chars?: string, loc?: SourceLocation): ASTv1.TextNode;
567 // Expressions
568 function buildSexpr(path: BuilderHead, params?: ASTv1.Expression[], hash?: ASTv1.Hash, loc?: SourceLocation): ASTv1.SubExpression;
569 function buildThis(loc?: SourceLocation): ASTv1.ThisHead;
570 function buildAtName(name: string, loc?: SourceLocation): ASTv1.AtHead;
571 function buildVar(name: string, loc?: SourceLocation): ASTv1.VarHead;
572 function buildHeadFromString(original: string, loc?: SourceLocation): ASTv1.PathHead;
573 function buildCleanPath(head: ASTv1.PathHead, tail?: string[], loc?: SourceLocation): ASTv1.PathExpression;
574 function buildPath(path: ASTv1.PathExpression | string | {
575 head: string;
576 tail: string[];
577 }, loc?: SourceLocation): ASTv1.PathExpression;
578 function buildPath(path: BuilderHead, loc?: SourceLocation): ASTv1.CallableExpression;
579 function buildPath(path: BuilderHead | ASTv1.Literal, loc?: SourceLocation): ASTv1.Expression;
580 function buildPath(path: ASTv1.Expression, loc?: SourceLocation): ASTv1.Expression;
581 function buildLiteral<T extends ASTv1.Literal>(type: T["type"], value: T["value"], loc?: SourceLocation): T;
582 // Miscellaneous
583 function buildHash(pairs?: ASTv1.HashPair[], loc?: SourceLocation): ASTv1.Hash;
584 function buildPair(key: string, value: ASTv1.Expression, loc?: SourceLocation): ASTv1.HashPair;
585 function buildProgram(body?: ASTv1.Statement[], blockParams?: string[], loc?: SourceLocation): ASTv1.Template | ASTv1.Block;
586 function buildBlockItself(body?: ASTv1.Statement[], params?: Array<ASTv1.VarHead | string>, chained?: boolean, loc?: SourceLocation): ASTv1.Block;
587 function buildTemplate(body?: ASTv1.Statement[], blockParams?: string[], loc?: SourceLocation): ASTv1.Template;
588 function buildPosition(line: number, column: number): SourcePosition;
589 function buildLoc(loc: Nullable<SourceLocation>): SourceSpan;
590 function buildLoc(startLine: number, startColumn: number, endLine?: number, endColumn?: number, source?: string): SourceSpan;
591 const _default: {
592 mustache: typeof buildMustache;
593 block: typeof buildBlock;
594 comment: typeof buildComment;
595 mustacheComment: typeof buildMustacheComment;
596 element: typeof buildElement;
597 elementModifier: typeof buildElementModifier;
598 attr: typeof buildAttr;
599 text: typeof buildText;
600 sexpr: typeof buildSexpr;
601 concat: typeof buildConcat;
602 hash: typeof buildHash;
603 pair: typeof buildPair;
604 literal: typeof buildLiteral;
605 program: typeof buildProgram;
606 blockItself: typeof buildBlockItself;
607 template: typeof buildTemplate;
608 loc: typeof buildLoc;
609 pos: typeof buildPosition;
610 path: typeof buildPath;
611 fullPath: typeof buildCleanPath;
612 head: typeof buildHeadFromString;
613 at: typeof buildAtName;
614 var: typeof buildVar;
615 this: typeof buildThis;
616 string: (value: string) => ASTv1.StringLiteral;
617 boolean: (value: boolean) => ASTv1.BooleanLiteral;
618 number: (value: number) => ASTv1.NumberLiteral;
619 undefined(): ASTv1.UndefinedLiteral;
620 null(): ASTv1.NullLiteral;
621 };
622 const publicBuilder: typeof _default;
623 interface PendingError {
624 mustache(span: SourceSpan): never;
625 eof(offset: SourceOffset): never;
626 }
627 abstract class HandlebarsNodeVisitors extends Parser {
628 // Because we interleave the HTML and HBS parsing, sometimes the HTML
629 // tokenizer can run out of tokens when we switch into {{...}} or reached
630 // EOF. There are positions where neither of these are expected, and it would
631 // like to generate an error, but there is no span to attach the error to.
632 // This allows the HTML tokenization to stash an error message and the next
633 // mustache visitor will attach the message to the appropriate span and throw
634 // the error.
635 protected pendingError: Nullable<PendingError>;
636 abstract appendToCommentData(s: string): void;
637 abstract beginAttributeValue(quoted: boolean): void;
638 abstract finishAttributeValue(): void;
639 parse(program: HBS.Program, blockParams: string[]): ASTv1.Template;
640 Program(program: HBS.Program, blockParams?: ASTv1.VarHead[]): ASTv1.Block;
641 private parseProgram;
642 BlockStatement(block: HBS.BlockStatement): ASTv1.BlockStatement | void;
643 MustacheStatement(rawMustache: HBS.MustacheStatement): ASTv1.MustacheStatement | void;
644 appendDynamicAttributeValuePart(part: ASTv1.MustacheStatement): void;
645 finalizeTextPart(): void;
646 startTextPart(): void;
647 ContentStatement(content: HBS.ContentStatement): void;
648 CommentStatement(rawComment: HBS.CommentStatement): Nullable<ASTv1.MustacheCommentStatement>;
649 PartialStatement(partial: HBS.PartialStatement): never;
650 PartialBlockStatement(partialBlock: HBS.PartialBlockStatement): never;
651 Decorator(decorator: HBS.Decorator): never;
652 DecoratorBlock(decoratorBlock: HBS.DecoratorBlock): never;
653 SubExpression(sexpr: HBS.SubExpression): ASTv1.SubExpression;
654 PathExpression(path: HBS.PathExpression): ASTv1.PathExpression;
655 Hash(hash: HBS.Hash): ASTv1.Hash;
656 StringLiteral(string: HBS.StringLiteral): ASTv1.StringLiteral;
657 BooleanLiteral(boolean: HBS.BooleanLiteral): ASTv1.BooleanLiteral;
658 NumberLiteral(number: HBS.NumberLiteral): ASTv1.NumberLiteral;
659 UndefinedLiteral(undef: HBS.UndefinedLiteral): ASTv1.UndefinedLiteral;
660 NullLiteral(nul: HBS.NullLiteral): ASTv1.NullLiteral;
661 }
662 class TokenizerEventHandlers extends HandlebarsNodeVisitors {
663 private tagOpenLine;
664 private tagOpenColumn;
665 reset(): void;
666 // Comment
667 beginComment(): void;
668 appendToCommentData(char: string): void;
669 finishComment(): void;
670 // Data
671 beginData(): void;
672 appendToData(char: string): void;
673 finishData(): void;
674 // Tags - basic
675 tagOpen(): void;
676 beginStartTag(): void;
677 beginEndTag(): void;
678 finishTag(): void;
679 finishStartTag(): void;
680 finishEndTag(isVoid: boolean): void;
681 markTagAsSelfClosing(): void;
682 // Tags - name
683 appendToTagName(char: string): void;
684 // Tags - attributes
685 beginAttribute(): void;
686 appendToAttributeName(char: string): void;
687 beginAttributeValue(isQuoted: boolean): void;
688 appendToAttributeValue(char: string): void;
689 finishAttributeValue(): void;
690 private parsePossibleBlockParams;
691 reportSyntaxError(message: string): void;
692 assembleConcatenatedValue(parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[]): ASTv1.ConcatStatement;
693 validateEndTag(tag: StartTag | EndTag, element: ASTv1.ElementNode, selfClosing: boolean): void;
694 assembleAttributeValue(parts: ASTv1.AttrPart[], isQuoted: boolean, isDynamic: boolean, span: src.SourceSpan): ASTv1.AttrValue;
695 }
696 /**
697 ASTPlugins can make changes to the Glimmer template AST before
698 compilation begins.
699 */
700 interface ASTPluginBuilder<TEnv extends ASTPluginEnvironment = ASTPluginEnvironment> {
701 (env: TEnv): ASTPlugin;
702 }
703 interface ASTPlugin {
704 name: string;
705 visitor: NodeVisitor;
706 }
707 interface ASTPluginEnvironment {
708 meta?: object;
709 syntax: Syntax;
710 }
711 interface HandlebarsParseOptions {
712 srcName?: string;
713 ignoreStandalone?: boolean;
714 }
715 interface TemplateIdFn {
716 (src: string): Nullable<string>;
717 }
718 interface PrecompileOptions extends PreprocessOptions {
719 id?: TemplateIdFn;
720 /**
721 * Additional non-native keywords.
722 *
723 * Local variables (block params or lexical scope) always takes precedence,
724 * but otherwise, suitable free variable candidates (e.g. those are not part
725 * of a path) are matched against this list and turned into keywords.
726 *
727 * In strict mode compilation, keywords suppresses the undefined reference
728 * error and will be resolved by the runtime environment.
729 *
730 * In loose mode, keywords are currently ignored and since all free variables
731 * are already resolved by the runtime environment.
732 */
733 keywords?: readonly string[];
734 customizeComponentName?: ((input: string) => string) | undefined;
735 }
736 interface PrecompileOptionsWithLexicalScope extends PrecompileOptions {
737 lexicalScope: (variable: string) => boolean;
738 }
739 interface PreprocessOptions {
740 strictMode?: boolean;
741 locals?: string[];
742 meta?: {
743 moduleName?: string;
744 };
745 plugins?: {
746 ast?: ASTPluginBuilder[];
747 };
748 parseOptions?: HandlebarsParseOptions;
749 customizeComponentName?: ((input: string) => string) | undefined;
750 /**
751 Useful for specifying a group of options together.
752
753 When `'codemod'` we disable all whitespace control in handlebars
754 (to preserve as much as possible) and we also avoid any
755 escaping/unescaping of HTML entity codes.
756 */
757 mode?: "codemod" | "precompile";
758 }
759 interface Syntax {
760 parse: typeof preprocess;
761 builders: typeof publicBuilder;
762 print: typeof print;
763 traverse: typeof traverse;
764 Walker: typeof Walker;
765 }
766 function preprocess(input: string | src.Source | HBS.Program, options?: PreprocessOptions): ASTv1.Template;
767 class Source {
768 readonly source: string;
769 readonly module: string;
770 static from(source: string, options?: PrecompileOptions): Source;
771 constructor(source: string, module?: string);
772 /**
773 * Validate that the character offset represents a position in the source string.
774 */
775 check(offset: number): boolean;
776 slice(start: number, end: number): string;
777 offsetFor(line: number, column: number): SourceOffset;
778 spanFor({ start, end }: Readonly<SourceLocation>): SourceSpan;
779 hbsPosFor(offset: number): Nullable<SourcePosition>;
780 charPosFor(position: SourcePosition): number | null;
781 }
782 enum OffsetKind {
783 /**
784 * We have already computed the character position of this offset or span.
785 */
786 CharPosition = "CharPosition",
787 /**
788 * This offset or span was instantiated with a Handlebars SourcePosition or SourceLocation. Its
789 * character position will be computed on demand.
790 */
791 HbsPosition = "HbsPosition",
792 /**
793 * for (rare) situations where a node is created but there was no source location (e.g. the name
794 * "default" in default blocks when the word "default" never appeared in source). This is used
795 * by the internals when there is a legitimate reason for the internals to synthesize a node
796 * with no location.
797 */
798 InternalsSynthetic = "InternalsSynthetic",
799 /**
800 * For situations where a node represents zero parts of the source (for example, empty arguments).
801 * In general, we attempt to assign these nodes *some* position (empty arguments can be
802 * positioned immediately after the callee), but it's not always possible
803 */
804 NonExistent = "NonExistent",
805 /**
806 * For situations where a source location was expected, but it didn't correspond to the node in
807 * the source. This happens if a plugin creates broken locations.
808 */
809 Broken = "Broken"
810 }
811 /**
812 * This file implements the DSL used by span and offset in places where they need to exhaustively
813 * consider all combinations of states (Handlebars offsets, character offsets and invisible/broken
814 * offsets).
815 *
816 * It's probably overkill, but it makes the code that uses it clear. It could be refactored or
817 * removed.
818 */
819 const MatchAny = "MATCH_ANY";
820 type MatchAny = "MATCH_ANY";
821 type Matches = "Char,Hbs" | "Hbs,Char" | "Hbs,Hbs" | "Char,Char" | "Invisible,Any" | "Any,Invisible";
822 const IsInvisible = "IS_INVISIBLE";
823 type IsInvisible = "IS_INVISIBLE";
824 type Pattern = OffsetKind | IsInvisible | MatchAny;
825 class When<Out> {
826 _map: Map<Pattern, Out>;
827 get(pattern: Pattern, or: () => Out): Out;
828 add(pattern: Pattern, out: Out): void;
829 match(kind: OffsetKind): Out[];
830 }
831 type ExhaustiveCheck<Out, In extends Matches, Removed extends Matches> = Exclude<In, Removed> extends never ? ExhaustiveMatcher<Out> : Matcher<Out, Exclude<In, Removed>>;
832 type MatchFn<Out> = (left: PositionData, right: PositionData) => Out;
833 interface ExhaustiveMatcher<Out> {
834 check(): MatchFn<Out>;
835 }
836 function match<Out>(callback: (m: Matcher<Out>) => ExhaustiveMatcher<Out>): MatchFn<Out>;
837 class Matcher<Out, M extends Matches = Matches> {
838 _whens: When<When<(left: PositionData, right: PositionData) => Out>>;
839 /**
840 * You didn't exhaustively match all possibilities.
841 */
842 protected check(): MatchFn<Out>;
843 private matchFor;
844 // This big block is the bulk of the heavy lifting in this file. It facilitates exhaustiveness
845 // checking so that matchers can ensure they've actually covered all the cases (and TypeScript
846 // will treat it as an exhaustive match).
847 when(left: OffsetKind.CharPosition, right: OffsetKind.HbsPosition, callback: (left: CharPosition, right: HbsPosition) => Out): ExhaustiveCheck<Out, M, "Char,Hbs">;
848 when(left: OffsetKind.HbsPosition, right: OffsetKind.CharPosition, callback: (left: HbsPosition, right: CharPosition) => Out): ExhaustiveCheck<Out, M, "Hbs,Char">;
849 when(left: OffsetKind.HbsPosition, right: OffsetKind.HbsPosition, callback: (left: HbsPosition, right: HbsPosition) => Out): ExhaustiveCheck<Out, M, "Hbs,Hbs">;
850 when(left: OffsetKind.CharPosition, right: OffsetKind.CharPosition, callback: (left: CharPosition, right: CharPosition) => Out): ExhaustiveCheck<Out, M, "Char,Char">;
851 when(left: IsInvisible, right: MatchAny, callback: (left: InvisiblePosition, right: PositionData) => Out): Matcher<Out, Exclude<M, "Invisible,Any">>;
852 when(left: MatchAny, right: IsInvisible, callback: (left: PositionData, right: InvisiblePosition) => Out): ExhaustiveCheck<Out, M, "Any,Invisible">;
853 when(left: MatchAny, right: MatchAny, callback: (left: PositionData, right: PositionData) => Out): ExhaustiveMatcher<Out>;
854 }
855 type SerializedSourceSlice<Chars extends string = string> = [
856 chars: Chars,
857 span: src.SerializedSourceSpan
858 ];
859 class SourceSlice<Chars extends string = string> {
860 static synthetic<S extends string>(chars: S): SourceSlice<S>;
861 static load(source: src.Source, slice: SerializedSourceSlice): SourceSlice;
862 readonly chars: Chars;
863 readonly loc: src.SourceSpan;
864 constructor(options: {
865 loc: src.SourceSpan;
866 chars: Chars;
867 });
868 getString(): string;
869 serialize(): SerializedSourceSlice<Chars>;
870 }
871 /**
872 * All spans have these details in common.
873 */
874 interface SpanData {
875 readonly kind: OffsetKind;
876 /**
877 * Convert this span into a string. If the span is broken, return `''`.
878 */
879 asString(): string;
880 /**
881 * Gets the module the span was located in.
882 */
883 getModule(): string;
884 /**
885 * Get the starting position for this span. Try to avoid creating new position objects, as they
886 * cache computations.
887 */
888 getStart(): AnyPosition;
889 /**
890 * Get the ending position for this span. Try to avoid creating new position objects, as they
891 * cache computations.
892 */
893 getEnd(): AnyPosition;
894 /**
895 * Compute the `SourceLocation` for this span, returned as an instance of `HbsSpan`.
896 */
897 toHbsSpan(): HbsSpan | null;
898 /**
899 * For compatibility, whenever the `start` or `end` of a {@see SourceOffset} changes, spans are
900 * notified of the change so they can update themselves. This shouldn't happen outside of AST
901 * plugins.
902 */
903 locDidUpdate(changes: {
904 start?: SourcePosition;
905 end?: SourcePosition;
906 }): void;
907 /**
908 * Serialize into a {@see SerializedSourceSpan}, which is compact and designed for readability in
909 * context like AST Explorer. If you need a {@see SourceLocation}, use {@see toJSON}.
910 */
911 serialize(): SerializedSourceSpan;
912 }
913 /**
914 * A `SourceSpan` object represents a span of characters inside of a template source.
915 *
916 * There are three kinds of `SourceSpan` objects:
917 *
918 * - `ConcreteSourceSpan`, which contains byte offsets
919 * - `LazySourceSpan`, which contains `SourceLocation`s from the Handlebars AST, which can be
920 * converted to byte offsets on demand.
921 * - `InvisibleSourceSpan`, which represent source strings that aren't present in the source,
922 * because:
923 * - they were created synthetically
924 * - their location is nonsensical (the span is broken)
925 * - they represent nothing in the source (this currently happens only when a bug in the
926 * upstream Handlebars parser fails to assign a location to empty blocks)
927 *
928 * At a high level, all `SourceSpan` objects provide:
929 *
930 * - byte offsets
931 * - source in column and line format
932 *
933 * And you can do these operations on `SourceSpan`s:
934 *
935 * - collapse it to a `SourceSpan` representing its starting or ending position
936 * - slice out some characters, optionally skipping some characters at the beginning or end
937 * - create a new `SourceSpan` with a different starting or ending offset
938 *
939 * All SourceSpan objects implement `SourceLocation`, for compatibility. All SourceSpan
940 * objects have a `toJSON` that emits `SourceLocation`, also for compatibility.
941 *
942 * For compatibility, subclasses of `AbstractSourceSpan` must implement `locDidUpdate`, which
943 * happens when an AST plugin attempts to modify the `start` or `end` of a span directly.
944 *
945 * The goal is to avoid creating any problems for use-cases like AST Explorer.
946 */
947 class SourceSpan implements SourceLocation {
948 private data;
949 static get NON_EXISTENT(): SourceSpan;
950 static load(source: Source, serialized: SerializedSourceSpan): SourceSpan;
951 static forHbsLoc(source: Source, loc: SourceLocation): SourceSpan;
952 static forCharPositions(source: Source, startPos: number, endPos: number): SourceSpan;
953 static synthetic(chars: string): SourceSpan;
954 static broken(pos?: SourceLocation): SourceSpan;
955 readonly isInvisible: boolean;
956 constructor(data: SpanData & AnySpan);
957 getStart(): SourceOffset;
958 getEnd(): SourceOffset;
959 get loc(): SourceLocation;
960 get module(): string;
961 /**
962 * Get the starting `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
963 */
964 get startPosition(): SourcePosition;
965 /**
966 * Get the ending `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
967 */
968 get endPosition(): SourcePosition;
969 /**
970 * Support converting ASTv1 nodes into a serialized format using JSON.stringify.
971 */
972 toJSON(): SourceLocation;
973 /**
974 * Create a new span with the current span's end and a new beginning.
975 */
976 withStart(other: SourceOffset): SourceSpan;
977 /**
978 * Create a new span with the current span's beginning and a new ending.
979 */
980 withEnd(other: SourceOffset): SourceSpan;
981 asString(): string;
982 /**
983 * Convert this `SourceSpan` into a `SourceSlice`. In debug mode, this method optionally checks
984 * that the byte offsets represented by this `SourceSpan` actually correspond to the expected
985 * string.
986 */
987 toSlice(expected?: string): SourceSlice;
988 /**
989 * For compatibility with SourceLocation in AST plugins
990 *
991 * @deprecated use startPosition instead
992 */
993 get start(): SourcePosition;
994 /**
995 * For compatibility with SourceLocation in AST plugins
996 *
997 * @deprecated use withStart instead
998 */
999 set start(position: SourcePosition);
1000 /**
1001 * For compatibility with SourceLocation in AST plugins
1002 *
1003 * @deprecated use endPosition instead
1004 */
1005 get end(): SourcePosition;
1006 /**
1007 * For compatibility with SourceLocation in AST plugins
1008 *
1009 * @deprecated use withEnd instead
1010 */
1011 set end(position: SourcePosition);
1012 /**
1013 * For compatibility with SourceLocation in AST plugins
1014 *
1015 * @deprecated use module instead
1016 */
1017 get source(): string;
1018 collapse(where: "start" | "end"): SourceSpan;
1019 extend(other: SourceSpan): SourceSpan;
1020 serialize(): SerializedSourceSpan;
1021 slice({ skipStart, skipEnd }: {
1022 skipStart?: number;
1023 skipEnd?: number;
1024 }): SourceSpan;
1025 sliceStartChars({ skipStart, chars }: {
1026 skipStart?: number;
1027 chars: number;
1028 }): SourceSpan;
1029 sliceEndChars({ skipEnd, chars }: {
1030 skipEnd?: number;
1031 chars: number;
1032 }): SourceSpan;
1033 }
1034 type AnySpan = HbsSpan | CharPositionSpan | InvisibleSpan;
1035 class CharPositionSpan implements SpanData {
1036 readonly source: Source;
1037 readonly charPositions: {
1038 start: CharPosition;
1039 end: CharPosition;
1040 };
1041 readonly kind = OffsetKind.CharPosition;
1042 _locPosSpan: HbsSpan | BROKEN | null;
1043 constructor(source: Source, charPositions: {
1044 start: CharPosition;
1045 end: CharPosition;
1046 });
1047 wrap(): SourceSpan;
1048 asString(): string;
1049 getModule(): string;
1050 getStart(): AnyPosition;
1051 getEnd(): AnyPosition;
1052 locDidUpdate(): void;
1053 toHbsSpan(): HbsSpan | null;
1054 serialize(): SerializedSourceSpan;
1055 toCharPosSpan(): CharPositionSpan;
1056 }
1057 class HbsSpan implements SpanData {
1058 readonly source: Source;
1059 readonly hbsPositions: {
1060 start: HbsPosition;
1061 end: HbsPosition;
1062 };
1063 readonly kind = OffsetKind.HbsPosition;
1064 _charPosSpan: CharPositionSpan | BROKEN | null;
1065 // the source location from Handlebars + AST Plugins -- could be wrong
1066 _providedHbsLoc: SourceLocation | null;
1067 constructor(source: Source, hbsPositions: {
1068 start: HbsPosition;
1069 end: HbsPosition;
1070 }, providedHbsLoc?: SourceLocation | null);
1071 serialize(): SerializedConcreteSourceSpan;
1072 wrap(): SourceSpan;
1073 private updateProvided;
1074 locDidUpdate({ start, end }: {
1075 start?: SourcePosition;
1076 end?: SourcePosition;
1077 }): void;
1078 asString(): string;
1079 getModule(): string;
1080 getStart(): AnyPosition;
1081 getEnd(): AnyPosition;
1082 toHbsLoc(): SourceLocation;
1083 toHbsSpan(): HbsSpan;
1084 toCharPosSpan(): CharPositionSpan | null;
1085 }
1086 class InvisibleSpan implements SpanData {
1087 readonly kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent;
1088 // whatever was provided, possibly broken
1089 readonly loc: SourceLocation;
1090 // if the span represents a synthetic string
1091 readonly string: string | null;
1092 constructor(kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent, loc: SourceLocation, string?: string | null);
1093 serialize(): SerializedConcreteSourceSpan;
1094 wrap(): SourceSpan;
1095 asString(): string;
1096 locDidUpdate({ start, end }: {
1097 start?: SourcePosition;
1098 end?: SourcePosition;
1099 }): void;
1100 getModule(): string;
1101 getStart(): AnyPosition;
1102 getEnd(): AnyPosition;
1103 toCharPosSpan(): InvisibleSpan;
1104 toHbsSpan(): null;
1105 toHbsLoc(): SourceLocation;
1106 }
1107 const span: MatchFn<SourceSpan>;
1108 type SerializedConcreteSourceSpan = /** collapsed */ number | /** normal */ [
1109 start: number,
1110 size: number
1111 ] | /** synthetic */ string;
1112 type SerializedSourceSpan = SerializedConcreteSourceSpan | OffsetKind.NonExistent | OffsetKind.Broken;
1113 interface SourceLocation {
1114 start: SourcePosition;
1115 end: SourcePosition;
1116 }
1117 interface SourcePosition {
1118 /** >= 1 */
1119 line: number;
1120 /** >= 0 */
1121 column: number;
1122 }
1123 const UNKNOWN_POSITION: Readonly<{
1124 readonly line: 1;
1125 readonly column: 0;
1126 }>;
1127 const SYNTHETIC_LOCATION: Readonly<{
1128 readonly source: "(synthetic)";
1129 readonly start: Readonly<{
1130 readonly line: 1;
1131 readonly column: 0;
1132 }>;
1133 readonly end: Readonly<{
1134 readonly line: 1;
1135 readonly column: 0;
1136 }>;
1137 }>;
1138 /** @deprecated */
1139 const SYNTHETIC: Readonly<{
1140 readonly source: "(synthetic)";
1141 readonly start: Readonly<{
1142 readonly line: 1;
1143 readonly column: 0;
1144 }>;
1145 readonly end: Readonly<{
1146 readonly line: 1;
1147 readonly column: 0;
1148 }>;
1149 }>;
1150 const TEMPORARY_LOCATION: Readonly<{
1151 readonly source: "(temporary)";
1152 readonly start: Readonly<{
1153 readonly line: 1;
1154 readonly column: 0;
1155 }>;
1156 readonly end: Readonly<{
1157 readonly line: 1;
1158 readonly column: 0;
1159 }>;
1160 }>;
1161 const NON_EXISTENT_LOCATION: Readonly<{
1162 readonly source: "(nonexistent)";
1163 readonly start: Readonly<{
1164 readonly line: 1;
1165 readonly column: 0;
1166 }>;
1167 readonly end: Readonly<{
1168 readonly line: 1;
1169 readonly column: 0;
1170 }>;
1171 }>;
1172 const BROKEN_LOCATION: Readonly<{
1173 readonly source: "(broken)";
1174 readonly start: Readonly<{
1175 readonly line: 1;
1176 readonly column: 0;
1177 }>;
1178 readonly end: Readonly<{
1179 readonly line: 1;
1180 readonly column: 0;
1181 }>;
1182 }>;
1183 type LocatedWithSpan = {
1184 offsets: SourceSpan;
1185 };
1186 type LocatedWithOptionalSpan = {
1187 offsets: SourceSpan | null;
1188 };
1189 type LocatedWithPositions = {
1190 loc: SourceLocation;
1191 };
1192 type LocatedWithOptionalPositions = {
1193 loc?: SourceLocation;
1194 };
1195 function isLocatedWithPositionsArray(location: LocatedWithOptionalPositions[]): location is PresentArray<LocatedWithPositions>;
1196 function isLocatedWithPositions(location: LocatedWithOptionalPositions): location is LocatedWithPositions;
1197 type HasSourceLocation = SourceLocation | LocatedWithPositions | PresentArray<LocatedWithPositions>;
1198 type MaybeHasSourceLocation = null | LocatedWithOptionalPositions | LocatedWithOptionalPositions[];
1199 /**
1200 * All positions have these details in common. Most notably, all three kinds of positions can
1201 * must be able to attempt to convert themselves into {@see CharPosition}.
1202 */
1203 interface PositionData {
1204 readonly kind: OffsetKind;
1205 toCharPos(): CharPosition | null;
1206 toJSON(): SourcePosition;
1207 }
1208 /**
1209 * Used to indicate that an attempt to convert a `SourcePosition` to a character offset failed. It
1210 * is separate from `null` so that `null` can be used to indicate that the computation wasn't yet
1211 * attempted (and therefore to cache the failure)
1212 */
1213 const BROKEN = "BROKEN";
1214 type BROKEN = "BROKEN";
1215 type AnyPosition = HbsPosition | CharPosition | InvisiblePosition;
1216 /**
1217 * A `SourceOffset` represents a single position in the source.
1218 *
1219 * There are three kinds of backing data for `SourceOffset` objects:
1220 *
1221 * - `CharPosition`, which contains a character offset into the raw source string
1222 * - `HbsPosition`, which contains a `SourcePosition` from the Handlebars AST, which can be
1223 * converted to a `CharPosition` on demand.
1224 * - `InvisiblePosition`, which represents a position not in source (@see {InvisiblePosition})
1225 */
1226 class SourceOffset {
1227 readonly data: PositionData & AnyPosition;
1228 /**
1229 * Create a `SourceOffset` from a Handlebars `SourcePosition`. It's stored as-is, and converted
1230 * into a character offset on demand, which avoids unnecessarily computing the offset of every
1231 * `SourceLocation`, but also means that broken `SourcePosition`s are not always detected.
1232 */
1233 static forHbsPos(source: Source, pos: SourcePosition): SourceOffset;
1234 /**
1235 * Create a `SourceOffset` that corresponds to a broken `SourcePosition`. This means that the
1236 * calling code determined (or knows) that the `SourceLocation` doesn't correspond correctly to
1237 * any part of the source.
1238 */
1239 static broken(pos?: SourcePosition): SourceOffset;
1240 constructor(data: PositionData & AnyPosition);
1241 /**
1242 * Get the character offset for this `SourceOffset`, if possible.
1243 */
1244 get offset(): number | null;
1245 /**
1246 * Compare this offset with another one.
1247 *
1248 * If both offsets are `HbsPosition`s, they're equivalent as long as their lines and columns are
1249 * the same. This avoids computing offsets unnecessarily.
1250 *
1251 * Otherwise, two `SourceOffset`s are equivalent if their successfully computed character offsets
1252 * are the same.
1253 */
1254 eql(right: SourceOffset): boolean;
1255 /**
1256 * Create a span that starts from this source offset and ends with another source offset. Avoid
1257 * computing character offsets if both `SourceOffset`s are still lazy.
1258 */
1259 until(other: SourceOffset): SourceSpan;
1260 /**
1261 * Create a `SourceOffset` by moving the character position represented by this source offset
1262 * forward or backward (if `by` is negative), if possible.
1263 *
1264 * If this `SourceOffset` can't compute a valid character offset, `move` returns a broken offset.
1265 *
1266 * If the resulting character offset is less than 0 or greater than the size of the source, `move`
1267 * returns a broken offset.
1268 */
1269 move(by: number): SourceOffset;
1270 /**
1271 * Create a new `SourceSpan` that represents a collapsed range at this source offset. Avoid
1272 * computing the character offset if it has not already been computed.
1273 */
1274 collapsed(): SourceSpan;
1275 /**
1276 * Convert this `SourceOffset` into a Handlebars {@see SourcePosition} for compatibility with
1277 * existing plugins.
1278 */
1279 toJSON(): SourcePosition;
1280 }
1281 class CharPosition implements PositionData {
1282 readonly source: Source;
1283 readonly charPos: number;
1284 readonly kind = OffsetKind.CharPosition;
1285 /** Computed from char offset */
1286 _locPos: HbsPosition | BROKEN | null;
1287 constructor(source: Source, charPos: number);
1288 /**
1289 * This is already a `CharPosition`.
1290 *
1291 * {@see HbsPosition} for the alternative.
1292 */
1293 toCharPos(): CharPosition;
1294 /**
1295 * Produce a Handlebars {@see SourcePosition} for this `CharPosition`. If this `CharPosition` was
1296 * computed using {@see SourceOffset#move}, this will compute the `SourcePosition` for the offset.
1297 */
1298 toJSON(): SourcePosition;
1299 wrap(): SourceOffset;
1300 /**
1301 * A `CharPosition` always has an offset it can produce without any additional computation.
1302 */
1303 get offset(): number;
1304 /**
1305 * Convert the current character offset to an `HbsPosition`, if it was not already computed. Once
1306 * a `CharPosition` has computed its `HbsPosition`, it will not need to do compute it again, and
1307 * the same `CharPosition` is retained when used as one of the ends of a `SourceSpan`, so
1308 * computing the `HbsPosition` should be a one-time operation.
1309 */
1310 toHbsPos(): HbsPosition | null;
1311 }
1312 class HbsPosition implements PositionData {
1313 readonly source: Source;
1314 readonly hbsPos: SourcePosition;
1315 readonly kind = OffsetKind.HbsPosition;
1316 _charPos: CharPosition | BROKEN | null;
1317 constructor(source: Source, hbsPos: SourcePosition, charPos?: number | null);
1318 /**
1319 * Lazily compute the character offset from the {@see SourcePosition}. Once an `HbsPosition` has
1320 * computed its `CharPosition`, it will not need to do compute it again, and the same
1321 * `HbsPosition` is retained when used as one of the ends of a `SourceSpan`, so computing the
1322 * `CharPosition` should be a one-time operation.
1323 */
1324 toCharPos(): CharPosition | null;
1325 /**
1326 * Return the {@see SourcePosition} that this `HbsPosition` was instantiated with. This operation
1327 * does not need to compute anything.
1328 */
1329 toJSON(): SourcePosition;
1330 wrap(): SourceOffset;
1331 /**
1332 * This is already an `HbsPosition`.
1333 *
1334 * {@see CharPosition} for the alternative.
1335 */
1336 toHbsPos(): HbsPosition;
1337 }
1338 class InvisiblePosition implements PositionData {
1339 readonly kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent;
1340 // whatever was provided, possibly broken
1341 readonly pos: SourcePosition;
1342 constructor(kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent, pos: SourcePosition);
1343 /**
1344 * A broken position cannot be turned into a {@see CharacterPosition}.
1345 */
1346 toCharPos(): null;
1347 /**
1348 * The serialization of an `InvisiblePosition is whatever Handlebars {@see SourcePosition} was
1349 * originally identified as broken, non-existent or synthetic.
1350 *
1351 * If an `InvisiblePosition` never had an source offset at all, this method returns
1352 * {@see UNKNOWN_POSITION} for compatibility.
1353 */
1354 toJSON(): SourcePosition;
1355 wrap(): SourceOffset;
1356 get offset(): null;
1357 }
1358 type HasSpan = SourceSpan | LocatedWithSpan | PresentArray<LocatedWithSpan>;
1359 type MaybeHasSpan = SourceSpan | LocatedWithOptionalSpan | LocatedWithOptionalSpan[] | null;
1360 type ToSourceOffset = number | SourceOffset;
1361 class SpanList {
1362 static range(span: PresentArray<HasSourceSpan>): SourceSpan;
1363 static range(span: HasSourceSpan[], fallback: SourceSpan): SourceSpan;
1364 _span: SourceSpan[];
1365 constructor(span?: SourceSpan[]);
1366 add(offset: SourceSpan): void;
1367 getRangeOffset(fallback: SourceSpan): SourceSpan;
1368 }
1369 type HasSourceSpan = {
1370 loc: SourceSpan;
1371 } | SourceSpan | [
1372 HasSourceSpan,
1373 ...HasSourceSpan[]
1374 ];
1375 function loc(span: HasSourceSpan): SourceSpan;
1376 type MaybeHasSourceSpan = {
1377 loc: SourceSpan;
1378 } | SourceSpan | MaybeHasSourceSpan[];
1379 function hasSpan(span: MaybeHasSourceSpan): span is HasSourceSpan;
1380 function maybeLoc(location: MaybeHasSourceSpan, fallback: SourceSpan): SourceSpan;
1381}
1382declare namespace ASTv1 {
1383 type ParserNodeBuilder<N extends {
1384 loc: src.SourceSpan;
1385 }> = Omit<N, "loc"> & {
1386 start: src.SourceOffset;
1387 };
1388 interface StartTag {
1389 readonly type: "StartTag";
1390 name: string;
1391 nameStart: Nullable<src.SourceOffset>;
1392 nameEnd: Nullable<src.SourceOffset>;
1393 readonly attributes: ASTv1.AttrNode[];
1394 readonly modifiers: ASTv1.ElementModifierStatement[];
1395 readonly comments: ASTv1.MustacheCommentStatement[];
1396 readonly params: ASTv1.VarHead[];
1397 selfClosing: boolean;
1398 readonly loc: src.SourceSpan;
1399 }
1400 interface EndTag {
1401 readonly type: "EndTag";
1402 name: string;
1403 readonly loc: src.SourceSpan;
1404 }
1405 interface Attribute {
1406 name: string;
1407 currentPart: ASTv1.TextNode | null;
1408 parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[];
1409 isQuoted: boolean;
1410 isDynamic: boolean;
1411 start: src.SourceOffset;
1412 valueSpan: src.SourceSpan;
1413 }
1414 abstract class Parser {
1415 protected elementStack: ASTv1.ParentNode[];
1416 private lines;
1417 readonly source: src.Source;
1418 currentAttribute: Nullable<Attribute>;
1419 currentNode: Nullable<Readonly<ParserNodeBuilder<ASTv1.CommentStatement> | ParserNodeBuilder<ASTv1.TextNode> | ParserNodeBuilder<StartTag> | ParserNodeBuilder<EndTag>>>;
1420 tokenizer: EventedTokenizer;
1421 constructor(source: src.Source, entityParser?: EntityParser, mode?: "precompile" | "codemod");
1422 offset(): src.SourceOffset;
1423 pos({ line, column }: src.SourcePosition): src.SourceOffset;
1424 finish<T extends {
1425 loc: src.SourceSpan;
1426 }>(node: ParserNodeBuilder<T>): T;
1427 abstract parse(node: HBS.Program, locals: string[]): ASTv1.Template;
1428 abstract Program(node: HBS.Program): HBS.Output<"Program">;
1429 abstract MustacheStatement(node: HBS.MustacheStatement): HBS.Output<"MustacheStatement">;
1430 abstract Decorator(node: HBS.Decorator): HBS.Output<"Decorator">;
1431 abstract BlockStatement(node: HBS.BlockStatement): HBS.Output<"BlockStatement">;
1432 abstract DecoratorBlock(node: HBS.DecoratorBlock): HBS.Output<"DecoratorBlock">;
1433 abstract PartialStatement(node: HBS.PartialStatement): HBS.Output<"PartialStatement">;
1434 abstract PartialBlockStatement(node: HBS.PartialBlockStatement): HBS.Output<"PartialBlockStatement">;
1435 abstract ContentStatement(node: HBS.ContentStatement): HBS.Output<"ContentStatement">;
1436 abstract CommentStatement(node: HBS.CommentStatement): HBS.Output<"CommentStatement">;
1437 abstract SubExpression(node: HBS.SubExpression): HBS.Output<"SubExpression">;
1438 abstract PathExpression(node: HBS.PathExpression): HBS.Output<"PathExpression">;
1439 abstract StringLiteral(node: HBS.StringLiteral): HBS.Output<"StringLiteral">;
1440 abstract BooleanLiteral(node: HBS.BooleanLiteral): HBS.Output<"BooleanLiteral">;
1441 abstract NumberLiteral(node: HBS.NumberLiteral): HBS.Output<"NumberLiteral">;
1442 abstract UndefinedLiteral(node: HBS.UndefinedLiteral): HBS.Output<"UndefinedLiteral">;
1443 abstract NullLiteral(node: HBS.NullLiteral): HBS.Output<"NullLiteral">;
1444 abstract reset(): void;
1445 abstract finishData(): void;
1446 abstract tagOpen(): void;
1447 abstract beginData(): void;
1448 abstract appendToData(char: string): void;
1449 abstract beginStartTag(): void;
1450 abstract appendToTagName(char: string): void;
1451 abstract beginAttribute(): void;
1452 abstract appendToAttributeName(char: string): void;
1453 abstract beginAttributeValue(quoted: boolean): void;
1454 abstract appendToAttributeValue(char: string): void;
1455 abstract finishAttributeValue(): void;
1456 abstract markTagAsSelfClosing(): void;
1457 abstract beginEndTag(): void;
1458 abstract finishTag(): void;
1459 abstract beginComment(): void;
1460 abstract appendToCommentData(char: string): void;
1461 abstract finishComment(): void;
1462 abstract reportSyntaxError(error: string): void;
1463 get currentAttr(): Attribute;
1464 get currentTag(): ParserNodeBuilder<StartTag> | ParserNodeBuilder<EndTag>;
1465 get currentStartTag(): ParserNodeBuilder<StartTag>;
1466 get currentEndTag(): ParserNodeBuilder<EndTag>;
1467 get currentComment(): ParserNodeBuilder<ASTv1.CommentStatement>;
1468 get currentData(): ParserNodeBuilder<ASTv1.TextNode>;
1469 acceptNode<T extends HBS.NodeType>(node: HBS.Node<T>): HBS.Output<T>;
1470 currentElement(): ASTv1.ParentNode;
1471 sourceForNode(node: HBS.Node, endNode?: {
1472 loc: HBS.SourceLocation;
1473 }): string;
1474 }
1475 // ensure stays in sync with typing
1476 // ParentNode and ChildKey types are derived from VisitorKeysMap
1477 const visitorKeys: {
1478 readonly Template: readonly [
1479 "body"
1480 ];
1481 readonly Block: readonly [
1482 "body"
1483 ];
1484 readonly MustacheStatement: readonly [
1485 "path",
1486 "params",
1487 "hash"
1488 ];
1489 readonly BlockStatement: readonly [
1490 "path",
1491 "params",
1492 "hash",
1493 "program",
1494 "inverse"
1495 ];
1496 readonly ElementModifierStatement: readonly [
1497 "path",
1498 "params",
1499 "hash"
1500 ];
1501 readonly CommentStatement: readonly [
1502 ];
1503 readonly MustacheCommentStatement: readonly [
1504 ];
1505 readonly ElementNode: readonly [
1506 "attributes",
1507 "modifiers",
1508 "children",
1509 "comments"
1510 ];
1511 readonly AttrNode: readonly [
1512 "value"
1513 ];
1514 readonly TextNode: readonly [
1515 ];
1516 readonly ConcatStatement: readonly [
1517 "parts"
1518 ];
1519 readonly SubExpression: readonly [
1520 "path",
1521 "params",
1522 "hash"
1523 ];
1524 readonly PathExpression: readonly [
1525 ];
1526 readonly StringLiteral: readonly [
1527 ];
1528 readonly BooleanLiteral: readonly [
1529 ];
1530 readonly NumberLiteral: readonly [
1531 ];
1532 readonly NullLiteral: readonly [
1533 ];
1534 readonly UndefinedLiteral: readonly [
1535 ];
1536 readonly Hash: readonly [
1537 "pairs"
1538 ];
1539 readonly HashPair: readonly [
1540 "value"
1541 ];
1542 };
1543 type VisitorKeysMap = typeof visitorKeys;
1544 type VisitorKeys = {
1545 [P in keyof VisitorKeysMap]: VisitorKeysMap[P][number];
1546 };
1547 type VisitorKey<N extends ASTv1.Node> = VisitorKeys[N["type"]] & keyof N;
1548 class WalkerPath<N extends ASTv1.Node> {
1549 node: N;
1550 parent: WalkerPath<ASTv1.Node> | null;
1551 parentKey: string | null;
1552 constructor(node: N, parent?: WalkerPath<ASTv1.Node> | null, parentKey?: string | null);
1553 get parentNode(): ASTv1.Node | null;
1554 parents(): Iterable<WalkerPath<ASTv1.Node> | null>;
1555 }
1556 interface FullNodeTraversal<N extends ASTv1.Node> {
1557 enter?(node: N, path: WalkerPath<N>): void;
1558 exit?(node: N, path: WalkerPath<N>): void;
1559 keys?: KeysVisitor<N>;
1560 }
1561 type NodeHandler<N extends ASTv1.Node> = (node: N, path: WalkerPath<N>) => void;
1562 type NodeTraversal<N extends ASTv1.Node> = FullNodeTraversal<N> | NodeHandler<N>;
1563 type NodeVisitor = {
1564 [P in keyof ASTv1.Nodes]?: NodeTraversal<ASTv1.Nodes[P]>;
1565 } & {
1566 All?: NodeTraversal<ASTv1.Node>;
1567 /**
1568 * @deprecated use Template or Block instead
1569 */
1570 Program?: NodeTraversal<ASTv1.Template | ASTv1.Block>;
1571 };
1572 interface FullKeyTraversal<N extends ASTv1.Node, K extends string> {
1573 enter?(node: N, key: K): void;
1574 exit?(node: N, key: K): void;
1575 }
1576 type KeyHandler<N extends ASTv1.Node, K extends VisitorKey<N>> = (node: N, key: K) => void;
1577 type KeyTraversal<N extends ASTv1.Node, K extends VisitorKey<N>> = FullKeyTraversal<N, K> | KeyHandler<N, K>;
1578 type KeysVisitor<N extends ASTv1.Node> = {
1579 [P in VisitorKey<N>]?: KeyTraversal<N, P>;
1580 } & {
1581 All?: KeyTraversal<N, VisitorKey<N>>;
1582 /**
1583 * @deprecated use Template or Block instead
1584 */
1585 Program?: KeyTraversal<ASTv1.Template | ASTv1.Block, "body">;
1586 };
1587 const voidMap: Set<string>;
1588 function getVoidTags(): string[];
1589 interface PrinterOptions {
1590 entityEncoding: ASTv1.EntityEncodingState;
1591 /**
1592 * Used to override the mechanism of printing a given AST.Node.
1593 *
1594 * This will generally only be useful to source -> source codemods
1595 * where you would like to specialize/override the way a given node is
1596 * printed (e.g. you would like to preserve as much of the original
1597 * formatting as possible).
1598 *
1599 * When the provided override returns undefined, the default built in printing
1600 * will be done for the AST.Node.
1601 *
1602 * @param ast the ast node to be printed
1603 * @param options the options specified during the print() invocation
1604 */
1605 override?(ast: ASTv1.Node, options: PrinterOptions): void | string;
1606 }
1607 /**
1608 * Examples when true:
1609 * - link
1610 * - liNK
1611 *
1612 * Examples when false:
1613 * - Link (component)
1614 */
1615 function isVoidTag(tag: string): boolean;
1616 class Printer {
1617 private buffer;
1618 private options;
1619 constructor(options: PrinterOptions);
1620 /*
1621 This is used by _all_ methods on this Printer class that add to `this.buffer`,
1622 it allows consumers of the printer to use alternate string representations for
1623 a given node.
1624
1625 The primary use case for this are things like source -> source codemod utilities.
1626 For example, ember-template-recast attempts to always preserve the original string
1627 formatting in each AST node if no modifications are made to it.
1628 */
1629 handledByOverride(node: ASTv1.Node, ensureLeadingWhitespace?: boolean): boolean;
1630 Node(node: ASTv1.Node): void;
1631 Expression(expression: ASTv1.Expression): void;
1632 Literal(literal: ASTv1.Literal): void;
1633 TopLevelStatement(statement: ASTv1.TopLevelStatement | ASTv1.Template | ASTv1.AttrNode): void;
1634 Template(template: ASTv1.Template): void;
1635 Block(block: ASTv1.Block): void;
1636 TopLevelStatements(statements: ASTv1.TopLevelStatement[]): void;
1637 ElementNode(el: ASTv1.ElementNode): void;
1638 OpenElementNode(el: ASTv1.ElementNode): void;
1639 CloseElementNode(el: ASTv1.ElementNode): void;
1640 AttrNode(attr: ASTv1.AttrNode): void;
1641 AttrNodeValue(value: ASTv1.AttrNode["value"]): void;
1642 TextNode(text: ASTv1.TextNode, isAttr?: boolean): void;
1643 MustacheStatement(mustache: ASTv1.MustacheStatement): void;
1644 BlockStatement(block: ASTv1.BlockStatement): void;
1645 BlockParams(blockParams: string[]): void;
1646 ConcatStatement(concat: ASTv1.ConcatStatement): void;
1647 MustacheCommentStatement(comment: ASTv1.MustacheCommentStatement): void;
1648 ElementModifierStatement(mod: ASTv1.ElementModifierStatement): void;
1649 CommentStatement(comment: ASTv1.CommentStatement): void;
1650 PathExpression(path: ASTv1.PathExpression): void;
1651 SubExpression(sexp: ASTv1.SubExpression): void;
1652 Params(params: ASTv1.Expression[]): void;
1653 Hash(hash: ASTv1.Hash): void;
1654 HashPair(pair: ASTv1.HashPair): void;
1655 StringLiteral(str: ASTv1.StringLiteral): void;
1656 BooleanLiteral(bool: ASTv1.BooleanLiteral): void;
1657 NumberLiteral(number: ASTv1.NumberLiteral): void;
1658 UndefinedLiteral(node: ASTv1.UndefinedLiteral): void;
1659 NullLiteral(node: ASTv1.NullLiteral): void;
1660 print(node: ASTv1.Node): string;
1661 }
1662 function build(ast: ASTv1.Node, options?: PrinterOptions): string;
1663 const print: typeof build;
1664 function traverse(node: ASTv1.Node, visitor: NodeVisitor): void;
1665 type NodeCallback<N extends ASTv1.Node> = (node: N, walker: Walker) => void;
1666 class Walker {
1667 order?: unknown;
1668 stack: unknown[];
1669 constructor(order?: unknown);
1670 visit<N extends ASTv1.Node>(node: Nullable<N>, visitor: NodeCallback<N>): void;
1671 children<N extends ASTv1.Node>(node: N & ASTv1.Node, callback: NodeCallback<N & ASTv1.Node>): void;
1672 }
1673 // const SOURCE = new Source('', '(tests)');
1674 // Statements
1675 type BuilderHead = string | ASTv1.CallableExpression;
1676 type TagDescriptor = string | ASTv1.PathExpression | {
1677 path: ASTv1.PathExpression;
1678 selfClosing?: boolean;
1679 } | {
1680 name: string;
1681 selfClosing?: boolean;
1682 };
1683 function buildMustache(path: BuilderHead | ASTv1.Literal, params?: ASTv1.Expression[], hash?: ASTv1.Hash, trusting?: boolean, loc?: SourceLocation, strip?: ASTv1.StripFlags): ASTv1.MustacheStatement;
1684 type PossiblyDeprecatedBlock = ASTv1.Block | ASTv1.Template;
1685 function buildBlock(path: BuilderHead, params: Nullable<ASTv1.Expression[]>, hash: Nullable<ASTv1.Hash>, _defaultBlock: PossiblyDeprecatedBlock, _elseBlock?: Nullable<PossiblyDeprecatedBlock>, loc?: SourceLocation, openStrip?: ASTv1.StripFlags, inverseStrip?: ASTv1.StripFlags, closeStrip?: ASTv1.StripFlags): ASTv1.BlockStatement;
1686 function buildElementModifier(path: BuilderHead, params?: ASTv1.Expression[], hash?: ASTv1.Hash, loc?: Nullable<SourceLocation>): ASTv1.ElementModifierStatement;
1687 function buildComment(value: string, loc?: SourceLocation): ASTv1.CommentStatement;
1688 function buildMustacheComment(value: string, loc?: SourceLocation): ASTv1.MustacheCommentStatement;
1689 function buildConcat(parts: (ASTv1.TextNode | ASTv1.MustacheStatement)[], loc?: SourceLocation): ASTv1.ConcatStatement;
1690 // Nodes
1691 type ElementParts = [
1692 "attrs",
1693 ...AttrSexp[]
1694 ] | [
1695 "modifiers",
1696 ...ModifierSexp[]
1697 ] | [
1698 "body",
1699 ...ASTv1.Statement[]
1700 ] | [
1701 "comments",
1702 ...ElementComment[]
1703 ] | [
1704 "as",
1705 ...string[]
1706 ] | [
1707 "loc",
1708 SourceLocation
1709 ];
1710 type PathSexp = string | [
1711 "path",
1712 string,
1713 LocSexp?
1714 ];
1715 type ModifierSexp = string | [
1716 PathSexp,
1717 LocSexp?
1718 ] | [
1719 PathSexp,
1720 ASTv1.Expression[],
1721 LocSexp?
1722 ] | [
1723 PathSexp,
1724 ASTv1.Expression[],
1725 Dict<ASTv1.Expression>,
1726 LocSexp?
1727 ];
1728 type AttrSexp = [
1729 string,
1730 ASTv1.AttrNode["value"] | string,
1731 LocSexp?
1732 ];
1733 type LocSexp = [
1734 "loc",
1735 SourceLocation
1736 ];
1737 type ElementComment = ASTv1.MustacheCommentStatement | SourceLocation | string;
1738 type SexpValue = string | ASTv1.Expression[] | Dict<ASTv1.Expression> | LocSexp | PathSexp | undefined;
1739 interface BuildElementOptions {
1740 attrs?: ASTv1.AttrNode[];
1741 modifiers?: ASTv1.ElementModifierStatement[];
1742 children?: ASTv1.Statement[];
1743 comments?: ASTv1.MustacheCommentStatement[];
1744 blockParams?: ASTv1.VarHead[] | string[];
1745 openTag?: SourceLocation;
1746 closeTag?: Nullable<SourceLocation>;
1747 loc?: SourceLocation;
1748 }
1749 function buildElement(tag: TagDescriptor, options?: BuildElementOptions): ASTv1.ElementNode;
1750 function buildAttr(name: string, value: ASTv1.AttrValue, loc?: SourceLocation): ASTv1.AttrNode;
1751 function buildText(chars?: string, loc?: SourceLocation): ASTv1.TextNode;
1752 // Expressions
1753 function buildSexpr(path: BuilderHead, params?: ASTv1.Expression[], hash?: ASTv1.Hash, loc?: SourceLocation): ASTv1.SubExpression;
1754 function buildThis(loc?: SourceLocation): ASTv1.ThisHead;
1755 function buildAtName(name: string, loc?: SourceLocation): ASTv1.AtHead;
1756 function buildVar(name: string, loc?: SourceLocation): ASTv1.VarHead;
1757 function buildHeadFromString(original: string, loc?: SourceLocation): ASTv1.PathHead;
1758 function buildCleanPath(head: ASTv1.PathHead, tail?: string[], loc?: SourceLocation): ASTv1.PathExpression;
1759 function buildPath(path: ASTv1.PathExpression | string | {
1760 head: string;
1761 tail: string[];
1762 }, loc?: SourceLocation): ASTv1.PathExpression;
1763 function buildPath(path: BuilderHead, loc?: SourceLocation): ASTv1.CallableExpression;
1764 function buildPath(path: BuilderHead | ASTv1.Literal, loc?: SourceLocation): ASTv1.Expression;
1765 function buildPath(path: ASTv1.Expression, loc?: SourceLocation): ASTv1.Expression;
1766 function buildLiteral<T extends ASTv1.Literal>(type: T["type"], value: T["value"], loc?: SourceLocation): T;
1767 // Miscellaneous
1768 function buildHash(pairs?: ASTv1.HashPair[], loc?: SourceLocation): ASTv1.Hash;
1769 function buildPair(key: string, value: ASTv1.Expression, loc?: SourceLocation): ASTv1.HashPair;
1770 function buildProgram(body?: ASTv1.Statement[], blockParams?: string[], loc?: SourceLocation): ASTv1.Template | ASTv1.Block;
1771 function buildBlockItself(body?: ASTv1.Statement[], params?: Array<ASTv1.VarHead | string>, chained?: boolean, loc?: SourceLocation): ASTv1.Block;
1772 function buildTemplate(body?: ASTv1.Statement[], blockParams?: string[], loc?: SourceLocation): ASTv1.Template;
1773 function buildPosition(line: number, column: number): SourcePosition;
1774 function buildLoc(loc: Nullable<SourceLocation>): SourceSpan;
1775 function buildLoc(startLine: number, startColumn: number, endLine?: number, endColumn?: number, source?: string): SourceSpan;
1776 const _default: {
1777 mustache: typeof buildMustache;
1778 block: typeof buildBlock;
1779 comment: typeof buildComment;
1780 mustacheComment: typeof buildMustacheComment;
1781 element: typeof buildElement;
1782 elementModifier: typeof buildElementModifier;
1783 attr: typeof buildAttr;
1784 text: typeof buildText;
1785 sexpr: typeof buildSexpr;
1786 concat: typeof buildConcat;
1787 hash: typeof buildHash;
1788 pair: typeof buildPair;
1789 literal: typeof buildLiteral;
1790 program: typeof buildProgram;
1791 blockItself: typeof buildBlockItself;
1792 template: typeof buildTemplate;
1793 loc: typeof buildLoc;
1794 pos: typeof buildPosition;
1795 path: typeof buildPath;
1796 fullPath: typeof buildCleanPath;
1797 head: typeof buildHeadFromString;
1798 at: typeof buildAtName;
1799 var: typeof buildVar;
1800 this: typeof buildThis;
1801 string: (value: string) => ASTv1.StringLiteral;
1802 boolean: (value: boolean) => ASTv1.BooleanLiteral;
1803 number: (value: number) => ASTv1.NumberLiteral;
1804 undefined(): ASTv1.UndefinedLiteral;
1805 null(): ASTv1.NullLiteral;
1806 };
1807 const publicBuilder: typeof _default;
1808 interface PendingError {
1809 mustache(span: SourceSpan): never;
1810 eof(offset: SourceOffset): never;
1811 }
1812 abstract class HandlebarsNodeVisitors extends Parser {
1813 // Because we interleave the HTML and HBS parsing, sometimes the HTML
1814 // tokenizer can run out of tokens when we switch into {{...}} or reached
1815 // EOF. There are positions where neither of these are expected, and it would
1816 // like to generate an error, but there is no span to attach the error to.
1817 // This allows the HTML tokenization to stash an error message and the next
1818 // mustache visitor will attach the message to the appropriate span and throw
1819 // the error.
1820 protected pendingError: Nullable<PendingError>;
1821 abstract appendToCommentData(s: string): void;
1822 abstract beginAttributeValue(quoted: boolean): void;
1823 abstract finishAttributeValue(): void;
1824 parse(program: HBS.Program, blockParams: string[]): ASTv1.Template;
1825 Program(program: HBS.Program, blockParams?: ASTv1.VarHead[]): ASTv1.Block;
1826 private parseProgram;
1827 BlockStatement(block: HBS.BlockStatement): ASTv1.BlockStatement | void;
1828 MustacheStatement(rawMustache: HBS.MustacheStatement): ASTv1.MustacheStatement | void;
1829 appendDynamicAttributeValuePart(part: ASTv1.MustacheStatement): void;
1830 finalizeTextPart(): void;
1831 startTextPart(): void;
1832 ContentStatement(content: HBS.ContentStatement): void;
1833 CommentStatement(rawComment: HBS.CommentStatement): Nullable<ASTv1.MustacheCommentStatement>;
1834 PartialStatement(partial: HBS.PartialStatement): never;
1835 PartialBlockStatement(partialBlock: HBS.PartialBlockStatement): never;
1836 Decorator(decorator: HBS.Decorator): never;
1837 DecoratorBlock(decoratorBlock: HBS.DecoratorBlock): never;
1838 SubExpression(sexpr: HBS.SubExpression): ASTv1.SubExpression;
1839 PathExpression(path: HBS.PathExpression): ASTv1.PathExpression;
1840 Hash(hash: HBS.Hash): ASTv1.Hash;
1841 StringLiteral(string: HBS.StringLiteral): ASTv1.StringLiteral;
1842 BooleanLiteral(boolean: HBS.BooleanLiteral): ASTv1.BooleanLiteral;
1843 NumberLiteral(number: HBS.NumberLiteral): ASTv1.NumberLiteral;
1844 UndefinedLiteral(undef: HBS.UndefinedLiteral): ASTv1.UndefinedLiteral;
1845 NullLiteral(nul: HBS.NullLiteral): ASTv1.NullLiteral;
1846 }
1847 class TokenizerEventHandlers extends HandlebarsNodeVisitors {
1848 private tagOpenLine;
1849 private tagOpenColumn;
1850 reset(): void;
1851 // Comment
1852 beginComment(): void;
1853 appendToCommentData(char: string): void;
1854 finishComment(): void;
1855 // Data
1856 beginData(): void;
1857 appendToData(char: string): void;
1858 finishData(): void;
1859 // Tags - basic
1860 tagOpen(): void;
1861 beginStartTag(): void;
1862 beginEndTag(): void;
1863 finishTag(): void;
1864 finishStartTag(): void;
1865 finishEndTag(isVoid: boolean): void;
1866 markTagAsSelfClosing(): void;
1867 // Tags - name
1868 appendToTagName(char: string): void;
1869 // Tags - attributes
1870 beginAttribute(): void;
1871 appendToAttributeName(char: string): void;
1872 beginAttributeValue(isQuoted: boolean): void;
1873 appendToAttributeValue(char: string): void;
1874 finishAttributeValue(): void;
1875 private parsePossibleBlockParams;
1876 reportSyntaxError(message: string): void;
1877 assembleConcatenatedValue(parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[]): ASTv1.ConcatStatement;
1878 validateEndTag(tag: StartTag | EndTag, element: ASTv1.ElementNode, selfClosing: boolean): void;
1879 assembleAttributeValue(parts: ASTv1.AttrPart[], isQuoted: boolean, isDynamic: boolean, span: src.SourceSpan): ASTv1.AttrValue;
1880 }
1881 /**
1882 ASTPlugins can make changes to the Glimmer template AST before
1883 compilation begins.
1884 */
1885 interface ASTPluginBuilder<TEnv extends ASTPluginEnvironment = ASTPluginEnvironment> {
1886 (env: TEnv): ASTPlugin;
1887 }
1888 interface ASTPlugin {
1889 name: string;
1890 visitor: NodeVisitor;
1891 }
1892 interface ASTPluginEnvironment {
1893 meta?: object;
1894 syntax: Syntax;
1895 }
1896 interface HandlebarsParseOptions {
1897 srcName?: string;
1898 ignoreStandalone?: boolean;
1899 }
1900 interface TemplateIdFn {
1901 (src: string): Nullable<string>;
1902 }
1903 interface PrecompileOptions extends PreprocessOptions {
1904 id?: TemplateIdFn;
1905 /**
1906 * Additional non-native keywords.
1907 *
1908 * Local variables (block params or lexical scope) always takes precedence,
1909 * but otherwise, suitable free variable candidates (e.g. those are not part
1910 * of a path) are matched against this list and turned into keywords.
1911 *
1912 * In strict mode compilation, keywords suppresses the undefined reference
1913 * error and will be resolved by the runtime environment.
1914 *
1915 * In loose mode, keywords are currently ignored and since all free variables
1916 * are already resolved by the runtime environment.
1917 */
1918 keywords?: readonly string[];
1919 customizeComponentName?: ((input: string) => string) | undefined;
1920 }
1921 interface PrecompileOptionsWithLexicalScope extends PrecompileOptions {
1922 lexicalScope: (variable: string) => boolean;
1923 }
1924 interface PreprocessOptions {
1925 strictMode?: boolean;
1926 locals?: string[];
1927 meta?: {
1928 moduleName?: string;
1929 };
1930 plugins?: {
1931 ast?: ASTPluginBuilder[];
1932 };
1933 parseOptions?: HandlebarsParseOptions;
1934 customizeComponentName?: ((input: string) => string) | undefined;
1935 /**
1936 Useful for specifying a group of options together.
1937
1938 When `'codemod'` we disable all whitespace control in handlebars
1939 (to preserve as much as possible) and we also avoid any
1940 escaping/unescaping of HTML entity codes.
1941 */
1942 mode?: "codemod" | "precompile";
1943 }
1944 interface Syntax {
1945 parse: typeof preprocess;
1946 builders: typeof publicBuilder;
1947 print: typeof print;
1948 traverse: typeof traverse;
1949 Walker: typeof Walker;
1950 }
1951 function preprocess(input: string | src.Source | HBS.Program, options?: PreprocessOptions): ASTv1.Template;
1952 class Source {
1953 readonly source: string;
1954 readonly module: string;
1955 static from(source: string, options?: PrecompileOptions): Source;
1956 constructor(source: string, module?: string);
1957 /**
1958 * Validate that the character offset represents a position in the source string.
1959 */
1960 check(offset: number): boolean;
1961 slice(start: number, end: number): string;
1962 offsetFor(line: number, column: number): SourceOffset;
1963 spanFor({ start, end }: Readonly<SourceLocation>): SourceSpan;
1964 hbsPosFor(offset: number): Nullable<SourcePosition>;
1965 charPosFor(position: SourcePosition): number | null;
1966 }
1967 enum OffsetKind {
1968 /**
1969 * We have already computed the character position of this offset or span.
1970 */
1971 CharPosition = "CharPosition",
1972 /**
1973 * This offset or span was instantiated with a Handlebars SourcePosition or SourceLocation. Its
1974 * character position will be computed on demand.
1975 */
1976 HbsPosition = "HbsPosition",
1977 /**
1978 * for (rare) situations where a node is created but there was no source location (e.g. the name
1979 * "default" in default blocks when the word "default" never appeared in source). This is used
1980 * by the internals when there is a legitimate reason for the internals to synthesize a node
1981 * with no location.
1982 */
1983 InternalsSynthetic = "InternalsSynthetic",
1984 /**
1985 * For situations where a node represents zero parts of the source (for example, empty arguments).
1986 * In general, we attempt to assign these nodes *some* position (empty arguments can be
1987 * positioned immediately after the callee), but it's not always possible
1988 */
1989 NonExistent = "NonExistent",
1990 /**
1991 * For situations where a source location was expected, but it didn't correspond to the node in
1992 * the source. This happens if a plugin creates broken locations.
1993 */
1994 Broken = "Broken"
1995 }
1996 /**
1997 * This file implements the DSL used by span and offset in places where they need to exhaustively
1998 * consider all combinations of states (Handlebars offsets, character offsets and invisible/broken
1999 * offsets).
2000 *
2001 * It's probably overkill, but it makes the code that uses it clear. It could be refactored or
2002 * removed.
2003 */
2004 const MatchAny = "MATCH_ANY";
2005 type MatchAny = "MATCH_ANY";
2006 type Matches = "Char,Hbs" | "Hbs,Char" | "Hbs,Hbs" | "Char,Char" | "Invisible,Any" | "Any,Invisible";
2007 const IsInvisible = "IS_INVISIBLE";
2008 type IsInvisible = "IS_INVISIBLE";
2009 type Pattern = OffsetKind | IsInvisible | MatchAny;
2010 class When<Out> {
2011 _map: Map<Pattern, Out>;
2012 get(pattern: Pattern, or: () => Out): Out;
2013 add(pattern: Pattern, out: Out): void;
2014 match(kind: OffsetKind): Out[];
2015 }
2016 type ExhaustiveCheck<Out, In extends Matches, Removed extends Matches> = Exclude<In, Removed> extends never ? ExhaustiveMatcher<Out> : Matcher<Out, Exclude<In, Removed>>;
2017 type MatchFn<Out> = (left: PositionData, right: PositionData) => Out;
2018 interface ExhaustiveMatcher<Out> {
2019 check(): MatchFn<Out>;
2020 }
2021 function match<Out>(callback: (m: Matcher<Out>) => ExhaustiveMatcher<Out>): MatchFn<Out>;
2022 class Matcher<Out, M extends Matches = Matches> {
2023 _whens: When<When<(left: PositionData, right: PositionData) => Out>>;
2024 /**
2025 * You didn't exhaustively match all possibilities.
2026 */
2027 protected check(): MatchFn<Out>;
2028 private matchFor;
2029 // This big block is the bulk of the heavy lifting in this file. It facilitates exhaustiveness
2030 // checking so that matchers can ensure they've actually covered all the cases (and TypeScript
2031 // will treat it as an exhaustive match).
2032 when(left: OffsetKind.CharPosition, right: OffsetKind.HbsPosition, callback: (left: CharPosition, right: HbsPosition) => Out): ExhaustiveCheck<Out, M, "Char,Hbs">;
2033 when(left: OffsetKind.HbsPosition, right: OffsetKind.CharPosition, callback: (left: HbsPosition, right: CharPosition) => Out): ExhaustiveCheck<Out, M, "Hbs,Char">;
2034 when(left: OffsetKind.HbsPosition, right: OffsetKind.HbsPosition, callback: (left: HbsPosition, right: HbsPosition) => Out): ExhaustiveCheck<Out, M, "Hbs,Hbs">;
2035 when(left: OffsetKind.CharPosition, right: OffsetKind.CharPosition, callback: (left: CharPosition, right: CharPosition) => Out): ExhaustiveCheck<Out, M, "Char,Char">;
2036 when(left: IsInvisible, right: MatchAny, callback: (left: InvisiblePosition, right: PositionData) => Out): Matcher<Out, Exclude<M, "Invisible,Any">>;
2037 when(left: MatchAny, right: IsInvisible, callback: (left: PositionData, right: InvisiblePosition) => Out): ExhaustiveCheck<Out, M, "Any,Invisible">;
2038 when(left: MatchAny, right: MatchAny, callback: (left: PositionData, right: PositionData) => Out): ExhaustiveMatcher<Out>;
2039 }
2040 type SerializedSourceSlice<Chars extends string = string> = [
2041 chars: Chars,
2042 span: src.SerializedSourceSpan
2043 ];
2044 class SourceSlice<Chars extends string = string> {
2045 static synthetic<S extends string>(chars: S): SourceSlice<S>;
2046 static load(source: src.Source, slice: SerializedSourceSlice): SourceSlice;
2047 readonly chars: Chars;
2048 readonly loc: src.SourceSpan;
2049 constructor(options: {
2050 loc: src.SourceSpan;
2051 chars: Chars;
2052 });
2053 getString(): string;
2054 serialize(): SerializedSourceSlice<Chars>;
2055 }
2056 /**
2057 * All spans have these details in common.
2058 */
2059 interface SpanData {
2060 readonly kind: OffsetKind;
2061 /**
2062 * Convert this span into a string. If the span is broken, return `''`.
2063 */
2064 asString(): string;
2065 /**
2066 * Gets the module the span was located in.
2067 */
2068 getModule(): string;
2069 /**
2070 * Get the starting position for this span. Try to avoid creating new position objects, as they
2071 * cache computations.
2072 */
2073 getStart(): AnyPosition;
2074 /**
2075 * Get the ending position for this span. Try to avoid creating new position objects, as they
2076 * cache computations.
2077 */
2078 getEnd(): AnyPosition;
2079 /**
2080 * Compute the `SourceLocation` for this span, returned as an instance of `HbsSpan`.
2081 */
2082 toHbsSpan(): HbsSpan | null;
2083 /**
2084 * For compatibility, whenever the `start` or `end` of a {@see SourceOffset} changes, spans are
2085 * notified of the change so they can update themselves. This shouldn't happen outside of AST
2086 * plugins.
2087 */
2088 locDidUpdate(changes: {
2089 start?: SourcePosition;
2090 end?: SourcePosition;
2091 }): void;
2092 /**
2093 * Serialize into a {@see SerializedSourceSpan}, which is compact and designed for readability in
2094 * context like AST Explorer. If you need a {@see SourceLocation}, use {@see toJSON}.
2095 */
2096 serialize(): SerializedSourceSpan;
2097 }
2098 /**
2099 * A `SourceSpan` object represents a span of characters inside of a template source.
2100 *
2101 * There are three kinds of `SourceSpan` objects:
2102 *
2103 * - `ConcreteSourceSpan`, which contains byte offsets
2104 * - `LazySourceSpan`, which contains `SourceLocation`s from the Handlebars AST, which can be
2105 * converted to byte offsets on demand.
2106 * - `InvisibleSourceSpan`, which represent source strings that aren't present in the source,
2107 * because:
2108 * - they were created synthetically
2109 * - their location is nonsensical (the span is broken)
2110 * - they represent nothing in the source (this currently happens only when a bug in the
2111 * upstream Handlebars parser fails to assign a location to empty blocks)
2112 *
2113 * At a high level, all `SourceSpan` objects provide:
2114 *
2115 * - byte offsets
2116 * - source in column and line format
2117 *
2118 * And you can do these operations on `SourceSpan`s:
2119 *
2120 * - collapse it to a `SourceSpan` representing its starting or ending position
2121 * - slice out some characters, optionally skipping some characters at the beginning or end
2122 * - create a new `SourceSpan` with a different starting or ending offset
2123 *
2124 * All SourceSpan objects implement `SourceLocation`, for compatibility. All SourceSpan
2125 * objects have a `toJSON` that emits `SourceLocation`, also for compatibility.
2126 *
2127 * For compatibility, subclasses of `AbstractSourceSpan` must implement `locDidUpdate`, which
2128 * happens when an AST plugin attempts to modify the `start` or `end` of a span directly.
2129 *
2130 * The goal is to avoid creating any problems for use-cases like AST Explorer.
2131 */
2132 class SourceSpan implements SourceLocation {
2133 private data;
2134 static get NON_EXISTENT(): SourceSpan;
2135 static load(source: Source, serialized: SerializedSourceSpan): SourceSpan;
2136 static forHbsLoc(source: Source, loc: SourceLocation): SourceSpan;
2137 static forCharPositions(source: Source, startPos: number, endPos: number): SourceSpan;
2138 static synthetic(chars: string): SourceSpan;
2139 static broken(pos?: SourceLocation): SourceSpan;
2140 readonly isInvisible: boolean;
2141 constructor(data: SpanData & AnySpan);
2142 getStart(): SourceOffset;
2143 getEnd(): SourceOffset;
2144 get loc(): SourceLocation;
2145 get module(): string;
2146 /**
2147 * Get the starting `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
2148 */
2149 get startPosition(): SourcePosition;
2150 /**
2151 * Get the ending `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
2152 */
2153 get endPosition(): SourcePosition;
2154 /**
2155 * Support converting ASTv1 nodes into a serialized format using JSON.stringify.
2156 */
2157 toJSON(): SourceLocation;
2158 /**
2159 * Create a new span with the current span's end and a new beginning.
2160 */
2161 withStart(other: SourceOffset): SourceSpan;
2162 /**
2163 * Create a new span with the current span's beginning and a new ending.
2164 */
2165 withEnd(other: SourceOffset): SourceSpan;
2166 asString(): string;
2167 /**
2168 * Convert this `SourceSpan` into a `SourceSlice`. In debug mode, this method optionally checks
2169 * that the byte offsets represented by this `SourceSpan` actually correspond to the expected
2170 * string.
2171 */
2172 toSlice(expected?: string): SourceSlice;
2173 /**
2174 * For compatibility with SourceLocation in AST plugins
2175 *
2176 * @deprecated use startPosition instead
2177 */
2178 get start(): SourcePosition;
2179 /**
2180 * For compatibility with SourceLocation in AST plugins
2181 *
2182 * @deprecated use withStart instead
2183 */
2184 set start(position: SourcePosition);
2185 /**
2186 * For compatibility with SourceLocation in AST plugins
2187 *
2188 * @deprecated use endPosition instead
2189 */
2190 get end(): SourcePosition;
2191 /**
2192 * For compatibility with SourceLocation in AST plugins
2193 *
2194 * @deprecated use withEnd instead
2195 */
2196 set end(position: SourcePosition);
2197 /**
2198 * For compatibility with SourceLocation in AST plugins
2199 *
2200 * @deprecated use module instead
2201 */
2202 get source(): string;
2203 collapse(where: "start" | "end"): SourceSpan;
2204 extend(other: SourceSpan): SourceSpan;
2205 serialize(): SerializedSourceSpan;
2206 slice({ skipStart, skipEnd }: {
2207 skipStart?: number;
2208 skipEnd?: number;
2209 }): SourceSpan;
2210 sliceStartChars({ skipStart, chars }: {
2211 skipStart?: number;
2212 chars: number;
2213 }): SourceSpan;
2214 sliceEndChars({ skipEnd, chars }: {
2215 skipEnd?: number;
2216 chars: number;
2217 }): SourceSpan;
2218 }
2219 type AnySpan = HbsSpan | CharPositionSpan | InvisibleSpan;
2220 class CharPositionSpan implements SpanData {
2221 readonly source: Source;
2222 readonly charPositions: {
2223 start: CharPosition;
2224 end: CharPosition;
2225 };
2226 readonly kind = OffsetKind.CharPosition;
2227 _locPosSpan: HbsSpan | BROKEN | null;
2228 constructor(source: Source, charPositions: {
2229 start: CharPosition;
2230 end: CharPosition;
2231 });
2232 wrap(): SourceSpan;
2233 asString(): string;
2234 getModule(): string;
2235 getStart(): AnyPosition;
2236 getEnd(): AnyPosition;
2237 locDidUpdate(): void;
2238 toHbsSpan(): HbsSpan | null;
2239 serialize(): SerializedSourceSpan;
2240 toCharPosSpan(): CharPositionSpan;
2241 }
2242 class HbsSpan implements SpanData {
2243 readonly source: Source;
2244 readonly hbsPositions: {
2245 start: HbsPosition;
2246 end: HbsPosition;
2247 };
2248 readonly kind = OffsetKind.HbsPosition;
2249 _charPosSpan: CharPositionSpan | BROKEN | null;
2250 // the source location from Handlebars + AST Plugins -- could be wrong
2251 _providedHbsLoc: SourceLocation | null;
2252 constructor(source: Source, hbsPositions: {
2253 start: HbsPosition;
2254 end: HbsPosition;
2255 }, providedHbsLoc?: SourceLocation | null);
2256 serialize(): SerializedConcreteSourceSpan;
2257 wrap(): SourceSpan;
2258 private updateProvided;
2259 locDidUpdate({ start, end }: {
2260 start?: SourcePosition;
2261 end?: SourcePosition;
2262 }): void;
2263 asString(): string;
2264 getModule(): string;
2265 getStart(): AnyPosition;
2266 getEnd(): AnyPosition;
2267 toHbsLoc(): SourceLocation;
2268 toHbsSpan(): HbsSpan;
2269 toCharPosSpan(): CharPositionSpan | null;
2270 }
2271 class InvisibleSpan implements SpanData {
2272 readonly kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent;
2273 // whatever was provided, possibly broken
2274 readonly loc: SourceLocation;
2275 // if the span represents a synthetic string
2276 readonly string: string | null;
2277 constructor(kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent, loc: SourceLocation, string?: string | null);
2278 serialize(): SerializedConcreteSourceSpan;
2279 wrap(): SourceSpan;
2280 asString(): string;
2281 locDidUpdate({ start, end }: {
2282 start?: SourcePosition;
2283 end?: SourcePosition;
2284 }): void;
2285 getModule(): string;
2286 getStart(): AnyPosition;
2287 getEnd(): AnyPosition;
2288 toCharPosSpan(): InvisibleSpan;
2289 toHbsSpan(): null;
2290 toHbsLoc(): SourceLocation;
2291 }
2292 const span: MatchFn<SourceSpan>;
2293 type SerializedConcreteSourceSpan = /** collapsed */ number | /** normal */ [
2294 start: number,
2295 size: number
2296 ] | /** synthetic */ string;
2297 type SerializedSourceSpan = SerializedConcreteSourceSpan | OffsetKind.NonExistent | OffsetKind.Broken;
2298 interface SourceLocation {
2299 start: SourcePosition;
2300 end: SourcePosition;
2301 }
2302 interface SourcePosition {
2303 /** >= 1 */
2304 line: number;
2305 /** >= 0 */
2306 column: number;
2307 }
2308 const UNKNOWN_POSITION: Readonly<{
2309 readonly line: 1;
2310 readonly column: 0;
2311 }>;
2312 const SYNTHETIC_LOCATION: Readonly<{
2313 readonly source: "(synthetic)";
2314 readonly start: Readonly<{
2315 readonly line: 1;
2316 readonly column: 0;
2317 }>;
2318 readonly end: Readonly<{
2319 readonly line: 1;
2320 readonly column: 0;
2321 }>;
2322 }>;
2323 /** @deprecated */
2324 const SYNTHETIC: Readonly<{
2325 readonly source: "(synthetic)";
2326 readonly start: Readonly<{
2327 readonly line: 1;
2328 readonly column: 0;
2329 }>;
2330 readonly end: Readonly<{
2331 readonly line: 1;
2332 readonly column: 0;
2333 }>;
2334 }>;
2335 const TEMPORARY_LOCATION: Readonly<{
2336 readonly source: "(temporary)";
2337 readonly start: Readonly<{
2338 readonly line: 1;
2339 readonly column: 0;
2340 }>;
2341 readonly end: Readonly<{
2342 readonly line: 1;
2343 readonly column: 0;
2344 }>;
2345 }>;
2346 const NON_EXISTENT_LOCATION: Readonly<{
2347 readonly source: "(nonexistent)";
2348 readonly start: Readonly<{
2349 readonly line: 1;
2350 readonly column: 0;
2351 }>;
2352 readonly end: Readonly<{
2353 readonly line: 1;
2354 readonly column: 0;
2355 }>;
2356 }>;
2357 const BROKEN_LOCATION: Readonly<{
2358 readonly source: "(broken)";
2359 readonly start: Readonly<{
2360 readonly line: 1;
2361 readonly column: 0;
2362 }>;
2363 readonly end: Readonly<{
2364 readonly line: 1;
2365 readonly column: 0;
2366 }>;
2367 }>;
2368 type LocatedWithSpan = {
2369 offsets: SourceSpan;
2370 };
2371 type LocatedWithOptionalSpan = {
2372 offsets: SourceSpan | null;
2373 };
2374 type LocatedWithPositions = {
2375 loc: SourceLocation;
2376 };
2377 type LocatedWithOptionalPositions = {
2378 loc?: SourceLocation;
2379 };
2380 function isLocatedWithPositionsArray(location: LocatedWithOptionalPositions[]): location is PresentArray<LocatedWithPositions>;
2381 function isLocatedWithPositions(location: LocatedWithOptionalPositions): location is LocatedWithPositions;
2382 type HasSourceLocation = SourceLocation | LocatedWithPositions | PresentArray<LocatedWithPositions>;
2383 type MaybeHasSourceLocation = null | LocatedWithOptionalPositions | LocatedWithOptionalPositions[];
2384 /**
2385 * All positions have these details in common. Most notably, all three kinds of positions can
2386 * must be able to attempt to convert themselves into {@see CharPosition}.
2387 */
2388 interface PositionData {
2389 readonly kind: OffsetKind;
2390 toCharPos(): CharPosition | null;
2391 toJSON(): SourcePosition;
2392 }
2393 /**
2394 * Used to indicate that an attempt to convert a `SourcePosition` to a character offset failed. It
2395 * is separate from `null` so that `null` can be used to indicate that the computation wasn't yet
2396 * attempted (and therefore to cache the failure)
2397 */
2398 const BROKEN = "BROKEN";
2399 type BROKEN = "BROKEN";
2400 type AnyPosition = HbsPosition | CharPosition | InvisiblePosition;
2401 /**
2402 * A `SourceOffset` represents a single position in the source.
2403 *
2404 * There are three kinds of backing data for `SourceOffset` objects:
2405 *
2406 * - `CharPosition`, which contains a character offset into the raw source string
2407 * - `HbsPosition`, which contains a `SourcePosition` from the Handlebars AST, which can be
2408 * converted to a `CharPosition` on demand.
2409 * - `InvisiblePosition`, which represents a position not in source (@see {InvisiblePosition})
2410 */
2411 class SourceOffset {
2412 readonly data: PositionData & AnyPosition;
2413 /**
2414 * Create a `SourceOffset` from a Handlebars `SourcePosition`. It's stored as-is, and converted
2415 * into a character offset on demand, which avoids unnecessarily computing the offset of every
2416 * `SourceLocation`, but also means that broken `SourcePosition`s are not always detected.
2417 */
2418 static forHbsPos(source: Source, pos: SourcePosition): SourceOffset;
2419 /**
2420 * Create a `SourceOffset` that corresponds to a broken `SourcePosition`. This means that the
2421 * calling code determined (or knows) that the `SourceLocation` doesn't correspond correctly to
2422 * any part of the source.
2423 */
2424 static broken(pos?: SourcePosition): SourceOffset;
2425 constructor(data: PositionData & AnyPosition);
2426 /**
2427 * Get the character offset for this `SourceOffset`, if possible.
2428 */
2429 get offset(): number | null;
2430 /**
2431 * Compare this offset with another one.
2432 *
2433 * If both offsets are `HbsPosition`s, they're equivalent as long as their lines and columns are
2434 * the same. This avoids computing offsets unnecessarily.
2435 *
2436 * Otherwise, two `SourceOffset`s are equivalent if their successfully computed character offsets
2437 * are the same.
2438 */
2439 eql(right: SourceOffset): boolean;
2440 /**
2441 * Create a span that starts from this source offset and ends with another source offset. Avoid
2442 * computing character offsets if both `SourceOffset`s are still lazy.
2443 */
2444 until(other: SourceOffset): SourceSpan;
2445 /**
2446 * Create a `SourceOffset` by moving the character position represented by this source offset
2447 * forward or backward (if `by` is negative), if possible.
2448 *
2449 * If this `SourceOffset` can't compute a valid character offset, `move` returns a broken offset.
2450 *
2451 * If the resulting character offset is less than 0 or greater than the size of the source, `move`
2452 * returns a broken offset.
2453 */
2454 move(by: number): SourceOffset;
2455 /**
2456 * Create a new `SourceSpan` that represents a collapsed range at this source offset. Avoid
2457 * computing the character offset if it has not already been computed.
2458 */
2459 collapsed(): SourceSpan;
2460 /**
2461 * Convert this `SourceOffset` into a Handlebars {@see SourcePosition} for compatibility with
2462 * existing plugins.
2463 */
2464 toJSON(): SourcePosition;
2465 }
2466 class CharPosition implements PositionData {
2467 readonly source: Source;
2468 readonly charPos: number;
2469 readonly kind = OffsetKind.CharPosition;
2470 /** Computed from char offset */
2471 _locPos: HbsPosition | BROKEN | null;
2472 constructor(source: Source, charPos: number);
2473 /**
2474 * This is already a `CharPosition`.
2475 *
2476 * {@see HbsPosition} for the alternative.
2477 */
2478 toCharPos(): CharPosition;
2479 /**
2480 * Produce a Handlebars {@see SourcePosition} for this `CharPosition`. If this `CharPosition` was
2481 * computed using {@see SourceOffset#move}, this will compute the `SourcePosition` for the offset.
2482 */
2483 toJSON(): SourcePosition;
2484 wrap(): SourceOffset;
2485 /**
2486 * A `CharPosition` always has an offset it can produce without any additional computation.
2487 */
2488 get offset(): number;
2489 /**
2490 * Convert the current character offset to an `HbsPosition`, if it was not already computed. Once
2491 * a `CharPosition` has computed its `HbsPosition`, it will not need to do compute it again, and
2492 * the same `CharPosition` is retained when used as one of the ends of a `SourceSpan`, so
2493 * computing the `HbsPosition` should be a one-time operation.
2494 */
2495 toHbsPos(): HbsPosition | null;
2496 }
2497 class HbsPosition implements PositionData {
2498 readonly source: Source;
2499 readonly hbsPos: SourcePosition;
2500 readonly kind = OffsetKind.HbsPosition;
2501 _charPos: CharPosition | BROKEN | null;
2502 constructor(source: Source, hbsPos: SourcePosition, charPos?: number | null);
2503 /**
2504 * Lazily compute the character offset from the {@see SourcePosition}. Once an `HbsPosition` has
2505 * computed its `CharPosition`, it will not need to do compute it again, and the same
2506 * `HbsPosition` is retained when used as one of the ends of a `SourceSpan`, so computing the
2507 * `CharPosition` should be a one-time operation.
2508 */
2509 toCharPos(): CharPosition | null;
2510 /**
2511 * Return the {@see SourcePosition} that this `HbsPosition` was instantiated with. This operation
2512 * does not need to compute anything.
2513 */
2514 toJSON(): SourcePosition;
2515 wrap(): SourceOffset;
2516 /**
2517 * This is already an `HbsPosition`.
2518 *
2519 * {@see CharPosition} for the alternative.
2520 */
2521 toHbsPos(): HbsPosition;
2522 }
2523 class InvisiblePosition implements PositionData {
2524 readonly kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent;
2525 // whatever was provided, possibly broken
2526 readonly pos: SourcePosition;
2527 constructor(kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent, pos: SourcePosition);
2528 /**
2529 * A broken position cannot be turned into a {@see CharacterPosition}.
2530 */
2531 toCharPos(): null;
2532 /**
2533 * The serialization of an `InvisiblePosition is whatever Handlebars {@see SourcePosition} was
2534 * originally identified as broken, non-existent or synthetic.
2535 *
2536 * If an `InvisiblePosition` never had an source offset at all, this method returns
2537 * {@see UNKNOWN_POSITION} for compatibility.
2538 */
2539 toJSON(): SourcePosition;
2540 wrap(): SourceOffset;
2541 get offset(): null;
2542 }
2543 type HasSpan = SourceSpan | LocatedWithSpan | PresentArray<LocatedWithSpan>;
2544 type MaybeHasSpan = SourceSpan | LocatedWithOptionalSpan | LocatedWithOptionalSpan[] | null;
2545 type ToSourceOffset = number | SourceOffset;
2546 class SpanList {
2547 static range(span: PresentArray<HasSourceSpan>): SourceSpan;
2548 static range(span: HasSourceSpan[], fallback: SourceSpan): SourceSpan;
2549 _span: SourceSpan[];
2550 constructor(span?: SourceSpan[]);
2551 add(offset: SourceSpan): void;
2552 getRangeOffset(fallback: SourceSpan): SourceSpan;
2553 }
2554 type HasSourceSpan = {
2555 loc: SourceSpan;
2556 } | SourceSpan | [
2557 HasSourceSpan,
2558 ...HasSourceSpan[]
2559 ];
2560 function loc(span: HasSourceSpan): SourceSpan;
2561 type MaybeHasSourceSpan = {
2562 loc: SourceSpan;
2563 } | SourceSpan | MaybeHasSourceSpan[];
2564 function hasSpan(span: MaybeHasSourceSpan): span is HasSourceSpan;
2565 function maybeLoc(location: MaybeHasSourceSpan, fallback: SourceSpan): SourceSpan;
2566 interface BaseNode {
2567 // Every leaf interface that extends BaseNode must specify a type property.
2568 // The type property should be a string literal. For example, Identifier
2569 // has: `type: "Identifier"`
2570 type: NodeType;
2571 loc: src.SourceSpan;
2572 }
2573 interface CommonProgram extends BaseNode {
2574 body: Statement[];
2575 }
2576 interface Block extends CommonProgram {
2577 type: "Block";
2578 params: VarHead[];
2579 chained?: boolean;
2580 /**
2581 * string accessor for params.name
2582 */
2583 blockParams: string[];
2584 }
2585 type EntityEncodingState = "transformed" | "raw";
2586 interface Template extends CommonProgram {
2587 type: "Template";
2588 blockParams: string[];
2589 }
2590 /**
2591 * @deprecated use Template or Block instead
2592 */
2593 type Program = Template | Block;
2594 type CallableExpression = SubExpression | PathExpression;
2595 interface CallParts {
2596 path: CallableExpression;
2597 params: Expression[];
2598 hash: Hash;
2599 loc: src.SourceSpan;
2600 }
2601 type CallNode = MustacheStatement | BlockStatement | ElementModifierStatement | SubExpression;
2602 interface MustacheStatement extends BaseNode {
2603 type: "MustacheStatement";
2604 path: Expression;
2605 params: Expression[];
2606 hash: Hash;
2607 trusting: boolean;
2608 strip: StripFlags;
2609 /**
2610 * @deprecated use trusting instead
2611 */
2612 escaped: boolean;
2613 }
2614 interface BlockStatement extends BaseNode {
2615 type: "BlockStatement";
2616 path: CallableExpression;
2617 params: Expression[];
2618 hash: Hash;
2619 program: Block;
2620 inverse?: Nullable<Block>;
2621 openStrip: StripFlags;
2622 inverseStrip: StripFlags;
2623 closeStrip: StripFlags;
2624 // Printer extension
2625 chained?: boolean;
2626 }
2627 interface ElementModifierStatement extends BaseNode {
2628 type: "ElementModifierStatement";
2629 path: CallableExpression;
2630 params: Expression[];
2631 hash: Hash;
2632 }
2633 interface CommentStatement extends BaseNode {
2634 type: "CommentStatement";
2635 value: string;
2636 }
2637 interface MustacheCommentStatement extends BaseNode {
2638 type: "MustacheCommentStatement";
2639 value: string;
2640 }
2641 interface ElementNode extends BaseNode {
2642 type: "ElementNode";
2643 path: PathExpression;
2644 selfClosing: boolean;
2645 attributes: AttrNode[];
2646 params: VarHead[];
2647 modifiers: ElementModifierStatement[];
2648 comments: MustacheCommentStatement[];
2649 children: Statement[];
2650 /**
2651 * span for the open tag
2652 */
2653 openTag: src.SourceSpan;
2654 /**
2655 * span for the close tag, null for void or self-closing tags
2656 */
2657 closeTag: Nullable<src.SourceSpan>;
2658 /**
2659 * string accessor for path.original
2660 */
2661 tag: string;
2662 /**
2663 * string accessor for params.name
2664 */
2665 blockParams: string[];
2666 }
2667 type StatementName = "MustacheStatement" | "CommentStatement" | "BlockStatement" | "MustacheCommentStatement" | "TextNode" | "ElementNode";
2668 interface AttrNode extends BaseNode {
2669 type: "AttrNode";
2670 name: string;
2671 value: AttrValue;
2672 }
2673 type AttrValue = TextNode | MustacheStatement | ConcatStatement;
2674 type AttrPart = TextNode | MustacheStatement;
2675 interface TextNode extends BaseNode {
2676 type: "TextNode";
2677 chars: string;
2678 }
2679 interface ConcatStatement extends BaseNode {
2680 type: "ConcatStatement";
2681 parts: PresentArray<TextNode | MustacheStatement>;
2682 }
2683 type ExpressionName = "SubExpression" | "PathExpression" | LiteralName;
2684 interface SubExpression extends BaseNode {
2685 type: "SubExpression";
2686 path: CallableExpression;
2687 params: Expression[];
2688 hash: Hash;
2689 }
2690 interface ThisHead {
2691 type: "ThisHead";
2692 original: "this";
2693 loc: src.SourceSpan;
2694 }
2695 interface AtHead {
2696 type: "AtHead";
2697 name: string;
2698 loc: src.SourceSpan;
2699 /**
2700 * alias for name
2701 */
2702 original: string;
2703 }
2704 interface VarHead {
2705 type: "VarHead";
2706 name: string;
2707 loc: src.SourceSpan;
2708 /**
2709 * alias for name
2710 */
2711 original: string;
2712 }
2713 type PathHead = ThisHead | AtHead | VarHead;
2714 interface MinimalPathExpression extends BaseNode {
2715 type: "PathExpression";
2716 head: PathHead;
2717 tail: string[];
2718 }
2719 interface PathExpression extends MinimalPathExpression {
2720 type: "PathExpression";
2721 original: string;
2722 head: PathHead;
2723 tail: string[];
2724 /**
2725 * @deprecated use `head` and `tail` instead
2726 */
2727 parts: readonly string[];
2728 /**
2729 * @deprecated use `head.type` instead
2730 */
2731 readonly this: boolean;
2732 /**
2733 * @deprecated use `head.type' instead
2734 */
2735 readonly data: boolean;
2736 }
2737 type LiteralName = "StringLiteral" | "BooleanLiteral" | "NumberLiteral" | "UndefinedLiteral" | "NullLiteral";
2738 interface StringLiteral extends BaseNode {
2739 type: "StringLiteral";
2740 value: string;
2741 /**
2742 * @deprecated use value instead
2743 */
2744 original: string;
2745 }
2746 interface BooleanLiteral extends BaseNode {
2747 type: "BooleanLiteral";
2748 value: boolean;
2749 /**
2750 * @deprecated use value instead
2751 */
2752 original: boolean;
2753 }
2754 interface NumberLiteral extends BaseNode {
2755 type: "NumberLiteral";
2756 value: number;
2757 /**
2758 * @deprecated use value instead
2759 */
2760 original: number;
2761 }
2762 interface UndefinedLiteral extends BaseNode {
2763 type: "UndefinedLiteral";
2764 value: undefined;
2765 /**
2766 * @deprecated use value instead
2767 */
2768 original: undefined;
2769 }
2770 interface NullLiteral extends BaseNode {
2771 type: "NullLiteral";
2772 value: null;
2773 /**
2774 * @deprecated use value instead
2775 */
2776 original: null;
2777 }
2778 interface Hash extends BaseNode {
2779 type: "Hash";
2780 pairs: HashPair[];
2781 }
2782 interface HashPair extends BaseNode {
2783 type: "HashPair";
2784 key: string;
2785 value: Expression;
2786 }
2787 interface StripFlags {
2788 open: boolean;
2789 close: boolean;
2790 }
2791 type Nodes = {
2792 Template: Template;
2793 Block: Block;
2794 MustacheStatement: MustacheStatement;
2795 BlockStatement: BlockStatement;
2796 ElementModifierStatement: ElementModifierStatement;
2797 CommentStatement: CommentStatement;
2798 MustacheCommentStatement: MustacheCommentStatement;
2799 ElementNode: ElementNode;
2800 AttrNode: AttrNode;
2801 TextNode: TextNode;
2802 ConcatStatement: ConcatStatement;
2803 SubExpression: SubExpression;
2804 PathExpression: PathExpression;
2805 StringLiteral: StringLiteral;
2806 BooleanLiteral: BooleanLiteral;
2807 NumberLiteral: NumberLiteral;
2808 NullLiteral: NullLiteral;
2809 UndefinedLiteral: UndefinedLiteral;
2810 Hash: Hash;
2811 HashPair: HashPair;
2812 };
2813 type NodeType = keyof Nodes;
2814 type Node = Nodes[NodeType];
2815 // These "sub-node" cannot appear standalone, they are only used inside another
2816 // "real" AST node to provide richer information. The distinction mostly exists
2817 // for backwards compatibility reason. These nodes are not traversed and do not
2818 // have visitor keys for them, so it won't break existing AST consumers (e.g.
2819 // those that implemented an `All` visitor may not be expecting these new types
2820 // of nodes).
2821 //
2822 // Conceptually, the idea of "sub-node" does make sense, and you can say source
2823 // locations are another kind of these things. However, in these cases, they
2824 // actually fully implement the `BaseNode` interface, and only not extending
2825 // `BaseNode` because the `type` field is not `keyof Nodes` (which is circular
2826 // reasoning). If these are not "real" nodes because they can only appear in
2827 // very limited context, then the same reasoning probably applies for, say,
2828 // HashPair.
2829 //
2830 // If we do eventually make some kind of breaking change here, perhaps with
2831 // some kind of opt-in, then we can consider upgrading these into "real" nodes,
2832 // but for now, this is where they go, and it isn't a huge problem in practice
2833 // because there are little utility in traversing these kind of nodes anyway.
2834 type SubNodes = {
2835 ThisHead: ThisHead;
2836 AtHead: AtHead;
2837 VarHead: VarHead;
2838 };
2839 type SubNodeType = keyof SubNodes;
2840 type SubNode = SubNodes[SubNodeType];
2841 type Statement = Nodes[StatementName];
2842 type Statements = Pick<Nodes, StatementName>;
2843 type Literal = Nodes[LiteralName];
2844 type Expression = Nodes[ExpressionName];
2845 type Expressions = Pick<Nodes, ExpressionName>;
2846 type TopLevelStatement = Statement | Nodes["Block"];
2847 type ParentNode = Template | Block | ElementNode;
2848}
2849declare function getVoidTags(): string[];
2850interface PrinterOptions {
2851 entityEncoding: ASTv1.EntityEncodingState;
2852 /**
2853 * Used to override the mechanism of printing a given AST.Node.
2854 *
2855 * This will generally only be useful to source -> source codemods
2856 * where you would like to specialize/override the way a given node is
2857 * printed (e.g. you would like to preserve as much of the original
2858 * formatting as possible).
2859 *
2860 * When the provided override returns undefined, the default built in printing
2861 * will be done for the AST.Node.
2862 *
2863 * @param ast the ast node to be printed
2864 * @param options the options specified during the print() invocation
2865 */
2866 override?(ast: ASTv1.Node, options: PrinterOptions): void | string;
2867}
2868/**
2869 * Examples when true:
2870 * - link
2871 * - liNK
2872 *
2873 * Examples when false:
2874 * - Link (component)
2875 */
2876declare function isVoidTag(tag: string): boolean;
2877declare function build(ast: ASTv1.Node, options?: PrinterOptions): string;
2878declare function sortByLoc(a: ASTv1.Node, b: ASTv1.Node): -1 | 0 | 1;
2879interface GetTemplateLocalsOptions {
2880 includeKeywords?: boolean;
2881 includeHtmlElements?: boolean;
2882}
2883/**
2884 * Parses and traverses a given handlebars html template to extract all template locals
2885 * referenced that could possible come from the parent scope. Can exclude known keywords
2886 * optionally.
2887 */
2888declare function getTemplateLocals(html: string, options?: GetTemplateLocalsOptions): string[];
2889type Keywords = keyof typeof KEYWORDS_TYPES;
2890type KeywordType = "Call" | "Modifier" | "Append" | "Block";
2891declare function isKeyword(word: string): word is Keywords;
2892declare function isKeyword(word: string, type: KeywordType): boolean;
2893/**
2894 * This includes the full list of keywords currently in use in the template
2895 * language, and where their valid usages are.
2896 */
2897declare const KEYWORDS_TYPES: {
2898 action: ("Call" | "Modifier")[];
2899 component: ("Block" | "Call" | "Append")[];
2900 debugger: "Append"[];
2901 "each-in": "Block"[];
2902 each: "Block"[];
2903 "has-block-params": ("Call" | "Append")[];
2904 "has-block": ("Call" | "Append")[];
2905 helper: ("Call" | "Append")[];
2906 if: ("Block" | "Call" | "Append")[];
2907 "in-element": "Block"[];
2908 let: "Block"[];
2909 log: ("Call" | "Append")[];
2910 modifier: ("Call" | "Modifier")[];
2911 mount: "Append"[];
2912 mut: ("Call" | "Append")[];
2913 outlet: "Append"[];
2914 readonly: ("Call" | "Append")[];
2915 unbound: ("Call" | "Append")[];
2916 unless: ("Block" | "Call" | "Append")[];
2917 yield: "Append"[];
2918};
2919type ParserNodeBuilder<N extends {
2920 loc: src.SourceSpan;
2921}> = Omit<N, "loc"> & {
2922 start: src.SourceOffset;
2923};
2924interface StartTag {
2925 readonly type: "StartTag";
2926 name: string;
2927 nameStart: Nullable<src.SourceOffset>;
2928 nameEnd: Nullable<src.SourceOffset>;
2929 readonly attributes: ASTv1.AttrNode[];
2930 readonly modifiers: ASTv1.ElementModifierStatement[];
2931 readonly comments: ASTv1.MustacheCommentStatement[];
2932 readonly params: ASTv1.VarHead[];
2933 selfClosing: boolean;
2934 readonly loc: src.SourceSpan;
2935}
2936interface EndTag {
2937 readonly type: "EndTag";
2938 name: string;
2939 readonly loc: src.SourceSpan;
2940}
2941interface Attribute {
2942 name: string;
2943 currentPart: ASTv1.TextNode | null;
2944 parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[];
2945 isQuoted: boolean;
2946 isDynamic: boolean;
2947 start: src.SourceOffset;
2948 valueSpan: src.SourceSpan;
2949}
2950declare abstract class Parser {
2951 protected elementStack: ASTv1.ParentNode[];
2952 private lines;
2953 readonly source: src.Source;
2954 currentAttribute: Nullable<Attribute>;
2955 currentNode: Nullable<Readonly<ParserNodeBuilder<ASTv1.CommentStatement> | ParserNodeBuilder<ASTv1.TextNode> | ParserNodeBuilder<StartTag> | ParserNodeBuilder<EndTag>>>;
2956 tokenizer: EventedTokenizer;
2957 constructor(source: src.Source, entityParser?: EntityParser, mode?: "precompile" | "codemod");
2958 offset(): src.SourceOffset;
2959 pos({ line, column }: src.SourcePosition): src.SourceOffset;
2960 finish<T extends {
2961 loc: src.SourceSpan;
2962 }>(node: ParserNodeBuilder<T>): T;
2963 abstract parse(node: HBS.Program, locals: string[]): ASTv1.Template;
2964 abstract Program(node: HBS.Program): HBS.Output<"Program">;
2965 abstract MustacheStatement(node: HBS.MustacheStatement): HBS.Output<"MustacheStatement">;
2966 abstract Decorator(node: HBS.Decorator): HBS.Output<"Decorator">;
2967 abstract BlockStatement(node: HBS.BlockStatement): HBS.Output<"BlockStatement">;
2968 abstract DecoratorBlock(node: HBS.DecoratorBlock): HBS.Output<"DecoratorBlock">;
2969 abstract PartialStatement(node: HBS.PartialStatement): HBS.Output<"PartialStatement">;
2970 abstract PartialBlockStatement(node: HBS.PartialBlockStatement): HBS.Output<"PartialBlockStatement">;
2971 abstract ContentStatement(node: HBS.ContentStatement): HBS.Output<"ContentStatement">;
2972 abstract CommentStatement(node: HBS.CommentStatement): HBS.Output<"CommentStatement">;
2973 abstract SubExpression(node: HBS.SubExpression): HBS.Output<"SubExpression">;
2974 abstract PathExpression(node: HBS.PathExpression): HBS.Output<"PathExpression">;
2975 abstract StringLiteral(node: HBS.StringLiteral): HBS.Output<"StringLiteral">;
2976 abstract BooleanLiteral(node: HBS.BooleanLiteral): HBS.Output<"BooleanLiteral">;
2977 abstract NumberLiteral(node: HBS.NumberLiteral): HBS.Output<"NumberLiteral">;
2978 abstract UndefinedLiteral(node: HBS.UndefinedLiteral): HBS.Output<"UndefinedLiteral">;
2979 abstract NullLiteral(node: HBS.NullLiteral): HBS.Output<"NullLiteral">;
2980 abstract reset(): void;
2981 abstract finishData(): void;
2982 abstract tagOpen(): void;
2983 abstract beginData(): void;
2984 abstract appendToData(char: string): void;
2985 abstract beginStartTag(): void;
2986 abstract appendToTagName(char: string): void;
2987 abstract beginAttribute(): void;
2988 abstract appendToAttributeName(char: string): void;
2989 abstract beginAttributeValue(quoted: boolean): void;
2990 abstract appendToAttributeValue(char: string): void;
2991 abstract finishAttributeValue(): void;
2992 abstract markTagAsSelfClosing(): void;
2993 abstract beginEndTag(): void;
2994 abstract finishTag(): void;
2995 abstract beginComment(): void;
2996 abstract appendToCommentData(char: string): void;
2997 abstract finishComment(): void;
2998 abstract reportSyntaxError(error: string): void;
2999 get currentAttr(): Attribute;
3000 get currentTag(): ParserNodeBuilder<StartTag> | ParserNodeBuilder<EndTag>;
3001 get currentStartTag(): ParserNodeBuilder<StartTag>;
3002 get currentEndTag(): ParserNodeBuilder<EndTag>;
3003 get currentComment(): ParserNodeBuilder<ASTv1.CommentStatement>;
3004 get currentData(): ParserNodeBuilder<ASTv1.TextNode>;
3005 acceptNode<T extends HBS.NodeType>(node: HBS.Node<T>): HBS.Output<T>;
3006 currentElement(): ASTv1.ParentNode;
3007 sourceForNode(node: HBS.Node, endNode?: {
3008 loc: HBS.SourceLocation;
3009 }): string;
3010}
3011// ensure stays in sync with typing
3012// ParentNode and ChildKey types are derived from VisitorKeysMap
3013declare const visitorKeys: {
3014 readonly Template: readonly [
3015 "body"
3016 ];
3017 readonly Block: readonly [
3018 "body"
3019 ];
3020 readonly MustacheStatement: readonly [
3021 "path",
3022 "params",
3023 "hash"
3024 ];
3025 readonly BlockStatement: readonly [
3026 "path",
3027 "params",
3028 "hash",
3029 "program",
3030 "inverse"
3031 ];
3032 readonly ElementModifierStatement: readonly [
3033 "path",
3034 "params",
3035 "hash"
3036 ];
3037 readonly CommentStatement: readonly [
3038 ];
3039 readonly MustacheCommentStatement: readonly [
3040 ];
3041 readonly ElementNode: readonly [
3042 "attributes",
3043 "modifiers",
3044 "children",
3045 "comments"
3046 ];
3047 readonly AttrNode: readonly [
3048 "value"
3049 ];
3050 readonly TextNode: readonly [
3051 ];
3052 readonly ConcatStatement: readonly [
3053 "parts"
3054 ];
3055 readonly SubExpression: readonly [
3056 "path",
3057 "params",
3058 "hash"
3059 ];
3060 readonly PathExpression: readonly [
3061 ];
3062 readonly StringLiteral: readonly [
3063 ];
3064 readonly BooleanLiteral: readonly [
3065 ];
3066 readonly NumberLiteral: readonly [
3067 ];
3068 readonly NullLiteral: readonly [
3069 ];
3070 readonly UndefinedLiteral: readonly [
3071 ];
3072 readonly Hash: readonly [
3073 "pairs"
3074 ];
3075 readonly HashPair: readonly [
3076 "value"
3077 ];
3078};
3079type VisitorKeysMap = typeof visitorKeys;
3080type VisitorKeys = {
3081 [P in keyof VisitorKeysMap]: VisitorKeysMap[P][number];
3082};
3083type VisitorKey<N extends ASTv1.Node> = VisitorKeys[N["type"]] & keyof N;
3084declare class WalkerPath<N extends ASTv1.Node> {
3085 node: N;
3086 parent: WalkerPath<ASTv1.Node> | null;
3087 parentKey: string | null;
3088 constructor(node: N, parent?: WalkerPath<ASTv1.Node> | null, parentKey?: string | null);
3089 get parentNode(): ASTv1.Node | null;
3090 parents(): Iterable<WalkerPath<ASTv1.Node> | null>;
3091}
3092interface FullNodeTraversal<N extends ASTv1.Node> {
3093 enter?(node: N, path: WalkerPath<N>): void;
3094 exit?(node: N, path: WalkerPath<N>): void;
3095 keys?: KeysVisitor<N>;
3096}
3097type NodeHandler<N extends ASTv1.Node> = (node: N, path: WalkerPath<N>) => void;
3098type NodeTraversal<N extends ASTv1.Node> = FullNodeTraversal<N> | NodeHandler<N>;
3099type NodeVisitor = {
3100 [P in keyof ASTv1.Nodes]?: NodeTraversal<ASTv1.Nodes[P]>;
3101} & {
3102 All?: NodeTraversal<ASTv1.Node>;
3103 /**
3104 * @deprecated use Template or Block instead
3105 */
3106 Program?: NodeTraversal<ASTv1.Template | ASTv1.Block>;
3107};
3108interface FullKeyTraversal<N extends ASTv1.Node, K extends string> {
3109 enter?(node: N, key: K): void;
3110 exit?(node: N, key: K): void;
3111}
3112type KeyHandler<N extends ASTv1.Node, K extends VisitorKey<N>> = (node: N, key: K) => void;
3113type KeyTraversal<N extends ASTv1.Node, K extends VisitorKey<N>> = FullKeyTraversal<N, K> | KeyHandler<N, K>;
3114type KeysVisitor<N extends ASTv1.Node> = {
3115 [P in VisitorKey<N>]?: KeyTraversal<N, P>;
3116} & {
3117 All?: KeyTraversal<N, VisitorKey<N>>;
3118 /**
3119 * @deprecated use Template or Block instead
3120 */
3121 Program?: KeyTraversal<ASTv1.Template | ASTv1.Block, "body">;
3122};
3123declare const print: typeof build;
3124declare function traverse(node: ASTv1.Node, visitor: NodeVisitor): void;
3125type NodeCallback<N extends ASTv1.Node> = (node: N, walker: Walker) => void;
3126declare class Walker {
3127 order?: unknown;
3128 stack: unknown[];
3129 constructor(order?: unknown);
3130 visit<N extends ASTv1.Node>(node: Nullable<N>, visitor: NodeCallback<N>): void;
3131 children<N extends ASTv1.Node>(node: N & ASTv1.Node, callback: NodeCallback<N & ASTv1.Node>): void;
3132}
3133declare class Source {
3134 readonly source: string;
3135 readonly module: string;
3136 static from(source: string, options?: PrecompileOptions): Source;
3137 constructor(source: string, module?: string);
3138 /**
3139 * Validate that the character offset represents a position in the source string.
3140 */
3141 check(offset: number): boolean;
3142 slice(start: number, end: number): string;
3143 offsetFor(line: number, column: number): SourceOffset;
3144 spanFor({ start, end }: Readonly<SourceLocation>): SourceSpan;
3145 hbsPosFor(offset: number): Nullable<SourcePosition>;
3146 charPosFor(position: SourcePosition): number | null;
3147}
3148declare enum OffsetKind {
3149 /**
3150 * We have already computed the character position of this offset or span.
3151 */
3152 CharPosition = "CharPosition",
3153 /**
3154 * This offset or span was instantiated with a Handlebars SourcePosition or SourceLocation. Its
3155 * character position will be computed on demand.
3156 */
3157 HbsPosition = "HbsPosition",
3158 /**
3159 * for (rare) situations where a node is created but there was no source location (e.g. the name
3160 * "default" in default blocks when the word "default" never appeared in source). This is used
3161 * by the internals when there is a legitimate reason for the internals to synthesize a node
3162 * with no location.
3163 */
3164 InternalsSynthetic = "InternalsSynthetic",
3165 /**
3166 * For situations where a node represents zero parts of the source (for example, empty arguments).
3167 * In general, we attempt to assign these nodes *some* position (empty arguments can be
3168 * positioned immediately after the callee), but it's not always possible
3169 */
3170 NonExistent = "NonExistent",
3171 /**
3172 * For situations where a source location was expected, but it didn't correspond to the node in
3173 * the source. This happens if a plugin creates broken locations.
3174 */
3175 Broken = "Broken"
3176}
3177/**
3178 * This file implements the DSL used by span and offset in places where they need to exhaustively
3179 * consider all combinations of states (Handlebars offsets, character offsets and invisible/broken
3180 * offsets).
3181 *
3182 * It's probably overkill, but it makes the code that uses it clear. It could be refactored or
3183 * removed.
3184 */
3185declare const MatchAny = "MATCH_ANY";
3186type MatchAny = "MATCH_ANY";
3187type Matches = "Char,Hbs" | "Hbs,Char" | "Hbs,Hbs" | "Char,Char" | "Invisible,Any" | "Any,Invisible";
3188declare const IsInvisible = "IS_INVISIBLE";
3189type IsInvisible = "IS_INVISIBLE";
3190type Pattern = OffsetKind | IsInvisible | MatchAny;
3191declare class When<Out> {
3192 _map: Map<Pattern, Out>;
3193 get(pattern: Pattern, or: () => Out): Out;
3194 add(pattern: Pattern, out: Out): void;
3195 match(kind: OffsetKind): Out[];
3196}
3197type ExhaustiveCheck<Out, In extends Matches, Removed extends Matches> = Exclude<In, Removed> extends never ? ExhaustiveMatcher<Out> : Matcher<Out, Exclude<In, Removed>>;
3198type MatchFn<Out> = (left: PositionData, right: PositionData) => Out;
3199interface ExhaustiveMatcher<Out> {
3200 check(): MatchFn<Out>;
3201}
3202declare class Matcher<Out, M extends Matches = Matches> {
3203 _whens: When<When<(left: PositionData, right: PositionData) => Out>>;
3204 /**
3205 * You didn't exhaustively match all possibilities.
3206 */
3207 protected check(): MatchFn<Out>;
3208 private matchFor;
3209 // This big block is the bulk of the heavy lifting in this file. It facilitates exhaustiveness
3210 // checking so that matchers can ensure they've actually covered all the cases (and TypeScript
3211 // will treat it as an exhaustive match).
3212 when(left: OffsetKind.CharPosition, right: OffsetKind.HbsPosition, callback: (left: CharPosition, right: HbsPosition) => Out): ExhaustiveCheck<Out, M, "Char,Hbs">;
3213 when(left: OffsetKind.HbsPosition, right: OffsetKind.CharPosition, callback: (left: HbsPosition, right: CharPosition) => Out): ExhaustiveCheck<Out, M, "Hbs,Char">;
3214 when(left: OffsetKind.HbsPosition, right: OffsetKind.HbsPosition, callback: (left: HbsPosition, right: HbsPosition) => Out): ExhaustiveCheck<Out, M, "Hbs,Hbs">;
3215 when(left: OffsetKind.CharPosition, right: OffsetKind.CharPosition, callback: (left: CharPosition, right: CharPosition) => Out): ExhaustiveCheck<Out, M, "Char,Char">;
3216 when(left: IsInvisible, right: MatchAny, callback: (left: InvisiblePosition, right: PositionData) => Out): Matcher<Out, Exclude<M, "Invisible,Any">>;
3217 when(left: MatchAny, right: IsInvisible, callback: (left: PositionData, right: InvisiblePosition) => Out): ExhaustiveCheck<Out, M, "Any,Invisible">;
3218 when(left: MatchAny, right: MatchAny, callback: (left: PositionData, right: PositionData) => Out): ExhaustiveMatcher<Out>;
3219}
3220type SerializedSourceSlice<Chars extends string = string> = [
3221 chars: Chars,
3222 span: src.SerializedSourceSpan
3223];
3224declare class SourceSlice<Chars extends string = string> {
3225 static synthetic<S extends string>(chars: S): SourceSlice<S>;
3226 static load(source: src.Source, slice: SerializedSourceSlice): SourceSlice;
3227 readonly chars: Chars;
3228 readonly loc: src.SourceSpan;
3229 constructor(options: {
3230 loc: src.SourceSpan;
3231 chars: Chars;
3232 });
3233 getString(): string;
3234 serialize(): SerializedSourceSlice<Chars>;
3235}
3236/**
3237 * All spans have these details in common.
3238 */
3239interface SpanData {
3240 readonly kind: OffsetKind;
3241 /**
3242 * Convert this span into a string. If the span is broken, return `''`.
3243 */
3244 asString(): string;
3245 /**
3246 * Gets the module the span was located in.
3247 */
3248 getModule(): string;
3249 /**
3250 * Get the starting position for this span. Try to avoid creating new position objects, as they
3251 * cache computations.
3252 */
3253 getStart(): AnyPosition;
3254 /**
3255 * Get the ending position for this span. Try to avoid creating new position objects, as they
3256 * cache computations.
3257 */
3258 getEnd(): AnyPosition;
3259 /**
3260 * Compute the `SourceLocation` for this span, returned as an instance of `HbsSpan`.
3261 */
3262 toHbsSpan(): HbsSpan | null;
3263 /**
3264 * For compatibility, whenever the `start` or `end` of a {@see SourceOffset} changes, spans are
3265 * notified of the change so they can update themselves. This shouldn't happen outside of AST
3266 * plugins.
3267 */
3268 locDidUpdate(changes: {
3269 start?: SourcePosition;
3270 end?: SourcePosition;
3271 }): void;
3272 /**
3273 * Serialize into a {@see SerializedSourceSpan}, which is compact and designed for readability in
3274 * context like AST Explorer. If you need a {@see SourceLocation}, use {@see toJSON}.
3275 */
3276 serialize(): SerializedSourceSpan;
3277}
3278/**
3279 * A `SourceSpan` object represents a span of characters inside of a template source.
3280 *
3281 * There are three kinds of `SourceSpan` objects:
3282 *
3283 * - `ConcreteSourceSpan`, which contains byte offsets
3284 * - `LazySourceSpan`, which contains `SourceLocation`s from the Handlebars AST, which can be
3285 * converted to byte offsets on demand.
3286 * - `InvisibleSourceSpan`, which represent source strings that aren't present in the source,
3287 * because:
3288 * - they were created synthetically
3289 * - their location is nonsensical (the span is broken)
3290 * - they represent nothing in the source (this currently happens only when a bug in the
3291 * upstream Handlebars parser fails to assign a location to empty blocks)
3292 *
3293 * At a high level, all `SourceSpan` objects provide:
3294 *
3295 * - byte offsets
3296 * - source in column and line format
3297 *
3298 * And you can do these operations on `SourceSpan`s:
3299 *
3300 * - collapse it to a `SourceSpan` representing its starting or ending position
3301 * - slice out some characters, optionally skipping some characters at the beginning or end
3302 * - create a new `SourceSpan` with a different starting or ending offset
3303 *
3304 * All SourceSpan objects implement `SourceLocation`, for compatibility. All SourceSpan
3305 * objects have a `toJSON` that emits `SourceLocation`, also for compatibility.
3306 *
3307 * For compatibility, subclasses of `AbstractSourceSpan` must implement `locDidUpdate`, which
3308 * happens when an AST plugin attempts to modify the `start` or `end` of a span directly.
3309 *
3310 * The goal is to avoid creating any problems for use-cases like AST Explorer.
3311 */
3312declare class SourceSpan implements SourceLocation {
3313 private data;
3314 static get NON_EXISTENT(): SourceSpan;
3315 static load(source: Source, serialized: SerializedSourceSpan): SourceSpan;
3316 static forHbsLoc(source: Source, loc: SourceLocation): SourceSpan;
3317 static forCharPositions(source: Source, startPos: number, endPos: number): SourceSpan;
3318 static synthetic(chars: string): SourceSpan;
3319 static broken(pos?: SourceLocation): SourceSpan;
3320 readonly isInvisible: boolean;
3321 constructor(data: SpanData & AnySpan);
3322 getStart(): SourceOffset;
3323 getEnd(): SourceOffset;
3324 get loc(): SourceLocation;
3325 get module(): string;
3326 /**
3327 * Get the starting `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
3328 */
3329 get startPosition(): SourcePosition;
3330 /**
3331 * Get the ending `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
3332 */
3333 get endPosition(): SourcePosition;
3334 /**
3335 * Support converting ASTv1 nodes into a serialized format using JSON.stringify.
3336 */
3337 toJSON(): SourceLocation;
3338 /**
3339 * Create a new span with the current span's end and a new beginning.
3340 */
3341 withStart(other: SourceOffset): SourceSpan;
3342 /**
3343 * Create a new span with the current span's beginning and a new ending.
3344 */
3345 withEnd(other: SourceOffset): SourceSpan;
3346 asString(): string;
3347 /**
3348 * Convert this `SourceSpan` into a `SourceSlice`. In debug mode, this method optionally checks
3349 * that the byte offsets represented by this `SourceSpan` actually correspond to the expected
3350 * string.
3351 */
3352 toSlice(expected?: string): SourceSlice;
3353 /**
3354 * For compatibility with SourceLocation in AST plugins
3355 *
3356 * @deprecated use startPosition instead
3357 */
3358 get start(): SourcePosition;
3359 /**
3360 * For compatibility with SourceLocation in AST plugins
3361 *
3362 * @deprecated use withStart instead
3363 */
3364 set start(position: SourcePosition);
3365 /**
3366 * For compatibility with SourceLocation in AST plugins
3367 *
3368 * @deprecated use endPosition instead
3369 */
3370 get end(): SourcePosition;
3371 /**
3372 * For compatibility with SourceLocation in AST plugins
3373 *
3374 * @deprecated use withEnd instead
3375 */
3376 set end(position: SourcePosition);
3377 /**
3378 * For compatibility with SourceLocation in AST plugins
3379 *
3380 * @deprecated use module instead
3381 */
3382 get source(): string;
3383 collapse(where: "start" | "end"): SourceSpan;
3384 extend(other: SourceSpan): SourceSpan;
3385 serialize(): SerializedSourceSpan;
3386 slice({ skipStart, skipEnd }: {
3387 skipStart?: number;
3388 skipEnd?: number;
3389 }): SourceSpan;
3390 sliceStartChars({ skipStart, chars }: {
3391 skipStart?: number;
3392 chars: number;
3393 }): SourceSpan;
3394 sliceEndChars({ skipEnd, chars }: {
3395 skipEnd?: number;
3396 chars: number;
3397 }): SourceSpan;
3398}
3399type AnySpan = HbsSpan | CharPositionSpan | InvisibleSpan;
3400declare class CharPositionSpan implements SpanData {
3401 readonly source: Source;
3402 readonly charPositions: {
3403 start: CharPosition;
3404 end: CharPosition;
3405 };
3406 readonly kind = OffsetKind.CharPosition;
3407 _locPosSpan: HbsSpan | BROKEN | null;
3408 constructor(source: Source, charPositions: {
3409 start: CharPosition;
3410 end: CharPosition;
3411 });
3412 wrap(): SourceSpan;
3413 asString(): string;
3414 getModule(): string;
3415 getStart(): AnyPosition;
3416 getEnd(): AnyPosition;
3417 locDidUpdate(): void;
3418 toHbsSpan(): HbsSpan | null;
3419 serialize(): SerializedSourceSpan;
3420 toCharPosSpan(): CharPositionSpan;
3421}
3422declare class HbsSpan implements SpanData {
3423 readonly source: Source;
3424 readonly hbsPositions: {
3425 start: HbsPosition;
3426 end: HbsPosition;
3427 };
3428 readonly kind = OffsetKind.HbsPosition;
3429 _charPosSpan: CharPositionSpan | BROKEN | null;
3430 // the source location from Handlebars + AST Plugins -- could be wrong
3431 _providedHbsLoc: SourceLocation | null;
3432 constructor(source: Source, hbsPositions: {
3433 start: HbsPosition;
3434 end: HbsPosition;
3435 }, providedHbsLoc?: SourceLocation | null);
3436 serialize(): SerializedConcreteSourceSpan;
3437 wrap(): SourceSpan;
3438 private updateProvided;
3439 locDidUpdate({ start, end }: {
3440 start?: SourcePosition;
3441 end?: SourcePosition;
3442 }): void;
3443 asString(): string;
3444 getModule(): string;
3445 getStart(): AnyPosition;
3446 getEnd(): AnyPosition;
3447 toHbsLoc(): SourceLocation;
3448 toHbsSpan(): HbsSpan;
3449 toCharPosSpan(): CharPositionSpan | null;
3450}
3451declare class InvisibleSpan implements SpanData {
3452 readonly kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent;
3453 // whatever was provided, possibly broken
3454 readonly loc: SourceLocation;
3455 // if the span represents a synthetic string
3456 readonly string: string | null;
3457 constructor(kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent, loc: SourceLocation, string?: string | null);
3458 serialize(): SerializedConcreteSourceSpan;
3459 wrap(): SourceSpan;
3460 asString(): string;
3461 locDidUpdate({ start, end }: {
3462 start?: SourcePosition;
3463 end?: SourcePosition;
3464 }): void;
3465 getModule(): string;
3466 getStart(): AnyPosition;
3467 getEnd(): AnyPosition;
3468 toCharPosSpan(): InvisibleSpan;
3469 toHbsSpan(): null;
3470 toHbsLoc(): SourceLocation;
3471}
3472declare const span: MatchFn<SourceSpan>;
3473type SerializedConcreteSourceSpan = /** collapsed */ number | /** normal */ [
3474 start: number,
3475 size: number
3476] | /** synthetic */ string;
3477type SerializedSourceSpan = SerializedConcreteSourceSpan | OffsetKind.NonExistent | OffsetKind.Broken;
3478/**
3479 * All positions have these details in common. Most notably, all three kinds of positions can
3480 * must be able to attempt to convert themselves into {@see CharPosition}.
3481 */
3482interface PositionData {
3483 readonly kind: OffsetKind;
3484 toCharPos(): CharPosition | null;
3485 toJSON(): SourcePosition;
3486}
3487/**
3488 * Used to indicate that an attempt to convert a `SourcePosition` to a character offset failed. It
3489 * is separate from `null` so that `null` can be used to indicate that the computation wasn't yet
3490 * attempted (and therefore to cache the failure)
3491 */
3492declare const BROKEN = "BROKEN";
3493type BROKEN = "BROKEN";
3494type AnyPosition = HbsPosition | CharPosition | InvisiblePosition;
3495/**
3496 * A `SourceOffset` represents a single position in the source.
3497 *
3498 * There are three kinds of backing data for `SourceOffset` objects:
3499 *
3500 * - `CharPosition`, which contains a character offset into the raw source string
3501 * - `HbsPosition`, which contains a `SourcePosition` from the Handlebars AST, which can be
3502 * converted to a `CharPosition` on demand.
3503 * - `InvisiblePosition`, which represents a position not in source (@see {InvisiblePosition})
3504 */
3505declare class SourceOffset {
3506 readonly data: PositionData & AnyPosition;
3507 /**
3508 * Create a `SourceOffset` from a Handlebars `SourcePosition`. It's stored as-is, and converted
3509 * into a character offset on demand, which avoids unnecessarily computing the offset of every
3510 * `SourceLocation`, but also means that broken `SourcePosition`s are not always detected.
3511 */
3512 static forHbsPos(source: Source, pos: SourcePosition): SourceOffset;
3513 /**
3514 * Create a `SourceOffset` that corresponds to a broken `SourcePosition`. This means that the
3515 * calling code determined (or knows) that the `SourceLocation` doesn't correspond correctly to
3516 * any part of the source.
3517 */
3518 static broken(pos?: SourcePosition): SourceOffset;
3519 constructor(data: PositionData & AnyPosition);
3520 /**
3521 * Get the character offset for this `SourceOffset`, if possible.
3522 */
3523 get offset(): number | null;
3524 /**
3525 * Compare this offset with another one.
3526 *
3527 * If both offsets are `HbsPosition`s, they're equivalent as long as their lines and columns are
3528 * the same. This avoids computing offsets unnecessarily.
3529 *
3530 * Otherwise, two `SourceOffset`s are equivalent if their successfully computed character offsets
3531 * are the same.
3532 */
3533 eql(right: SourceOffset): boolean;
3534 /**
3535 * Create a span that starts from this source offset and ends with another source offset. Avoid
3536 * computing character offsets if both `SourceOffset`s are still lazy.
3537 */
3538 until(other: SourceOffset): SourceSpan;
3539 /**
3540 * Create a `SourceOffset` by moving the character position represented by this source offset
3541 * forward or backward (if `by` is negative), if possible.
3542 *
3543 * If this `SourceOffset` can't compute a valid character offset, `move` returns a broken offset.
3544 *
3545 * If the resulting character offset is less than 0 or greater than the size of the source, `move`
3546 * returns a broken offset.
3547 */
3548 move(by: number): SourceOffset;
3549 /**
3550 * Create a new `SourceSpan` that represents a collapsed range at this source offset. Avoid
3551 * computing the character offset if it has not already been computed.
3552 */
3553 collapsed(): SourceSpan;
3554 /**
3555 * Convert this `SourceOffset` into a Handlebars {@see SourcePosition} for compatibility with
3556 * existing plugins.
3557 */
3558 toJSON(): SourcePosition;
3559}
3560declare class CharPosition implements PositionData {
3561 readonly source: Source;
3562 readonly charPos: number;
3563 readonly kind = OffsetKind.CharPosition;
3564 /** Computed from char offset */
3565 _locPos: HbsPosition | BROKEN | null;
3566 constructor(source: Source, charPos: number);
3567 /**
3568 * This is already a `CharPosition`.
3569 *
3570 * {@see HbsPosition} for the alternative.
3571 */
3572 toCharPos(): CharPosition;
3573 /**
3574 * Produce a Handlebars {@see SourcePosition} for this `CharPosition`. If this `CharPosition` was
3575 * computed using {@see SourceOffset#move}, this will compute the `SourcePosition` for the offset.
3576 */
3577 toJSON(): SourcePosition;
3578 wrap(): SourceOffset;
3579 /**
3580 * A `CharPosition` always has an offset it can produce without any additional computation.
3581 */
3582 get offset(): number;
3583 /**
3584 * Convert the current character offset to an `HbsPosition`, if it was not already computed. Once
3585 * a `CharPosition` has computed its `HbsPosition`, it will not need to do compute it again, and
3586 * the same `CharPosition` is retained when used as one of the ends of a `SourceSpan`, so
3587 * computing the `HbsPosition` should be a one-time operation.
3588 */
3589 toHbsPos(): HbsPosition | null;
3590}
3591declare class HbsPosition implements PositionData {
3592 readonly source: Source;
3593 readonly hbsPos: SourcePosition;
3594 readonly kind = OffsetKind.HbsPosition;
3595 _charPos: CharPosition | BROKEN | null;
3596 constructor(source: Source, hbsPos: SourcePosition, charPos?: number | null);
3597 /**
3598 * Lazily compute the character offset from the {@see SourcePosition}. Once an `HbsPosition` has
3599 * computed its `CharPosition`, it will not need to do compute it again, and the same
3600 * `HbsPosition` is retained when used as one of the ends of a `SourceSpan`, so computing the
3601 * `CharPosition` should be a one-time operation.
3602 */
3603 toCharPos(): CharPosition | null;
3604 /**
3605 * Return the {@see SourcePosition} that this `HbsPosition` was instantiated with. This operation
3606 * does not need to compute anything.
3607 */
3608 toJSON(): SourcePosition;
3609 wrap(): SourceOffset;
3610 /**
3611 * This is already an `HbsPosition`.
3612 *
3613 * {@see CharPosition} for the alternative.
3614 */
3615 toHbsPos(): HbsPosition;
3616}
3617declare class InvisiblePosition implements PositionData {
3618 readonly kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent;
3619 // whatever was provided, possibly broken
3620 readonly pos: SourcePosition;
3621 constructor(kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent, pos: SourcePosition);
3622 /**
3623 * A broken position cannot be turned into a {@see CharacterPosition}.
3624 */
3625 toCharPos(): null;
3626 /**
3627 * The serialization of an `InvisiblePosition is whatever Handlebars {@see SourcePosition} was
3628 * originally identified as broken, non-existent or synthetic.
3629 *
3630 * If an `InvisiblePosition` never had an source offset at all, this method returns
3631 * {@see UNKNOWN_POSITION} for compatibility.
3632 */
3633 toJSON(): SourcePosition;
3634 wrap(): SourceOffset;
3635 get offset(): null;
3636}
3637interface SourceLocation {
3638 start: SourcePosition;
3639 end: SourcePosition;
3640}
3641interface SourcePosition {
3642 /** >= 1 */
3643 line: number;
3644 /** >= 0 */
3645 column: number;
3646}
3647type LocatedWithSpan = {
3648 offsets: SourceSpan;
3649};
3650type LocatedWithOptionalSpan = {
3651 offsets: SourceSpan | null;
3652};
3653type LocatedWithPositions = {
3654 loc: SourceLocation;
3655};
3656type LocatedWithOptionalPositions = {
3657 loc?: SourceLocation;
3658};
3659// const SOURCE = new Source('', '(tests)');
3660// Statements
3661type BuilderHead = string | ASTv1.CallableExpression;
3662type TagDescriptor = string | ASTv1.PathExpression | {
3663 path: ASTv1.PathExpression;
3664 selfClosing?: boolean;
3665} | {
3666 name: string;
3667 selfClosing?: boolean;
3668};
3669declare function buildMustache(path: BuilderHead | ASTv1.Literal, params?: ASTv1.Expression[], hash?: ASTv1.Hash, trusting?: boolean, loc?: SourceLocation, strip?: ASTv1.StripFlags): ASTv1.MustacheStatement;
3670type PossiblyDeprecatedBlock = ASTv1.Block | ASTv1.Template;
3671declare function buildBlock(path: BuilderHead, params: Nullable<ASTv1.Expression[]>, hash: Nullable<ASTv1.Hash>, _defaultBlock: PossiblyDeprecatedBlock, _elseBlock?: Nullable<PossiblyDeprecatedBlock>, loc?: SourceLocation, openStrip?: ASTv1.StripFlags, inverseStrip?: ASTv1.StripFlags, closeStrip?: ASTv1.StripFlags): ASTv1.BlockStatement;
3672declare function buildElementModifier(path: BuilderHead, params?: ASTv1.Expression[], hash?: ASTv1.Hash, loc?: Nullable<SourceLocation>): ASTv1.ElementModifierStatement;
3673declare function buildComment(value: string, loc?: SourceLocation): ASTv1.CommentStatement;
3674declare function buildMustacheComment(value: string, loc?: SourceLocation): ASTv1.MustacheCommentStatement;
3675declare function buildConcat(parts: (ASTv1.TextNode | ASTv1.MustacheStatement)[], loc?: SourceLocation): ASTv1.ConcatStatement;
3676type PathSexp = string | [
3677 "path",
3678 string,
3679 LocSexp?
3680];
3681type ModifierSexp = string | [
3682 PathSexp,
3683 LocSexp?
3684] | [
3685 PathSexp,
3686 ASTv1.Expression[],
3687 LocSexp?
3688] | [
3689 PathSexp,
3690 ASTv1.Expression[],
3691 Dict<ASTv1.Expression>,
3692 LocSexp?
3693];
3694type AttrSexp = [
3695 string,
3696 ASTv1.AttrNode["value"] | string,
3697 LocSexp?
3698];
3699type LocSexp = [
3700 "loc",
3701 SourceLocation
3702];
3703type ElementComment = ASTv1.MustacheCommentStatement | SourceLocation | string;
3704interface BuildElementOptions {
3705 attrs?: ASTv1.AttrNode[];
3706 modifiers?: ASTv1.ElementModifierStatement[];
3707 children?: ASTv1.Statement[];
3708 comments?: ASTv1.MustacheCommentStatement[];
3709 blockParams?: ASTv1.VarHead[] | string[];
3710 openTag?: SourceLocation;
3711 closeTag?: Nullable<SourceLocation>;
3712 loc?: SourceLocation;
3713}
3714declare function buildElement(tag: TagDescriptor, options?: BuildElementOptions): ASTv1.ElementNode;
3715declare function buildAttr(name: string, value: ASTv1.AttrValue, loc?: SourceLocation): ASTv1.AttrNode;
3716declare function buildText(chars?: string, loc?: SourceLocation): ASTv1.TextNode;
3717// Expressions
3718declare function buildSexpr(path: BuilderHead, params?: ASTv1.Expression[], hash?: ASTv1.Hash, loc?: SourceLocation): ASTv1.SubExpression;
3719declare function buildThis(loc?: SourceLocation): ASTv1.ThisHead;
3720declare function buildAtName(name: string, loc?: SourceLocation): ASTv1.AtHead;
3721declare function buildVar(name: string, loc?: SourceLocation): ASTv1.VarHead;
3722declare function buildHeadFromString(original: string, loc?: SourceLocation): ASTv1.PathHead;
3723declare function buildCleanPath(head: ASTv1.PathHead, tail?: string[], loc?: SourceLocation): ASTv1.PathExpression;
3724declare function buildPath(path: ASTv1.PathExpression | string | {
3725 head: string;
3726 tail: string[];
3727}, loc?: SourceLocation): ASTv1.PathExpression;
3728declare function buildPath(path: BuilderHead, loc?: SourceLocation): ASTv1.CallableExpression;
3729declare function buildPath(path: BuilderHead | ASTv1.Literal, loc?: SourceLocation): ASTv1.Expression;
3730declare function buildPath(path: ASTv1.Expression, loc?: SourceLocation): ASTv1.Expression;
3731declare function buildLiteral<T extends ASTv1.Literal>(type: T["type"], value: T["value"], loc?: SourceLocation): T;
3732// Miscellaneous
3733declare function buildHash(pairs?: ASTv1.HashPair[], loc?: SourceLocation): ASTv1.Hash;
3734declare function buildPair(key: string, value: ASTv1.Expression, loc?: SourceLocation): ASTv1.HashPair;
3735declare function buildProgram(body?: ASTv1.Statement[], blockParams?: string[], loc?: SourceLocation): ASTv1.Template | ASTv1.Block;
3736declare function buildBlockItself(body?: ASTv1.Statement[], params?: Array<ASTv1.VarHead | string>, chained?: boolean, loc?: SourceLocation): ASTv1.Block;
3737declare function buildTemplate(body?: ASTv1.Statement[], blockParams?: string[], loc?: SourceLocation): ASTv1.Template;
3738declare function buildPosition(line: number, column: number): SourcePosition;
3739declare function buildLoc(loc: Nullable<SourceLocation>): SourceSpan;
3740declare function buildLoc(startLine: number, startColumn: number, endLine?: number, endColumn?: number, source?: string): SourceSpan;
3741declare const _default: {
3742 mustache: typeof buildMustache;
3743 block: typeof buildBlock;
3744 comment: typeof buildComment;
3745 mustacheComment: typeof buildMustacheComment;
3746 element: typeof buildElement;
3747 elementModifier: typeof buildElementModifier;
3748 attr: typeof buildAttr;
3749 text: typeof buildText;
3750 sexpr: typeof buildSexpr;
3751 concat: typeof buildConcat;
3752 hash: typeof buildHash;
3753 pair: typeof buildPair;
3754 literal: typeof buildLiteral;
3755 program: typeof buildProgram;
3756 blockItself: typeof buildBlockItself;
3757 template: typeof buildTemplate;
3758 loc: typeof buildLoc;
3759 pos: typeof buildPosition;
3760 path: typeof buildPath;
3761 fullPath: typeof buildCleanPath;
3762 head: typeof buildHeadFromString;
3763 at: typeof buildAtName;
3764 var: typeof buildVar;
3765 this: typeof buildThis;
3766 string: (value: string) => ASTv1.StringLiteral;
3767 boolean: (value: boolean) => ASTv1.BooleanLiteral;
3768 number: (value: number) => ASTv1.NumberLiteral;
3769 undefined(): ASTv1.UndefinedLiteral;
3770 null(): ASTv1.NullLiteral;
3771};
3772declare const publicBuilder: typeof _default;
3773interface PendingError {
3774 mustache(span: SourceSpan): never;
3775 eof(offset: SourceOffset): never;
3776}
3777declare abstract class HandlebarsNodeVisitors extends Parser {
3778 // Because we interleave the HTML and HBS parsing, sometimes the HTML
3779 // tokenizer can run out of tokens when we switch into {{...}} or reached
3780 // EOF. There are positions where neither of these are expected, and it would
3781 // like to generate an error, but there is no span to attach the error to.
3782 // This allows the HTML tokenization to stash an error message and the next
3783 // mustache visitor will attach the message to the appropriate span and throw
3784 // the error.
3785 protected pendingError: Nullable<PendingError>;
3786 abstract appendToCommentData(s: string): void;
3787 abstract beginAttributeValue(quoted: boolean): void;
3788 abstract finishAttributeValue(): void;
3789 parse(program: HBS.Program, blockParams: string[]): ASTv1.Template;
3790 Program(program: HBS.Program, blockParams?: ASTv1.VarHead[]): ASTv1.Block;
3791 private parseProgram;
3792 BlockStatement(block: HBS.BlockStatement): ASTv1.BlockStatement | void;
3793 MustacheStatement(rawMustache: HBS.MustacheStatement): ASTv1.MustacheStatement | void;
3794 appendDynamicAttributeValuePart(part: ASTv1.MustacheStatement): void;
3795 finalizeTextPart(): void;
3796 startTextPart(): void;
3797 ContentStatement(content: HBS.ContentStatement): void;
3798 CommentStatement(rawComment: HBS.CommentStatement): Nullable<ASTv1.MustacheCommentStatement>;
3799 PartialStatement(partial: HBS.PartialStatement): never;
3800 PartialBlockStatement(partialBlock: HBS.PartialBlockStatement): never;
3801 Decorator(decorator: HBS.Decorator): never;
3802 DecoratorBlock(decoratorBlock: HBS.DecoratorBlock): never;
3803 SubExpression(sexpr: HBS.SubExpression): ASTv1.SubExpression;
3804 PathExpression(path: HBS.PathExpression): ASTv1.PathExpression;
3805 Hash(hash: HBS.Hash): ASTv1.Hash;
3806 StringLiteral(string: HBS.StringLiteral): ASTv1.StringLiteral;
3807 BooleanLiteral(boolean: HBS.BooleanLiteral): ASTv1.BooleanLiteral;
3808 NumberLiteral(number: HBS.NumberLiteral): ASTv1.NumberLiteral;
3809 UndefinedLiteral(undef: HBS.UndefinedLiteral): ASTv1.UndefinedLiteral;
3810 NullLiteral(nul: HBS.NullLiteral): ASTv1.NullLiteral;
3811}
3812/**
3813 ASTPlugins can make changes to the Glimmer template AST before
3814 compilation begins.
3815 */
3816interface ASTPluginBuilder<TEnv extends ASTPluginEnvironment = ASTPluginEnvironment> {
3817 (env: TEnv): ASTPlugin;
3818}
3819interface ASTPlugin {
3820 name: string;
3821 visitor: NodeVisitor;
3822}
3823interface ASTPluginEnvironment {
3824 meta?: object;
3825 syntax: Syntax;
3826}
3827interface HandlebarsParseOptions {
3828 srcName?: string;
3829 ignoreStandalone?: boolean;
3830}
3831interface TemplateIdFn {
3832 (src: string): Nullable<string>;
3833}
3834interface PrecompileOptions extends PreprocessOptions {
3835 id?: TemplateIdFn;
3836 /**
3837 * Additional non-native keywords.
3838 *
3839 * Local variables (block params or lexical scope) always takes precedence,
3840 * but otherwise, suitable free variable candidates (e.g. those are not part
3841 * of a path) are matched against this list and turned into keywords.
3842 *
3843 * In strict mode compilation, keywords suppresses the undefined reference
3844 * error and will be resolved by the runtime environment.
3845 *
3846 * In loose mode, keywords are currently ignored and since all free variables
3847 * are already resolved by the runtime environment.
3848 */
3849 keywords?: readonly string[];
3850 customizeComponentName?: ((input: string) => string) | undefined;
3851}
3852interface PrecompileOptionsWithLexicalScope extends PrecompileOptions {
3853 lexicalScope: (variable: string) => boolean;
3854}
3855interface PreprocessOptions {
3856 strictMode?: boolean;
3857 locals?: string[];
3858 meta?: {
3859 moduleName?: string;
3860 };
3861 plugins?: {
3862 ast?: ASTPluginBuilder[];
3863 };
3864 parseOptions?: HandlebarsParseOptions;
3865 customizeComponentName?: ((input: string) => string) | undefined;
3866 /**
3867 Useful for specifying a group of options together.
3868
3869 When `'codemod'` we disable all whitespace control in handlebars
3870 (to preserve as much as possible) and we also avoid any
3871 escaping/unescaping of HTML entity codes.
3872 */
3873 mode?: "codemod" | "precompile";
3874}
3875interface Syntax {
3876 parse: typeof preprocess;
3877 builders: typeof publicBuilder;
3878 print: typeof print;
3879 traverse: typeof traverse;
3880 Walker: typeof Walker;
3881}
3882declare function preprocess(input: string | src.Source | HBS.Program, options?: PreprocessOptions): ASTv1.Template;
3883declare class SpanList {
3884 static range(span: PresentArray<HasSourceSpan>): SourceSpan;
3885 static range(span: HasSourceSpan[], fallback: SourceSpan): SourceSpan;
3886 _span: SourceSpan[];
3887 constructor(span?: SourceSpan[]);
3888 add(offset: SourceSpan): void;
3889 getRangeOffset(fallback: SourceSpan): SourceSpan;
3890}
3891type HasSourceSpan = {
3892 loc: SourceSpan;
3893} | SourceSpan | [
3894 HasSourceSpan,
3895 ...HasSourceSpan[]
3896];
3897declare function loc(span: HasSourceSpan): SourceSpan;
3898type MaybeHasSourceSpan = {
3899 loc: SourceSpan;
3900} | SourceSpan | MaybeHasSourceSpan[];
3901declare function hasSpan(span: MaybeHasSourceSpan): span is HasSourceSpan;
3902declare function maybeLoc(location: MaybeHasSourceSpan, fallback: SourceSpan): SourceSpan;
3903declare namespace ASTv2 {
3904 type SerializedSourceSlice<Chars extends string = string> = [
3905 chars: Chars,
3906 span: src.SerializedSourceSpan
3907 ];
3908 class SourceSlice<Chars extends string = string> {
3909 static synthetic<S extends string>(chars: S): SourceSlice<S>;
3910 static load(source: src.Source, slice: SerializedSourceSlice): SourceSlice;
3911 readonly chars: Chars;
3912 readonly loc: src.SourceSpan;
3913 constructor(options: {
3914 loc: src.SourceSpan;
3915 chars: Chars;
3916 });
3917 getString(): string;
3918 serialize(): SerializedSourceSlice<Chars>;
3919 }
3920 interface SourceLocation {
3921 start: SourcePosition;
3922 end: SourcePosition;
3923 }
3924 interface SourcePosition {
3925 /** >= 1 */
3926 line: number;
3927 /** >= 0 */
3928 column: number;
3929 }
3930 const UNKNOWN_POSITION: Readonly<{
3931 readonly line: 1;
3932 readonly column: 0;
3933 }>;
3934 const SYNTHETIC_LOCATION: Readonly<{
3935 readonly source: "(synthetic)";
3936 readonly start: Readonly<{
3937 readonly line: 1;
3938 readonly column: 0;
3939 }>;
3940 readonly end: Readonly<{
3941 readonly line: 1;
3942 readonly column: 0;
3943 }>;
3944 }>;
3945 /** @deprecated */
3946 const SYNTHETIC: Readonly<{
3947 readonly source: "(synthetic)";
3948 readonly start: Readonly<{
3949 readonly line: 1;
3950 readonly column: 0;
3951 }>;
3952 readonly end: Readonly<{
3953 readonly line: 1;
3954 readonly column: 0;
3955 }>;
3956 }>;
3957 const TEMPORARY_LOCATION: Readonly<{
3958 readonly source: "(temporary)";
3959 readonly start: Readonly<{
3960 readonly line: 1;
3961 readonly column: 0;
3962 }>;
3963 readonly end: Readonly<{
3964 readonly line: 1;
3965 readonly column: 0;
3966 }>;
3967 }>;
3968 const NON_EXISTENT_LOCATION: Readonly<{
3969 readonly source: "(nonexistent)";
3970 readonly start: Readonly<{
3971 readonly line: 1;
3972 readonly column: 0;
3973 }>;
3974 readonly end: Readonly<{
3975 readonly line: 1;
3976 readonly column: 0;
3977 }>;
3978 }>;
3979 const BROKEN_LOCATION: Readonly<{
3980 readonly source: "(broken)";
3981 readonly start: Readonly<{
3982 readonly line: 1;
3983 readonly column: 0;
3984 }>;
3985 readonly end: Readonly<{
3986 readonly line: 1;
3987 readonly column: 0;
3988 }>;
3989 }>;
3990 type LocatedWithSpan = {
3991 offsets: SourceSpan;
3992 };
3993 type LocatedWithOptionalSpan = {
3994 offsets: SourceSpan | null;
3995 };
3996 type LocatedWithPositions = {
3997 loc: SourceLocation;
3998 };
3999 type LocatedWithOptionalPositions = {
4000 loc?: SourceLocation;
4001 };
4002 function isLocatedWithPositionsArray(location: LocatedWithOptionalPositions[]): location is PresentArray<LocatedWithPositions>;
4003 function isLocatedWithPositions(location: LocatedWithOptionalPositions): location is LocatedWithPositions;
4004 type HasSourceLocation = SourceLocation | LocatedWithPositions | PresentArray<LocatedWithPositions>;
4005 type MaybeHasSourceLocation = null | LocatedWithOptionalPositions | LocatedWithOptionalPositions[];
4006 type ParserNodeBuilder<N extends {
4007 loc: src.SourceSpan;
4008 }> = Omit<N, "loc"> & {
4009 start: src.SourceOffset;
4010 };
4011 interface StartTag {
4012 readonly type: "StartTag";
4013 name: string;
4014 nameStart: Nullable<src.SourceOffset>;
4015 nameEnd: Nullable<src.SourceOffset>;
4016 readonly attributes: ASTv1.AttrNode[];
4017 readonly modifiers: ASTv1.ElementModifierStatement[];
4018 readonly comments: ASTv1.MustacheCommentStatement[];
4019 readonly params: ASTv1.VarHead[];
4020 selfClosing: boolean;
4021 readonly loc: src.SourceSpan;
4022 }
4023 interface EndTag {
4024 readonly type: "EndTag";
4025 name: string;
4026 readonly loc: src.SourceSpan;
4027 }
4028 interface Attribute {
4029 name: string;
4030 currentPart: ASTv1.TextNode | null;
4031 parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[];
4032 isQuoted: boolean;
4033 isDynamic: boolean;
4034 start: src.SourceOffset;
4035 valueSpan: src.SourceSpan;
4036 }
4037 abstract class Parser {
4038 protected elementStack: ASTv1.ParentNode[];
4039 private lines;
4040 readonly source: src.Source;
4041 currentAttribute: Nullable<Attribute>;
4042 currentNode: Nullable<Readonly<ParserNodeBuilder<ASTv1.CommentStatement> | ParserNodeBuilder<ASTv1.TextNode> | ParserNodeBuilder<StartTag> | ParserNodeBuilder<EndTag>>>;
4043 tokenizer: EventedTokenizer;
4044 constructor(source: src.Source, entityParser?: EntityParser, mode?: "precompile" | "codemod");
4045 offset(): src.SourceOffset;
4046 pos({ line, column }: src.SourcePosition): src.SourceOffset;
4047 finish<T extends {
4048 loc: src.SourceSpan;
4049 }>(node: ParserNodeBuilder<T>): T;
4050 abstract parse(node: HBS.Program, locals: string[]): ASTv1.Template;
4051 abstract Program(node: HBS.Program): HBS.Output<"Program">;
4052 abstract MustacheStatement(node: HBS.MustacheStatement): HBS.Output<"MustacheStatement">;
4053 abstract Decorator(node: HBS.Decorator): HBS.Output<"Decorator">;
4054 abstract BlockStatement(node: HBS.BlockStatement): HBS.Output<"BlockStatement">;
4055 abstract DecoratorBlock(node: HBS.DecoratorBlock): HBS.Output<"DecoratorBlock">;
4056 abstract PartialStatement(node: HBS.PartialStatement): HBS.Output<"PartialStatement">;
4057 abstract PartialBlockStatement(node: HBS.PartialBlockStatement): HBS.Output<"PartialBlockStatement">;
4058 abstract ContentStatement(node: HBS.ContentStatement): HBS.Output<"ContentStatement">;
4059 abstract CommentStatement(node: HBS.CommentStatement): HBS.Output<"CommentStatement">;
4060 abstract SubExpression(node: HBS.SubExpression): HBS.Output<"SubExpression">;
4061 abstract PathExpression(node: HBS.PathExpression): HBS.Output<"PathExpression">;
4062 abstract StringLiteral(node: HBS.StringLiteral): HBS.Output<"StringLiteral">;
4063 abstract BooleanLiteral(node: HBS.BooleanLiteral): HBS.Output<"BooleanLiteral">;
4064 abstract NumberLiteral(node: HBS.NumberLiteral): HBS.Output<"NumberLiteral">;
4065 abstract UndefinedLiteral(node: HBS.UndefinedLiteral): HBS.Output<"UndefinedLiteral">;
4066 abstract NullLiteral(node: HBS.NullLiteral): HBS.Output<"NullLiteral">;
4067 abstract reset(): void;
4068 abstract finishData(): void;
4069 abstract tagOpen(): void;
4070 abstract beginData(): void;
4071 abstract appendToData(char: string): void;
4072 abstract beginStartTag(): void;
4073 abstract appendToTagName(char: string): void;
4074 abstract beginAttribute(): void;
4075 abstract appendToAttributeName(char: string): void;
4076 abstract beginAttributeValue(quoted: boolean): void;
4077 abstract appendToAttributeValue(char: string): void;
4078 abstract finishAttributeValue(): void;
4079 abstract markTagAsSelfClosing(): void;
4080 abstract beginEndTag(): void;
4081 abstract finishTag(): void;
4082 abstract beginComment(): void;
4083 abstract appendToCommentData(char: string): void;
4084 abstract finishComment(): void;
4085 abstract reportSyntaxError(error: string): void;
4086 get currentAttr(): Attribute;
4087 get currentTag(): ParserNodeBuilder<StartTag> | ParserNodeBuilder<EndTag>;
4088 get currentStartTag(): ParserNodeBuilder<StartTag>;
4089 get currentEndTag(): ParserNodeBuilder<EndTag>;
4090 get currentComment(): ParserNodeBuilder<ASTv1.CommentStatement>;
4091 get currentData(): ParserNodeBuilder<ASTv1.TextNode>;
4092 acceptNode<T extends HBS.NodeType>(node: HBS.Node<T>): HBS.Output<T>;
4093 currentElement(): ASTv1.ParentNode;
4094 sourceForNode(node: HBS.Node, endNode?: {
4095 loc: HBS.SourceLocation;
4096 }): string;
4097 }
4098 // ensure stays in sync with typing
4099 // ParentNode and ChildKey types are derived from VisitorKeysMap
4100 const visitorKeys: {
4101 readonly Template: readonly [
4102 "body"
4103 ];
4104 readonly Block: readonly [
4105 "body"
4106 ];
4107 readonly MustacheStatement: readonly [
4108 "path",
4109 "params",
4110 "hash"
4111 ];
4112 readonly BlockStatement: readonly [
4113 "path",
4114 "params",
4115 "hash",
4116 "program",
4117 "inverse"
4118 ];
4119 readonly ElementModifierStatement: readonly [
4120 "path",
4121 "params",
4122 "hash"
4123 ];
4124 readonly CommentStatement: readonly [
4125 ];
4126 readonly MustacheCommentStatement: readonly [
4127 ];
4128 readonly ElementNode: readonly [
4129 "attributes",
4130 "modifiers",
4131 "children",
4132 "comments"
4133 ];
4134 readonly AttrNode: readonly [
4135 "value"
4136 ];
4137 readonly TextNode: readonly [
4138 ];
4139 readonly ConcatStatement: readonly [
4140 "parts"
4141 ];
4142 readonly SubExpression: readonly [
4143 "path",
4144 "params",
4145 "hash"
4146 ];
4147 readonly PathExpression: readonly [
4148 ];
4149 readonly StringLiteral: readonly [
4150 ];
4151 readonly BooleanLiteral: readonly [
4152 ];
4153 readonly NumberLiteral: readonly [
4154 ];
4155 readonly NullLiteral: readonly [
4156 ];
4157 readonly UndefinedLiteral: readonly [
4158 ];
4159 readonly Hash: readonly [
4160 "pairs"
4161 ];
4162 readonly HashPair: readonly [
4163 "value"
4164 ];
4165 };
4166 type VisitorKeysMap = typeof visitorKeys;
4167 type VisitorKeys = {
4168 [P in keyof VisitorKeysMap]: VisitorKeysMap[P][number];
4169 };
4170 type VisitorKey<N extends ASTv1.Node> = VisitorKeys[N["type"]] & keyof N;
4171 class WalkerPath<N extends ASTv1.Node> {
4172 node: N;
4173 parent: WalkerPath<ASTv1.Node> | null;
4174 parentKey: string | null;
4175 constructor(node: N, parent?: WalkerPath<ASTv1.Node> | null, parentKey?: string | null);
4176 get parentNode(): ASTv1.Node | null;
4177 parents(): Iterable<WalkerPath<ASTv1.Node> | null>;
4178 }
4179 interface FullNodeTraversal<N extends ASTv1.Node> {
4180 enter?(node: N, path: WalkerPath<N>): void;
4181 exit?(node: N, path: WalkerPath<N>): void;
4182 keys?: KeysVisitor<N>;
4183 }
4184 type NodeHandler<N extends ASTv1.Node> = (node: N, path: WalkerPath<N>) => void;
4185 type NodeTraversal<N extends ASTv1.Node> = FullNodeTraversal<N> | NodeHandler<N>;
4186 type NodeVisitor = {
4187 [P in keyof ASTv1.Nodes]?: NodeTraversal<ASTv1.Nodes[P]>;
4188 } & {
4189 All?: NodeTraversal<ASTv1.Node>;
4190 /**
4191 * @deprecated use Template or Block instead
4192 */
4193 Program?: NodeTraversal<ASTv1.Template | ASTv1.Block>;
4194 };
4195 interface FullKeyTraversal<N extends ASTv1.Node, K extends string> {
4196 enter?(node: N, key: K): void;
4197 exit?(node: N, key: K): void;
4198 }
4199 type KeyHandler<N extends ASTv1.Node, K extends VisitorKey<N>> = (node: N, key: K) => void;
4200 type KeyTraversal<N extends ASTv1.Node, K extends VisitorKey<N>> = FullKeyTraversal<N, K> | KeyHandler<N, K>;
4201 type KeysVisitor<N extends ASTv1.Node> = {
4202 [P in VisitorKey<N>]?: KeyTraversal<N, P>;
4203 } & {
4204 All?: KeyTraversal<N, VisitorKey<N>>;
4205 /**
4206 * @deprecated use Template or Block instead
4207 */
4208 Program?: KeyTraversal<ASTv1.Template | ASTv1.Block, "body">;
4209 };
4210 const voidMap: Set<string>;
4211 function getVoidTags(): string[];
4212 interface PrinterOptions {
4213 entityEncoding: ASTv1.EntityEncodingState;
4214 /**
4215 * Used to override the mechanism of printing a given AST.Node.
4216 *
4217 * This will generally only be useful to source -> source codemods
4218 * where you would like to specialize/override the way a given node is
4219 * printed (e.g. you would like to preserve as much of the original
4220 * formatting as possible).
4221 *
4222 * When the provided override returns undefined, the default built in printing
4223 * will be done for the AST.Node.
4224 *
4225 * @param ast the ast node to be printed
4226 * @param options the options specified during the print() invocation
4227 */
4228 override?(ast: ASTv1.Node, options: PrinterOptions): void | string;
4229 }
4230 /**
4231 * Examples when true:
4232 * - link
4233 * - liNK
4234 *
4235 * Examples when false:
4236 * - Link (component)
4237 */
4238 function isVoidTag(tag: string): boolean;
4239 class Printer {
4240 private buffer;
4241 private options;
4242 constructor(options: PrinterOptions);
4243 /*
4244 This is used by _all_ methods on this Printer class that add to `this.buffer`,
4245 it allows consumers of the printer to use alternate string representations for
4246 a given node.
4247
4248 The primary use case for this are things like source -> source codemod utilities.
4249 For example, ember-template-recast attempts to always preserve the original string
4250 formatting in each AST node if no modifications are made to it.
4251 */
4252 handledByOverride(node: ASTv1.Node, ensureLeadingWhitespace?: boolean): boolean;
4253 Node(node: ASTv1.Node): void;
4254 Expression(expression: ASTv1.Expression): void;
4255 Literal(literal: ASTv1.Literal): void;
4256 TopLevelStatement(statement: ASTv1.TopLevelStatement | ASTv1.Template | ASTv1.AttrNode): void;
4257 Template(template: ASTv1.Template): void;
4258 Block(block: ASTv1.Block): void;
4259 TopLevelStatements(statements: ASTv1.TopLevelStatement[]): void;
4260 ElementNode(el: ASTv1.ElementNode): void;
4261 OpenElementNode(el: ASTv1.ElementNode): void;
4262 CloseElementNode(el: ASTv1.ElementNode): void;
4263 AttrNode(attr: ASTv1.AttrNode): void;
4264 AttrNodeValue(value: ASTv1.AttrNode["value"]): void;
4265 TextNode(text: ASTv1.TextNode, isAttr?: boolean): void;
4266 MustacheStatement(mustache: ASTv1.MustacheStatement): void;
4267 BlockStatement(block: ASTv1.BlockStatement): void;
4268 BlockParams(blockParams: string[]): void;
4269 ConcatStatement(concat: ASTv1.ConcatStatement): void;
4270 MustacheCommentStatement(comment: ASTv1.MustacheCommentStatement): void;
4271 ElementModifierStatement(mod: ASTv1.ElementModifierStatement): void;
4272 CommentStatement(comment: ASTv1.CommentStatement): void;
4273 PathExpression(path: ASTv1.PathExpression): void;
4274 SubExpression(sexp: ASTv1.SubExpression): void;
4275 Params(params: ASTv1.Expression[]): void;
4276 Hash(hash: ASTv1.Hash): void;
4277 HashPair(pair: ASTv1.HashPair): void;
4278 StringLiteral(str: ASTv1.StringLiteral): void;
4279 BooleanLiteral(bool: ASTv1.BooleanLiteral): void;
4280 NumberLiteral(number: ASTv1.NumberLiteral): void;
4281 UndefinedLiteral(node: ASTv1.UndefinedLiteral): void;
4282 NullLiteral(node: ASTv1.NullLiteral): void;
4283 print(node: ASTv1.Node): string;
4284 }
4285 function build(ast: ASTv1.Node, options?: PrinterOptions): string;
4286 const print: typeof build;
4287 function traverse(node: ASTv1.Node, visitor: NodeVisitor): void;
4288 type NodeCallback<N extends ASTv1.Node> = (node: N, walker: Walker) => void;
4289 class Walker {
4290 order?: unknown;
4291 stack: unknown[];
4292 constructor(order?: unknown);
4293 visit<N extends ASTv1.Node>(node: Nullable<N>, visitor: NodeCallback<N>): void;
4294 children<N extends ASTv1.Node>(node: N & ASTv1.Node, callback: NodeCallback<N & ASTv1.Node>): void;
4295 }
4296 // const SOURCE = new Source('', '(tests)');
4297 // Statements
4298 type BuilderHead = string | ASTv1.CallableExpression;
4299 type TagDescriptor = string | ASTv1.PathExpression | {
4300 path: ASTv1.PathExpression;
4301 selfClosing?: boolean;
4302 } | {
4303 name: string;
4304 selfClosing?: boolean;
4305 };
4306 function buildMustache(path: BuilderHead | ASTv1.Literal, params?: ASTv1.Expression[], hash?: ASTv1.Hash, trusting?: boolean, loc?: SourceLocation, strip?: ASTv1.StripFlags): ASTv1.MustacheStatement;
4307 type PossiblyDeprecatedBlock = ASTv1.Block | ASTv1.Template;
4308 function buildBlock(path: BuilderHead, params: Nullable<ASTv1.Expression[]>, hash: Nullable<ASTv1.Hash>, _defaultBlock: PossiblyDeprecatedBlock, _elseBlock?: Nullable<PossiblyDeprecatedBlock>, loc?: SourceLocation, openStrip?: ASTv1.StripFlags, inverseStrip?: ASTv1.StripFlags, closeStrip?: ASTv1.StripFlags): ASTv1.BlockStatement;
4309 function buildElementModifier(path: BuilderHead, params?: ASTv1.Expression[], hash?: ASTv1.Hash, loc?: Nullable<SourceLocation>): ASTv1.ElementModifierStatement;
4310 function buildComment(value: string, loc?: SourceLocation): ASTv1.CommentStatement;
4311 function buildMustacheComment(value: string, loc?: SourceLocation): ASTv1.MustacheCommentStatement;
4312 function buildConcat(parts: (ASTv1.TextNode | ASTv1.MustacheStatement)[], loc?: SourceLocation): ASTv1.ConcatStatement;
4313 // Nodes
4314 type ElementParts = [
4315 "attrs",
4316 ...AttrSexp[]
4317 ] | [
4318 "modifiers",
4319 ...ModifierSexp[]
4320 ] | [
4321 "body",
4322 ...ASTv1.Statement[]
4323 ] | [
4324 "comments",
4325 ...ElementComment[]
4326 ] | [
4327 "as",
4328 ...string[]
4329 ] | [
4330 "loc",
4331 SourceLocation
4332 ];
4333 type PathSexp = string | [
4334 "path",
4335 string,
4336 LocSexp?
4337 ];
4338 type ModifierSexp = string | [
4339 PathSexp,
4340 LocSexp?
4341 ] | [
4342 PathSexp,
4343 ASTv1.Expression[],
4344 LocSexp?
4345 ] | [
4346 PathSexp,
4347 ASTv1.Expression[],
4348 Dict<ASTv1.Expression>,
4349 LocSexp?
4350 ];
4351 type AttrSexp = [
4352 string,
4353 ASTv1.AttrNode["value"] | string,
4354 LocSexp?
4355 ];
4356 type LocSexp = [
4357 "loc",
4358 SourceLocation
4359 ];
4360 type ElementComment = ASTv1.MustacheCommentStatement | SourceLocation | string;
4361 type SexpValue = string | ASTv1.Expression[] | Dict<ASTv1.Expression> | LocSexp | PathSexp | undefined;
4362 interface BuildElementOptions {
4363 attrs?: ASTv1.AttrNode[];
4364 modifiers?: ASTv1.ElementModifierStatement[];
4365 children?: ASTv1.Statement[];
4366 comments?: ASTv1.MustacheCommentStatement[];
4367 blockParams?: ASTv1.VarHead[] | string[];
4368 openTag?: SourceLocation;
4369 closeTag?: Nullable<SourceLocation>;
4370 loc?: SourceLocation;
4371 }
4372 function buildElement(tag: TagDescriptor, options?: BuildElementOptions): ASTv1.ElementNode;
4373 function buildAttr(name: string, value: ASTv1.AttrValue, loc?: SourceLocation): ASTv1.AttrNode;
4374 function buildText(chars?: string, loc?: SourceLocation): ASTv1.TextNode;
4375 // Expressions
4376 function buildSexpr(path: BuilderHead, params?: ASTv1.Expression[], hash?: ASTv1.Hash, loc?: SourceLocation): ASTv1.SubExpression;
4377 function buildThis(loc?: SourceLocation): ASTv1.ThisHead;
4378 function buildAtName(name: string, loc?: SourceLocation): ASTv1.AtHead;
4379 function buildVar(name: string, loc?: SourceLocation): ASTv1.VarHead;
4380 function buildHeadFromString(original: string, loc?: SourceLocation): ASTv1.PathHead;
4381 function buildCleanPath(head: ASTv1.PathHead, tail?: string[], loc?: SourceLocation): ASTv1.PathExpression;
4382 function buildPath(path: ASTv1.PathExpression | string | {
4383 head: string;
4384 tail: string[];
4385 }, loc?: SourceLocation): ASTv1.PathExpression;
4386 function buildPath(path: BuilderHead, loc?: SourceLocation): ASTv1.CallableExpression;
4387 function buildPath(path: BuilderHead | ASTv1.Literal, loc?: SourceLocation): ASTv1.Expression;
4388 function buildPath(path: ASTv1.Expression, loc?: SourceLocation): ASTv1.Expression;
4389 function buildLiteral<T extends ASTv1.Literal>(type: T["type"], value: T["value"], loc?: SourceLocation): T;
4390 // Miscellaneous
4391 function buildHash(pairs?: ASTv1.HashPair[], loc?: SourceLocation): ASTv1.Hash;
4392 function buildPair(key: string, value: ASTv1.Expression, loc?: SourceLocation): ASTv1.HashPair;
4393 function buildProgram(body?: ASTv1.Statement[], blockParams?: string[], loc?: SourceLocation): ASTv1.Template | ASTv1.Block;
4394 function buildBlockItself(body?: ASTv1.Statement[], params?: Array<ASTv1.VarHead | string>, chained?: boolean, loc?: SourceLocation): ASTv1.Block;
4395 function buildTemplate(body?: ASTv1.Statement[], blockParams?: string[], loc?: SourceLocation): ASTv1.Template;
4396 function buildPosition(line: number, column: number): SourcePosition;
4397 function buildLoc(loc: Nullable<SourceLocation>): SourceSpan;
4398 function buildLoc(startLine: number, startColumn: number, endLine?: number, endColumn?: number, source?: string): SourceSpan;
4399 const _default: {
4400 mustache: typeof buildMustache;
4401 block: typeof buildBlock;
4402 comment: typeof buildComment;
4403 mustacheComment: typeof buildMustacheComment;
4404 element: typeof buildElement;
4405 elementModifier: typeof buildElementModifier;
4406 attr: typeof buildAttr;
4407 text: typeof buildText;
4408 sexpr: typeof buildSexpr;
4409 concat: typeof buildConcat;
4410 hash: typeof buildHash;
4411 pair: typeof buildPair;
4412 literal: typeof buildLiteral;
4413 program: typeof buildProgram;
4414 blockItself: typeof buildBlockItself;
4415 template: typeof buildTemplate;
4416 loc: typeof buildLoc;
4417 pos: typeof buildPosition;
4418 path: typeof buildPath;
4419 fullPath: typeof buildCleanPath;
4420 head: typeof buildHeadFromString;
4421 at: typeof buildAtName;
4422 var: typeof buildVar;
4423 this: typeof buildThis;
4424 string: (value: string) => ASTv1.StringLiteral;
4425 boolean: (value: boolean) => ASTv1.BooleanLiteral;
4426 number: (value: number) => ASTv1.NumberLiteral;
4427 undefined(): ASTv1.UndefinedLiteral;
4428 null(): ASTv1.NullLiteral;
4429 };
4430 const publicBuilder: typeof _default;
4431 interface PendingError {
4432 mustache(span: SourceSpan): never;
4433 eof(offset: SourceOffset): never;
4434 }
4435 abstract class HandlebarsNodeVisitors extends Parser {
4436 // Because we interleave the HTML and HBS parsing, sometimes the HTML
4437 // tokenizer can run out of tokens when we switch into {{...}} or reached
4438 // EOF. There are positions where neither of these are expected, and it would
4439 // like to generate an error, but there is no span to attach the error to.
4440 // This allows the HTML tokenization to stash an error message and the next
4441 // mustache visitor will attach the message to the appropriate span and throw
4442 // the error.
4443 protected pendingError: Nullable<PendingError>;
4444 abstract appendToCommentData(s: string): void;
4445 abstract beginAttributeValue(quoted: boolean): void;
4446 abstract finishAttributeValue(): void;
4447 parse(program: HBS.Program, blockParams: string[]): ASTv1.Template;
4448 Program(program: HBS.Program, blockParams?: ASTv1.VarHead[]): ASTv1.Block;
4449 private parseProgram;
4450 BlockStatement(block: HBS.BlockStatement): ASTv1.BlockStatement | void;
4451 MustacheStatement(rawMustache: HBS.MustacheStatement): ASTv1.MustacheStatement | void;
4452 appendDynamicAttributeValuePart(part: ASTv1.MustacheStatement): void;
4453 finalizeTextPart(): void;
4454 startTextPart(): void;
4455 ContentStatement(content: HBS.ContentStatement): void;
4456 CommentStatement(rawComment: HBS.CommentStatement): Nullable<ASTv1.MustacheCommentStatement>;
4457 PartialStatement(partial: HBS.PartialStatement): never;
4458 PartialBlockStatement(partialBlock: HBS.PartialBlockStatement): never;
4459 Decorator(decorator: HBS.Decorator): never;
4460 DecoratorBlock(decoratorBlock: HBS.DecoratorBlock): never;
4461 SubExpression(sexpr: HBS.SubExpression): ASTv1.SubExpression;
4462 PathExpression(path: HBS.PathExpression): ASTv1.PathExpression;
4463 Hash(hash: HBS.Hash): ASTv1.Hash;
4464 StringLiteral(string: HBS.StringLiteral): ASTv1.StringLiteral;
4465 BooleanLiteral(boolean: HBS.BooleanLiteral): ASTv1.BooleanLiteral;
4466 NumberLiteral(number: HBS.NumberLiteral): ASTv1.NumberLiteral;
4467 UndefinedLiteral(undef: HBS.UndefinedLiteral): ASTv1.UndefinedLiteral;
4468 NullLiteral(nul: HBS.NullLiteral): ASTv1.NullLiteral;
4469 }
4470 class TokenizerEventHandlers extends HandlebarsNodeVisitors {
4471 private tagOpenLine;
4472 private tagOpenColumn;
4473 reset(): void;
4474 // Comment
4475 beginComment(): void;
4476 appendToCommentData(char: string): void;
4477 finishComment(): void;
4478 // Data
4479 beginData(): void;
4480 appendToData(char: string): void;
4481 finishData(): void;
4482 // Tags - basic
4483 tagOpen(): void;
4484 beginStartTag(): void;
4485 beginEndTag(): void;
4486 finishTag(): void;
4487 finishStartTag(): void;
4488 finishEndTag(isVoid: boolean): void;
4489 markTagAsSelfClosing(): void;
4490 // Tags - name
4491 appendToTagName(char: string): void;
4492 // Tags - attributes
4493 beginAttribute(): void;
4494 appendToAttributeName(char: string): void;
4495 beginAttributeValue(isQuoted: boolean): void;
4496 appendToAttributeValue(char: string): void;
4497 finishAttributeValue(): void;
4498 private parsePossibleBlockParams;
4499 reportSyntaxError(message: string): void;
4500 assembleConcatenatedValue(parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[]): ASTv1.ConcatStatement;
4501 validateEndTag(tag: StartTag | EndTag, element: ASTv1.ElementNode, selfClosing: boolean): void;
4502 assembleAttributeValue(parts: ASTv1.AttrPart[], isQuoted: boolean, isDynamic: boolean, span: src.SourceSpan): ASTv1.AttrValue;
4503 }
4504 /**
4505 ASTPlugins can make changes to the Glimmer template AST before
4506 compilation begins.
4507 */
4508 interface ASTPluginBuilder<TEnv extends ASTPluginEnvironment = ASTPluginEnvironment> {
4509 (env: TEnv): ASTPlugin;
4510 }
4511 interface ASTPlugin {
4512 name: string;
4513 visitor: NodeVisitor;
4514 }
4515 interface ASTPluginEnvironment {
4516 meta?: object;
4517 syntax: Syntax;
4518 }
4519 interface HandlebarsParseOptions {
4520 srcName?: string;
4521 ignoreStandalone?: boolean;
4522 }
4523 interface TemplateIdFn {
4524 (src: string): Nullable<string>;
4525 }
4526 interface PrecompileOptions extends PreprocessOptions {
4527 id?: TemplateIdFn;
4528 /**
4529 * Additional non-native keywords.
4530 *
4531 * Local variables (block params or lexical scope) always takes precedence,
4532 * but otherwise, suitable free variable candidates (e.g. those are not part
4533 * of a path) are matched against this list and turned into keywords.
4534 *
4535 * In strict mode compilation, keywords suppresses the undefined reference
4536 * error and will be resolved by the runtime environment.
4537 *
4538 * In loose mode, keywords are currently ignored and since all free variables
4539 * are already resolved by the runtime environment.
4540 */
4541 keywords?: readonly string[];
4542 customizeComponentName?: ((input: string) => string) | undefined;
4543 }
4544 interface PrecompileOptionsWithLexicalScope extends PrecompileOptions {
4545 lexicalScope: (variable: string) => boolean;
4546 }
4547 interface PreprocessOptions {
4548 strictMode?: boolean;
4549 locals?: string[];
4550 meta?: {
4551 moduleName?: string;
4552 };
4553 plugins?: {
4554 ast?: ASTPluginBuilder[];
4555 };
4556 parseOptions?: HandlebarsParseOptions;
4557 customizeComponentName?: ((input: string) => string) | undefined;
4558 /**
4559 Useful for specifying a group of options together.
4560
4561 When `'codemod'` we disable all whitespace control in handlebars
4562 (to preserve as much as possible) and we also avoid any
4563 escaping/unescaping of HTML entity codes.
4564 */
4565 mode?: "codemod" | "precompile";
4566 }
4567 interface Syntax {
4568 parse: typeof preprocess;
4569 builders: typeof publicBuilder;
4570 print: typeof print;
4571 traverse: typeof traverse;
4572 Walker: typeof Walker;
4573 }
4574 function preprocess(input: string | src.Source | HBS.Program, options?: PreprocessOptions): ASTv1.Template;
4575 class Source {
4576 readonly source: string;
4577 readonly module: string;
4578 static from(source: string, options?: PrecompileOptions): Source;
4579 constructor(source: string, module?: string);
4580 /**
4581 * Validate that the character offset represents a position in the source string.
4582 */
4583 check(offset: number): boolean;
4584 slice(start: number, end: number): string;
4585 offsetFor(line: number, column: number): SourceOffset;
4586 spanFor({ start, end }: Readonly<SourceLocation>): SourceSpan;
4587 hbsPosFor(offset: number): Nullable<SourcePosition>;
4588 charPosFor(position: SourcePosition): number | null;
4589 }
4590 enum OffsetKind {
4591 /**
4592 * We have already computed the character position of this offset or span.
4593 */
4594 CharPosition = "CharPosition",
4595 /**
4596 * This offset or span was instantiated with a Handlebars SourcePosition or SourceLocation. Its
4597 * character position will be computed on demand.
4598 */
4599 HbsPosition = "HbsPosition",
4600 /**
4601 * for (rare) situations where a node is created but there was no source location (e.g. the name
4602 * "default" in default blocks when the word "default" never appeared in source). This is used
4603 * by the internals when there is a legitimate reason for the internals to synthesize a node
4604 * with no location.
4605 */
4606 InternalsSynthetic = "InternalsSynthetic",
4607 /**
4608 * For situations where a node represents zero parts of the source (for example, empty arguments).
4609 * In general, we attempt to assign these nodes *some* position (empty arguments can be
4610 * positioned immediately after the callee), but it's not always possible
4611 */
4612 NonExistent = "NonExistent",
4613 /**
4614 * For situations where a source location was expected, but it didn't correspond to the node in
4615 * the source. This happens if a plugin creates broken locations.
4616 */
4617 Broken = "Broken"
4618 }
4619 /**
4620 * This file implements the DSL used by span and offset in places where they need to exhaustively
4621 * consider all combinations of states (Handlebars offsets, character offsets and invisible/broken
4622 * offsets).
4623 *
4624 * It's probably overkill, but it makes the code that uses it clear. It could be refactored or
4625 * removed.
4626 */
4627 const MatchAny = "MATCH_ANY";
4628 type MatchAny = "MATCH_ANY";
4629 type Matches = "Char,Hbs" | "Hbs,Char" | "Hbs,Hbs" | "Char,Char" | "Invisible,Any" | "Any,Invisible";
4630 const IsInvisible = "IS_INVISIBLE";
4631 type IsInvisible = "IS_INVISIBLE";
4632 type Pattern = OffsetKind | IsInvisible | MatchAny;
4633 class When<Out> {
4634 _map: Map<Pattern, Out>;
4635 get(pattern: Pattern, or: () => Out): Out;
4636 add(pattern: Pattern, out: Out): void;
4637 match(kind: OffsetKind): Out[];
4638 }
4639 type ExhaustiveCheck<Out, In extends Matches, Removed extends Matches> = Exclude<In, Removed> extends never ? ExhaustiveMatcher<Out> : Matcher<Out, Exclude<In, Removed>>;
4640 type MatchFn<Out> = (left: PositionData, right: PositionData) => Out;
4641 interface ExhaustiveMatcher<Out> {
4642 check(): MatchFn<Out>;
4643 }
4644 function match<Out>(callback: (m: Matcher<Out>) => ExhaustiveMatcher<Out>): MatchFn<Out>;
4645 class Matcher<Out, M extends Matches = Matches> {
4646 _whens: When<When<(left: PositionData, right: PositionData) => Out>>;
4647 /**
4648 * You didn't exhaustively match all possibilities.
4649 */
4650 protected check(): MatchFn<Out>;
4651 private matchFor;
4652 // This big block is the bulk of the heavy lifting in this file. It facilitates exhaustiveness
4653 // checking so that matchers can ensure they've actually covered all the cases (and TypeScript
4654 // will treat it as an exhaustive match).
4655 when(left: OffsetKind.CharPosition, right: OffsetKind.HbsPosition, callback: (left: CharPosition, right: HbsPosition) => Out): ExhaustiveCheck<Out, M, "Char,Hbs">;
4656 when(left: OffsetKind.HbsPosition, right: OffsetKind.CharPosition, callback: (left: HbsPosition, right: CharPosition) => Out): ExhaustiveCheck<Out, M, "Hbs,Char">;
4657 when(left: OffsetKind.HbsPosition, right: OffsetKind.HbsPosition, callback: (left: HbsPosition, right: HbsPosition) => Out): ExhaustiveCheck<Out, M, "Hbs,Hbs">;
4658 when(left: OffsetKind.CharPosition, right: OffsetKind.CharPosition, callback: (left: CharPosition, right: CharPosition) => Out): ExhaustiveCheck<Out, M, "Char,Char">;
4659 when(left: IsInvisible, right: MatchAny, callback: (left: InvisiblePosition, right: PositionData) => Out): Matcher<Out, Exclude<M, "Invisible,Any">>;
4660 when(left: MatchAny, right: IsInvisible, callback: (left: PositionData, right: InvisiblePosition) => Out): ExhaustiveCheck<Out, M, "Any,Invisible">;
4661 when(left: MatchAny, right: MatchAny, callback: (left: PositionData, right: PositionData) => Out): ExhaustiveMatcher<Out>;
4662 }
4663 /**
4664 * All spans have these details in common.
4665 */
4666 interface SpanData {
4667 readonly kind: OffsetKind;
4668 /**
4669 * Convert this span into a string. If the span is broken, return `''`.
4670 */
4671 asString(): string;
4672 /**
4673 * Gets the module the span was located in.
4674 */
4675 getModule(): string;
4676 /**
4677 * Get the starting position for this span. Try to avoid creating new position objects, as they
4678 * cache computations.
4679 */
4680 getStart(): AnyPosition;
4681 /**
4682 * Get the ending position for this span. Try to avoid creating new position objects, as they
4683 * cache computations.
4684 */
4685 getEnd(): AnyPosition;
4686 /**
4687 * Compute the `SourceLocation` for this span, returned as an instance of `HbsSpan`.
4688 */
4689 toHbsSpan(): HbsSpan | null;
4690 /**
4691 * For compatibility, whenever the `start` or `end` of a {@see SourceOffset} changes, spans are
4692 * notified of the change so they can update themselves. This shouldn't happen outside of AST
4693 * plugins.
4694 */
4695 locDidUpdate(changes: {
4696 start?: SourcePosition;
4697 end?: SourcePosition;
4698 }): void;
4699 /**
4700 * Serialize into a {@see SerializedSourceSpan}, which is compact and designed for readability in
4701 * context like AST Explorer. If you need a {@see SourceLocation}, use {@see toJSON}.
4702 */
4703 serialize(): SerializedSourceSpan;
4704 }
4705 /**
4706 * A `SourceSpan` object represents a span of characters inside of a template source.
4707 *
4708 * There are three kinds of `SourceSpan` objects:
4709 *
4710 * - `ConcreteSourceSpan`, which contains byte offsets
4711 * - `LazySourceSpan`, which contains `SourceLocation`s from the Handlebars AST, which can be
4712 * converted to byte offsets on demand.
4713 * - `InvisibleSourceSpan`, which represent source strings that aren't present in the source,
4714 * because:
4715 * - they were created synthetically
4716 * - their location is nonsensical (the span is broken)
4717 * - they represent nothing in the source (this currently happens only when a bug in the
4718 * upstream Handlebars parser fails to assign a location to empty blocks)
4719 *
4720 * At a high level, all `SourceSpan` objects provide:
4721 *
4722 * - byte offsets
4723 * - source in column and line format
4724 *
4725 * And you can do these operations on `SourceSpan`s:
4726 *
4727 * - collapse it to a `SourceSpan` representing its starting or ending position
4728 * - slice out some characters, optionally skipping some characters at the beginning or end
4729 * - create a new `SourceSpan` with a different starting or ending offset
4730 *
4731 * All SourceSpan objects implement `SourceLocation`, for compatibility. All SourceSpan
4732 * objects have a `toJSON` that emits `SourceLocation`, also for compatibility.
4733 *
4734 * For compatibility, subclasses of `AbstractSourceSpan` must implement `locDidUpdate`, which
4735 * happens when an AST plugin attempts to modify the `start` or `end` of a span directly.
4736 *
4737 * The goal is to avoid creating any problems for use-cases like AST Explorer.
4738 */
4739 class SourceSpan implements SourceLocation {
4740 private data;
4741 static get NON_EXISTENT(): SourceSpan;
4742 static load(source: Source, serialized: SerializedSourceSpan): SourceSpan;
4743 static forHbsLoc(source: Source, loc: SourceLocation): SourceSpan;
4744 static forCharPositions(source: Source, startPos: number, endPos: number): SourceSpan;
4745 static synthetic(chars: string): SourceSpan;
4746 static broken(pos?: SourceLocation): SourceSpan;
4747 readonly isInvisible: boolean;
4748 constructor(data: SpanData & AnySpan);
4749 getStart(): SourceOffset;
4750 getEnd(): SourceOffset;
4751 get loc(): SourceLocation;
4752 get module(): string;
4753 /**
4754 * Get the starting `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
4755 */
4756 get startPosition(): SourcePosition;
4757 /**
4758 * Get the ending `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
4759 */
4760 get endPosition(): SourcePosition;
4761 /**
4762 * Support converting ASTv1 nodes into a serialized format using JSON.stringify.
4763 */
4764 toJSON(): SourceLocation;
4765 /**
4766 * Create a new span with the current span's end and a new beginning.
4767 */
4768 withStart(other: SourceOffset): SourceSpan;
4769 /**
4770 * Create a new span with the current span's beginning and a new ending.
4771 */
4772 withEnd(other: SourceOffset): SourceSpan;
4773 asString(): string;
4774 /**
4775 * Convert this `SourceSpan` into a `SourceSlice`. In debug mode, this method optionally checks
4776 * that the byte offsets represented by this `SourceSpan` actually correspond to the expected
4777 * string.
4778 */
4779 toSlice(expected?: string): SourceSlice;
4780 /**
4781 * For compatibility with SourceLocation in AST plugins
4782 *
4783 * @deprecated use startPosition instead
4784 */
4785 get start(): SourcePosition;
4786 /**
4787 * For compatibility with SourceLocation in AST plugins
4788 *
4789 * @deprecated use withStart instead
4790 */
4791 set start(position: SourcePosition);
4792 /**
4793 * For compatibility with SourceLocation in AST plugins
4794 *
4795 * @deprecated use endPosition instead
4796 */
4797 get end(): SourcePosition;
4798 /**
4799 * For compatibility with SourceLocation in AST plugins
4800 *
4801 * @deprecated use withEnd instead
4802 */
4803 set end(position: SourcePosition);
4804 /**
4805 * For compatibility with SourceLocation in AST plugins
4806 *
4807 * @deprecated use module instead
4808 */
4809 get source(): string;
4810 collapse(where: "start" | "end"): SourceSpan;
4811 extend(other: SourceSpan): SourceSpan;
4812 serialize(): SerializedSourceSpan;
4813 slice({ skipStart, skipEnd }: {
4814 skipStart?: number;
4815 skipEnd?: number;
4816 }): SourceSpan;
4817 sliceStartChars({ skipStart, chars }: {
4818 skipStart?: number;
4819 chars: number;
4820 }): SourceSpan;
4821 sliceEndChars({ skipEnd, chars }: {
4822 skipEnd?: number;
4823 chars: number;
4824 }): SourceSpan;
4825 }
4826 type AnySpan = HbsSpan | CharPositionSpan | InvisibleSpan;
4827 class CharPositionSpan implements SpanData {
4828 readonly source: Source;
4829 readonly charPositions: {
4830 start: CharPosition;
4831 end: CharPosition;
4832 };
4833 readonly kind = OffsetKind.CharPosition;
4834 _locPosSpan: HbsSpan | BROKEN | null;
4835 constructor(source: Source, charPositions: {
4836 start: CharPosition;
4837 end: CharPosition;
4838 });
4839 wrap(): SourceSpan;
4840 asString(): string;
4841 getModule(): string;
4842 getStart(): AnyPosition;
4843 getEnd(): AnyPosition;
4844 locDidUpdate(): void;
4845 toHbsSpan(): HbsSpan | null;
4846 serialize(): SerializedSourceSpan;
4847 toCharPosSpan(): CharPositionSpan;
4848 }
4849 class HbsSpan implements SpanData {
4850 readonly source: Source;
4851 readonly hbsPositions: {
4852 start: HbsPosition;
4853 end: HbsPosition;
4854 };
4855 readonly kind = OffsetKind.HbsPosition;
4856 _charPosSpan: CharPositionSpan | BROKEN | null;
4857 // the source location from Handlebars + AST Plugins -- could be wrong
4858 _providedHbsLoc: SourceLocation | null;
4859 constructor(source: Source, hbsPositions: {
4860 start: HbsPosition;
4861 end: HbsPosition;
4862 }, providedHbsLoc?: SourceLocation | null);
4863 serialize(): SerializedConcreteSourceSpan;
4864 wrap(): SourceSpan;
4865 private updateProvided;
4866 locDidUpdate({ start, end }: {
4867 start?: SourcePosition;
4868 end?: SourcePosition;
4869 }): void;
4870 asString(): string;
4871 getModule(): string;
4872 getStart(): AnyPosition;
4873 getEnd(): AnyPosition;
4874 toHbsLoc(): SourceLocation;
4875 toHbsSpan(): HbsSpan;
4876 toCharPosSpan(): CharPositionSpan | null;
4877 }
4878 class InvisibleSpan implements SpanData {
4879 readonly kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent;
4880 // whatever was provided, possibly broken
4881 readonly loc: SourceLocation;
4882 // if the span represents a synthetic string
4883 readonly string: string | null;
4884 constructor(kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent, loc: SourceLocation, string?: string | null);
4885 serialize(): SerializedConcreteSourceSpan;
4886 wrap(): SourceSpan;
4887 asString(): string;
4888 locDidUpdate({ start, end }: {
4889 start?: SourcePosition;
4890 end?: SourcePosition;
4891 }): void;
4892 getModule(): string;
4893 getStart(): AnyPosition;
4894 getEnd(): AnyPosition;
4895 toCharPosSpan(): InvisibleSpan;
4896 toHbsSpan(): null;
4897 toHbsLoc(): SourceLocation;
4898 }
4899 const span: MatchFn<SourceSpan>;
4900 type SerializedConcreteSourceSpan = /** collapsed */ number | /** normal */ [
4901 start: number,
4902 size: number
4903 ] | /** synthetic */ string;
4904 type SerializedSourceSpan = SerializedConcreteSourceSpan | OffsetKind.NonExistent | OffsetKind.Broken;
4905 /**
4906 * All positions have these details in common. Most notably, all three kinds of positions can
4907 * must be able to attempt to convert themselves into {@see CharPosition}.
4908 */
4909 interface PositionData {
4910 readonly kind: OffsetKind;
4911 toCharPos(): CharPosition | null;
4912 toJSON(): SourcePosition;
4913 }
4914 /**
4915 * Used to indicate that an attempt to convert a `SourcePosition` to a character offset failed. It
4916 * is separate from `null` so that `null` can be used to indicate that the computation wasn't yet
4917 * attempted (and therefore to cache the failure)
4918 */
4919 const BROKEN = "BROKEN";
4920 type BROKEN = "BROKEN";
4921 type AnyPosition = HbsPosition | CharPosition | InvisiblePosition;
4922 /**
4923 * A `SourceOffset` represents a single position in the source.
4924 *
4925 * There are three kinds of backing data for `SourceOffset` objects:
4926 *
4927 * - `CharPosition`, which contains a character offset into the raw source string
4928 * - `HbsPosition`, which contains a `SourcePosition` from the Handlebars AST, which can be
4929 * converted to a `CharPosition` on demand.
4930 * - `InvisiblePosition`, which represents a position not in source (@see {InvisiblePosition})
4931 */
4932 class SourceOffset {
4933 readonly data: PositionData & AnyPosition;
4934 /**
4935 * Create a `SourceOffset` from a Handlebars `SourcePosition`. It's stored as-is, and converted
4936 * into a character offset on demand, which avoids unnecessarily computing the offset of every
4937 * `SourceLocation`, but also means that broken `SourcePosition`s are not always detected.
4938 */
4939 static forHbsPos(source: Source, pos: SourcePosition): SourceOffset;
4940 /**
4941 * Create a `SourceOffset` that corresponds to a broken `SourcePosition`. This means that the
4942 * calling code determined (or knows) that the `SourceLocation` doesn't correspond correctly to
4943 * any part of the source.
4944 */
4945 static broken(pos?: SourcePosition): SourceOffset;
4946 constructor(data: PositionData & AnyPosition);
4947 /**
4948 * Get the character offset for this `SourceOffset`, if possible.
4949 */
4950 get offset(): number | null;
4951 /**
4952 * Compare this offset with another one.
4953 *
4954 * If both offsets are `HbsPosition`s, they're equivalent as long as their lines and columns are
4955 * the same. This avoids computing offsets unnecessarily.
4956 *
4957 * Otherwise, two `SourceOffset`s are equivalent if their successfully computed character offsets
4958 * are the same.
4959 */
4960 eql(right: SourceOffset): boolean;
4961 /**
4962 * Create a span that starts from this source offset and ends with another source offset. Avoid
4963 * computing character offsets if both `SourceOffset`s are still lazy.
4964 */
4965 until(other: SourceOffset): SourceSpan;
4966 /**
4967 * Create a `SourceOffset` by moving the character position represented by this source offset
4968 * forward or backward (if `by` is negative), if possible.
4969 *
4970 * If this `SourceOffset` can't compute a valid character offset, `move` returns a broken offset.
4971 *
4972 * If the resulting character offset is less than 0 or greater than the size of the source, `move`
4973 * returns a broken offset.
4974 */
4975 move(by: number): SourceOffset;
4976 /**
4977 * Create a new `SourceSpan` that represents a collapsed range at this source offset. Avoid
4978 * computing the character offset if it has not already been computed.
4979 */
4980 collapsed(): SourceSpan;
4981 /**
4982 * Convert this `SourceOffset` into a Handlebars {@see SourcePosition} for compatibility with
4983 * existing plugins.
4984 */
4985 toJSON(): SourcePosition;
4986 }
4987 class CharPosition implements PositionData {
4988 readonly source: Source;
4989 readonly charPos: number;
4990 readonly kind = OffsetKind.CharPosition;
4991 /** Computed from char offset */
4992 _locPos: HbsPosition | BROKEN | null;
4993 constructor(source: Source, charPos: number);
4994 /**
4995 * This is already a `CharPosition`.
4996 *
4997 * {@see HbsPosition} for the alternative.
4998 */
4999 toCharPos(): CharPosition;
5000 /**
5001 * Produce a Handlebars {@see SourcePosition} for this `CharPosition`. If this `CharPosition` was
5002 * computed using {@see SourceOffset#move}, this will compute the `SourcePosition` for the offset.
5003 */
5004 toJSON(): SourcePosition;
5005 wrap(): SourceOffset;
5006 /**
5007 * A `CharPosition` always has an offset it can produce without any additional computation.
5008 */
5009 get offset(): number;
5010 /**
5011 * Convert the current character offset to an `HbsPosition`, if it was not already computed. Once
5012 * a `CharPosition` has computed its `HbsPosition`, it will not need to do compute it again, and
5013 * the same `CharPosition` is retained when used as one of the ends of a `SourceSpan`, so
5014 * computing the `HbsPosition` should be a one-time operation.
5015 */
5016 toHbsPos(): HbsPosition | null;
5017 }
5018 class HbsPosition implements PositionData {
5019 readonly source: Source;
5020 readonly hbsPos: SourcePosition;
5021 readonly kind = OffsetKind.HbsPosition;
5022 _charPos: CharPosition | BROKEN | null;
5023 constructor(source: Source, hbsPos: SourcePosition, charPos?: number | null);
5024 /**
5025 * Lazily compute the character offset from the {@see SourcePosition}. Once an `HbsPosition` has
5026 * computed its `CharPosition`, it will not need to do compute it again, and the same
5027 * `HbsPosition` is retained when used as one of the ends of a `SourceSpan`, so computing the
5028 * `CharPosition` should be a one-time operation.
5029 */
5030 toCharPos(): CharPosition | null;
5031 /**
5032 * Return the {@see SourcePosition} that this `HbsPosition` was instantiated with. This operation
5033 * does not need to compute anything.
5034 */
5035 toJSON(): SourcePosition;
5036 wrap(): SourceOffset;
5037 /**
5038 * This is already an `HbsPosition`.
5039 *
5040 * {@see CharPosition} for the alternative.
5041 */
5042 toHbsPos(): HbsPosition;
5043 }
5044 class InvisiblePosition implements PositionData {
5045 readonly kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent;
5046 // whatever was provided, possibly broken
5047 readonly pos: SourcePosition;
5048 constructor(kind: OffsetKind.Broken | OffsetKind.InternalsSynthetic | OffsetKind.NonExistent, pos: SourcePosition);
5049 /**
5050 * A broken position cannot be turned into a {@see CharacterPosition}.
5051 */
5052 toCharPos(): null;
5053 /**
5054 * The serialization of an `InvisiblePosition is whatever Handlebars {@see SourcePosition} was
5055 * originally identified as broken, non-existent or synthetic.
5056 *
5057 * If an `InvisiblePosition` never had an source offset at all, this method returns
5058 * {@see UNKNOWN_POSITION} for compatibility.
5059 */
5060 toJSON(): SourcePosition;
5061 wrap(): SourceOffset;
5062 get offset(): null;
5063 }
5064 /**
5065 * Attr nodes look like HTML attributes, but are classified as:
5066 *
5067 * 1. `HtmlAttr`, which means a regular HTML attribute in Glimmer
5068 * 2. `SplatAttr`, which means `...attributes`
5069 * 3. `ComponentArg`, which means an attribute whose name begins with `@`, and it is therefore a
5070 * component argument.
5071 */
5072 type AttrNode = HtmlAttr | SplatAttr | ComponentArg;
5073 /**
5074 * `HtmlAttr` and `SplatAttr` are grouped together because the order of the `SplatAttr` node,
5075 * relative to other attributes, matters.
5076 */
5077 type HtmlOrSplatAttr = HtmlAttr | SplatAttr;
5078 /**
5079 * "Attr Block" nodes are allowed inside an open element tag in templates. They interact with the
5080 * element (or component).
5081 */
5082 type AttrBlockNode = AttrNode | ElementModifier;
5083 interface BaseNodeFields {
5084 loc: SourceSpan;
5085 }
5086 /**
5087 * This is a convenience function for creating ASTv2 nodes, with an optional name and the node's
5088 * options.
5089 *
5090 * ```ts
5091 * export class HtmlText extends node('HtmlText').fields<{ chars: string }>() {}
5092 * ```
5093 *
5094 * This creates a new ASTv2 node with the name `'HtmlText'` and one field `chars: string` (in
5095 * addition to a `loc: SourceOffsets` field, which all nodes have).
5096 *
5097 * ```ts
5098 * export class Args extends node().fields<{
5099 * positional: PositionalArguments;
5100 * named: NamedArguments
5101 * }>() {}
5102 * ```
5103 *
5104 * This creates a new un-named ASTv2 node with two fields (`positional: Positional` and `named:
5105 * Named`, in addition to the generic `loc: SourceOffsets` field).
5106 *
5107 * Once you create a node using `node`, it is instantiated with all of its fields (including `loc`):
5108 *
5109 * ```ts
5110 * new HtmlText({ loc: offsets, chars: someString });
5111 * ```
5112 */
5113 function node(): {
5114 fields<Fields extends object>(): NodeConstructor<Fields & BaseNodeFields>;
5115 };
5116 function node<T extends string>(name: T): {
5117 fields<Fields extends object>(): TypedNodeConstructor<T, Fields & BaseNodeFields>;
5118 };
5119 interface NodeConstructor<Fields> {
5120 new (fields: Fields): Readonly<Fields>;
5121 }
5122 type TypedNode<T extends string, Fields> = {
5123 type: T;
5124 } & Readonly<Fields>;
5125 interface TypedNodeConstructor<T extends string, Fields> {
5126 new (options: Fields): TypedNode<T, Fields>;
5127 }
5128 const HtmlAttr_base: TypedNodeConstructor<"HtmlAttr", AttrNodeOptions & BaseNodeFields>;
5129 /**
5130 * `HtmlAttr` nodes are valid HTML attributes, with or without a value.
5131 *
5132 * Exceptions:
5133 *
5134 * - `...attributes` is `SplatAttr`
5135 * - `@x=<value>` is `ComponentArg`
5136 */
5137 class HtmlAttr extends HtmlAttr_base {
5138 }
5139 const SplatAttr_base: TypedNodeConstructor<"SplatAttr", {
5140 symbol: number;
5141 } & BaseNodeFields>;
5142 class SplatAttr extends SplatAttr_base {
5143 }
5144 const ComponentArg_base: NodeConstructor<AttrNodeOptions & BaseNodeFields>;
5145 /**
5146 * Corresponds to an argument passed by a component (`@x=<value>`)
5147 */
5148 class ComponentArg extends ComponentArg_base {
5149 /**
5150 * Convert the component argument into a named argument node
5151 */
5152 toNamedArgument(): NamedArgument;
5153 }
5154 const ElementModifier_base: TypedNodeConstructor<"ElementModifier", CallFields & BaseNodeFields>;
5155 /**
5156 * An `ElementModifier` is just a normal call node in modifier position.
5157 */
5158 class ElementModifier extends ElementModifier_base {
5159 }
5160 interface AttrNodeOptions {
5161 name: SourceSlice;
5162 value: ExpressionNode;
5163 trusting: boolean;
5164 }
5165 interface Upvar {
5166 readonly name: string;
5167 readonly resolution: ASTv2.FreeVarResolution;
5168 }
5169 interface SymbolTableOptions {
5170 customizeComponentName: (input: string) => string;
5171 lexicalScope: (variable: string) => boolean;
5172 }
5173 abstract class SymbolTable {
5174 static top(locals: readonly string[], keywords: readonly string[], options: SymbolTableOptions): ProgramSymbolTable;
5175 abstract has(name: string): boolean;
5176 abstract get(name: string): [
5177 symbol: number,
5178 isRoot: boolean
5179 ];
5180 abstract hasKeyword(name: string): boolean;
5181 abstract getKeyword(name: string): number;
5182 abstract hasLexical(name: string): boolean;
5183 abstract getLocalsMap(): Dict<number>;
5184 abstract getDebugInfo(): Core.DebugInfo;
5185 abstract setHasDebugger(): void;
5186 abstract allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number;
5187 abstract allocateNamed(name: string): number;
5188 abstract allocateBlock(name: string): number;
5189 abstract allocate(identifier: string): number;
5190 child(locals: string[]): BlockSymbolTable;
5191 }
5192 class ProgramSymbolTable extends SymbolTable {
5193 #private;
5194 private templateLocals;
5195 private keywords;
5196 private options;
5197 constructor(templateLocals: readonly string[], keywords: readonly string[], options: SymbolTableOptions);
5198 symbols: string[];
5199 upvars: string[];
5200 private size;
5201 private named;
5202 private blocks;
5203 private usedTemplateLocals;
5204 hasLexical(name: string): boolean;
5205 hasKeyword(name: string): boolean;
5206 getKeyword(name: string): number;
5207 getUsedTemplateLocals(): string[];
5208 setHasDebugger(): void;
5209 get hasEval(): boolean;
5210 has(name: string): boolean;
5211 get(name: string): [
5212 number,
5213 boolean
5214 ];
5215 getLocalsMap(): Dict<number>;
5216 getDebugInfo(): Core.DebugInfo;
5217 allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number;
5218 allocateNamed(name: string): number;
5219 allocateBlock(name: string): number;
5220 allocate(identifier: string): number;
5221 }
5222 class BlockSymbolTable extends SymbolTable {
5223 #private;
5224 private parent;
5225 symbols: string[];
5226 slots: number[];
5227 constructor(parent: SymbolTable, symbols: string[], slots: number[]);
5228 get locals(): string[];
5229 hasLexical(name: string): boolean;
5230 getKeyword(name: string): number;
5231 hasKeyword(name: string): boolean;
5232 has(name: string): boolean;
5233 get(name: string): [
5234 number,
5235 boolean
5236 ];
5237 getLocalsMap(): Dict<number>;
5238 getDebugInfo(): Core.DebugInfo;
5239 setHasDebugger(): void;
5240 allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number;
5241 allocateNamed(name: string): number;
5242 allocateBlock(name: string): number;
5243 allocate(identifier: string): number;
5244 }
5245 const Template_base: NodeConstructor<{
5246 table: ProgramSymbolTable;
5247 } & GlimmerParentNodeOptions & BaseNodeFields>;
5248 /**
5249 * Corresponds to an entire template.
5250 */
5251 class Template extends Template_base {
5252 }
5253 const Block_base: NodeConstructor<{
5254 scope: BlockSymbolTable;
5255 } & GlimmerParentNodeOptions & BaseNodeFields>;
5256 /**
5257 * Represents a block. In principle this could be merged with `NamedBlock`, because all cases
5258 * involving blocks have at least a notional name.
5259 */
5260 class Block extends Block_base {
5261 }
5262 const NamedBlocks_base: NodeConstructor<{
5263 blocks: readonly NamedBlock[];
5264 } & BaseNodeFields>;
5265 /**
5266 * Corresponds to a collection of named blocks.
5267 */
5268 class NamedBlocks extends NamedBlocks_base {
5269 /**
5270 * Get the `NamedBlock` for a given name.
5271 */
5272 get(name: "default"): NamedBlock;
5273 get(name: string): NamedBlock | null;
5274 }
5275 interface NamedBlockFields extends BaseNodeFields {
5276 name: SourceSlice;
5277 block: Block;
5278 // these are not currently supported, but are here for future expansion
5279 attrs: readonly HtmlOrSplatAttr[];
5280 componentArgs: readonly ComponentArg[];
5281 modifiers: readonly ElementModifier[];
5282 }
5283 const NamedBlock_base: NodeConstructor<NamedBlockFields & BaseNodeFields>;
5284 /**
5285 * Corresponds to a single named block. This is used for anonymous named blocks (`default` and
5286 * `else`).
5287 */
5288 class NamedBlock extends NamedBlock_base {
5289 get args(): Args;
5290 }
5291 /**
5292 * Content Nodes are allowed in content positions in templates. They correspond to behavior in the
5293 * [Data][data] tokenization state in HTML.
5294 *
5295 * [data]: https://html.spec.whatwg.org/multipage/parsing.html#data-state
5296 */
5297 type ContentNode = HtmlText | HtmlComment | AppendContent | InvokeBlock | InvokeComponent | SimpleElement | GlimmerComment;
5298 const GlimmerComment_base: TypedNodeConstructor<"GlimmerComment", {
5299 text: SourceSlice;
5300 } & BaseNodeFields>;
5301 class GlimmerComment extends GlimmerComment_base {
5302 }
5303 const HtmlText_base: TypedNodeConstructor<"HtmlText", {
5304 chars: string;
5305 } & BaseNodeFields>;
5306 class HtmlText extends HtmlText_base {
5307 }
5308 const HtmlComment_base: TypedNodeConstructor<"HtmlComment", {
5309 text: SourceSlice;
5310 } & BaseNodeFields>;
5311 class HtmlComment extends HtmlComment_base {
5312 }
5313 const AppendContent_base: TypedNodeConstructor<"AppendContent", {
5314 value: ExpressionNode;
5315 trusting: boolean;
5316 table: SymbolTable;
5317 } & BaseNodeFields>;
5318 class AppendContent extends AppendContent_base {
5319 get callee(): ExpressionNode;
5320 get args(): Args;
5321 }
5322 const InvokeBlock_base: TypedNodeConstructor<"InvokeBlock", CallFields & {
5323 blocks: NamedBlocks;
5324 } & BaseNodeFields>;
5325 class InvokeBlock extends InvokeBlock_base {
5326 }
5327 interface InvokeComponentFields {
5328 callee: ExpressionNode;
5329 blocks: NamedBlocks;
5330 attrs: readonly HtmlOrSplatAttr[];
5331 componentArgs: readonly ComponentArg[];
5332 modifiers: readonly ElementModifier[];
5333 }
5334 const InvokeComponent_base: TypedNodeConstructor<"InvokeComponent", InvokeComponentFields & BaseNodeFields>;
5335 /**
5336 * Corresponds to a component invocation. When the content of a component invocation contains no
5337 * named blocks, `blocks` contains a single named block named `"default"`. When a component
5338 * invocation is self-closing, `blocks` is empty.
5339 */
5340 class InvokeComponent extends InvokeComponent_base {
5341 get args(): Args;
5342 }
5343 interface SimpleElementOptions extends BaseNodeFields {
5344 tag: SourceSlice;
5345 body: readonly ContentNode[];
5346 attrs: readonly HtmlOrSplatAttr[];
5347 componentArgs: readonly ComponentArg[];
5348 modifiers: readonly ElementModifier[];
5349 }
5350 const SimpleElement_base: TypedNodeConstructor<"SimpleElement", SimpleElementOptions & BaseNodeFields>;
5351 /**
5352 * Corresponds to a simple HTML element. The AST allows component arguments and modifiers to support
5353 * future extensions.
5354 */
5355 class SimpleElement extends SimpleElement_base {
5356 get args(): Args;
5357 }
5358 type ElementNode = NamedBlock | InvokeComponent | SimpleElement;
5359 interface SerializedBaseNode {
5360 loc: SerializedSourceSpan;
5361 }
5362 interface GlimmerParentNodeOptions extends BaseNodeFields {
5363 body: readonly ContentNode[];
5364 }
5365 interface CallFields extends BaseNodeFields {
5366 callee: CalleeNode;
5367 args: Args;
5368 }
5369 type CalleeNode = KeywordExpression | PathExpression | CallExpression;
5370 type CallNode = CallExpression | InvokeBlock | AppendContent | InvokeComponent | ElementModifier;
5371 /**
5372 * Strict resolution is used:
5373 *
5374 * 1. in a strict mode template
5375 * 2. in an local variable invocation with dot paths
5376 */
5377 const STRICT_RESOLUTION: {
5378 resolution: () => GetContextualFreeOpcode;
5379 serialize: () => SerializedResolution;
5380 isAngleBracket: false;
5381 };
5382 type StrictResolution = typeof STRICT_RESOLUTION;
5383 const HTML_RESOLUTION: {
5384 isAngleBracket: true;
5385 resolution: () => GetContextualFreeOpcode;
5386 serialize: () => SerializedResolution;
5387 };
5388 type HtmlResolution = typeof HTML_RESOLUTION;
5389 function isStrictResolution(value: unknown): value is StrictResolution;
5390 /**
5391 * A `LooseModeResolution` includes one or more namespaces to resolve the variable in
5392 *
5393 * In practice, there are a limited number of possible combinations of these degrees of freedom,
5394 * and they are captured by the `Namespaces` union below.
5395 */
5396 class LooseModeResolution {
5397 readonly namespaces: Namespaces;
5398 readonly isAngleBracket: boolean;
5399 /**
5400 * Namespaced resolution is used in an unambiguous syntax position:
5401 *
5402 * 1. `(sexp)` (namespace: `Helper`)
5403 * 2. `{{#block}}` (namespace: `Component`)
5404 * 3. `<a {{modifier}}>` (namespace: `Modifier`)
5405 * 4. `<Component />` (namespace: `Component`)
5406 */
5407 static namespaced(namespace: FreeVarNamespace, isAngleBracket?: boolean): LooseModeResolution;
5408 /**
5409 * Append resolution is used when the variable should be resolved in both the `component` and
5410 * `helper` namespaces.
5411 *
5412 * ```hbs
5413 * {{x}}
5414 * ```
5415 *
5416 * ```hbs
5417 * {{x y}}
5418 * ```
5419 *
5420 * ^ In either case, `x` should be resolved in the `component` and `helper` namespaces.
5421 */
5422 static append(): LooseModeResolution;
5423 /**
5424 * Trusting append resolution is used when the variable should be resolved only in the
5425 * `helper` namespaces.
5426 *
5427 * ```hbs
5428 * {{{x}}}
5429 * ```
5430 *
5431 * ```hbs
5432 * {{{x y}}}
5433 * ```
5434 *
5435 * ^ In either case, `x` should be resolved in the `helper` namespace.
5436 */
5437 static trustingAppend(): LooseModeResolution;
5438 constructor(namespaces: Namespaces, isAngleBracket?: boolean);
5439 resolution(): GetContextualFreeOpcode;
5440 serialize(): SerializedResolution;
5441 }
5442 enum FreeVarNamespace {
5443 Helper = "Helper",
5444 Modifier = "Modifier",
5445 Component = "Component"
5446 }
5447 const HELPER_NAMESPACE = FreeVarNamespace.Helper;
5448 const MODIFIER_NAMESPACE = FreeVarNamespace.Modifier;
5449 const COMPONENT_NAMESPACE = FreeVarNamespace.Component;
5450 /**
5451 * A `Namespaced` must be resolved in one or more namespaces.
5452 *
5453 * ```hbs
5454 * <X />
5455 * ```
5456 *
5457 * ^ `X` is resolved in the `component` namespace
5458 *
5459 * ```hbs
5460 * (x)
5461 * ```
5462 *
5463 * ^ `x` is resolved in the `helper` namespace
5464 *
5465 * ```hbs
5466 * <a {{x}} />
5467 * ```
5468 *
5469 * ^ `x` is resolved in the `modifier` namespace
5470 */
5471 type Namespaces = [
5472 FreeVarNamespace.Helper
5473 ] | [
5474 FreeVarNamespace.Modifier
5475 ] | [
5476 FreeVarNamespace.Component
5477 ] | [
5478 FreeVarNamespace.Component,
5479 FreeVarNamespace.Helper
5480 ];
5481 type FreeVarResolution = StrictResolution | HtmlResolution | LooseModeResolution;
5482 // Serialization
5483 type SerializedResolution = "Strict" | "Helper" | "Modifier" | "Component" | "ComponentOrHelper";
5484 function loadResolution(resolution: SerializedResolution): FreeVarResolution;
5485 const ThisReference_base: TypedNodeConstructor<"This", object & BaseNodeFields>;
5486 /**
5487 * Corresponds to `this` at the head of an expression.
5488 */
5489 class ThisReference extends ThisReference_base {
5490 }
5491 const ArgReference_base: TypedNodeConstructor<"Arg", {
5492 name: SourceSlice;
5493 symbol: number;
5494 } & BaseNodeFields>;
5495 /**
5496 * Corresponds to `@<ident>` at the beginning of an expression.
5497 */
5498 class ArgReference extends ArgReference_base {
5499 }
5500 const LocalVarReference_base: TypedNodeConstructor<"Local", {
5501 name: string;
5502 isTemplateLocal: boolean;
5503 symbol: number;
5504 } & BaseNodeFields>;
5505 /**
5506 * Corresponds to `<ident>` at the beginning of an expression, when `<ident>` is in the current
5507 * block's scope.
5508 */
5509 class LocalVarReference extends LocalVarReference_base {
5510 }
5511 const FreeVarReference_base: TypedNodeConstructor<"Free", {
5512 name: string;
5513 resolution: FreeVarResolution;
5514 symbol: number;
5515 } & BaseNodeFields>;
5516 /**
5517 * Corresponds to `<ident>` at the beginning of an expression, when `<ident>` is *not* in the
5518 * current block's scope.
5519 *
5520 * The `resolution: FreeVarResolution` field describes how to resolve the free variable.
5521 *
5522 * Note: In strict mode, it must always be a variable that is in a concrete JavaScript scope that
5523 * the template will be installed into.
5524 */
5525 class FreeVarReference extends FreeVarReference_base {
5526 }
5527 type VariableReference = ThisReference | ArgReference | LocalVarReference | FreeVarReference;
5528 /**
5529 * A Handlebars literal.
5530 *
5531 * {@link https://handlebarsjs.com/guide/expressions.html#literal-segments}
5532 */
5533 type LiteralValue = string | boolean | number | undefined | null;
5534 interface LiteralTypes {
5535 string: string;
5536 boolean: boolean;
5537 number: number;
5538 null: null;
5539 undefined: undefined;
5540 }
5541 const LiteralExpression_base: TypedNodeConstructor<"Literal", {
5542 value: LiteralValue;
5543 } & BaseNodeFields>;
5544 /**
5545 * Corresponds to a Handlebars literal.
5546 *
5547 * @see {LiteralValue}
5548 */
5549 class LiteralExpression extends LiteralExpression_base {
5550 toSlice(this: StringLiteral): SourceSlice;
5551 }
5552 type StringLiteral = LiteralExpression & {
5553 value: string;
5554 };
5555 /**
5556 * Returns true if an input {@see ExpressionNode} is a literal.
5557 */
5558 function isLiteral<K extends keyof LiteralTypes = keyof LiteralTypes>(node: ExpressionNode, kind?: K): node is StringLiteral;
5559 const PathExpression_base: TypedNodeConstructor<"Path", {
5560 ref: VariableReference;
5561 tail: readonly SourceSlice[];
5562 } & BaseNodeFields>;
5563 /**
5564 * Corresponds to a path in expression position.
5565 *
5566 * ```hbs
5567 * this
5568 * this.x
5569 * @x
5570 * @x.y
5571 * x
5572 * x.y
5573 * ```
5574 */
5575 class PathExpression extends PathExpression_base {
5576 }
5577 const KeywordExpression_base: TypedNodeConstructor<"Keyword", {
5578 name: string;
5579 symbol: number;
5580 } & BaseNodeFields>;
5581 /**
5582 * Corresponds to a known strict-mode keyword. It behaves similarly to a
5583 * PathExpression with a FreeVarReference, but implies StrictResolution and
5584 * is guaranteed to not have a tail, since `{{outlet.foo}}` would have been
5585 * illegal.
5586 */
5587 class KeywordExpression extends KeywordExpression_base {
5588 }
5589 const CallExpression_base: TypedNodeConstructor<"Call", CallFields & BaseNodeFields>;
5590 /**
5591 * Corresponds to a parenthesized call expression.
5592 *
5593 * ```hbs
5594 * (x)
5595 * (x.y)
5596 * (x y)
5597 * (x.y z)
5598 * ```
5599 */
5600 class CallExpression extends CallExpression_base {
5601 }
5602 const InterpolateExpression_base: TypedNodeConstructor<"Interpolate", {
5603 parts: PresentArray<ExpressionNode>;
5604 } & BaseNodeFields>;
5605 /**
5606 * Corresponds to an interpolation in attribute value position.
5607 *
5608 * ```hbs
5609 * <a href="{{url}}.html"
5610 * ```
5611 */
5612 class InterpolateExpression extends InterpolateExpression_base {
5613 }
5614 type ExpressionNode = LiteralExpression | PathExpression | KeywordExpression | CallExpression | InterpolateExpression;
5615 const Args_base: NodeConstructor<{
5616 positional: PositionalArguments;
5617 named: NamedArguments;
5618 } & BaseNodeFields>;
5619 /**
5620 * Corresponds to syntaxes with positional and named arguments:
5621 *
5622 * - SubExpression
5623 * - Invoking Append
5624 * - Invoking attributes
5625 * - InvokeBlock
5626 *
5627 * If `Args` is empty, the `SourceOffsets` for this node should be the collapsed position
5628 * immediately after the parent call node's `callee`.
5629 */
5630 class Args extends Args_base {
5631 static empty(loc: SourceSpan): Args;
5632 static named(named: NamedArguments): Args;
5633 nth(offset: number): ExpressionNode | null;
5634 get(name: string): ExpressionNode | null;
5635 isEmpty(): boolean;
5636 }
5637 const PositionalArguments_base: NodeConstructor<{
5638 exprs: readonly ExpressionNode[];
5639 } & BaseNodeFields>;
5640 /**
5641 * Corresponds to positional arguments.
5642 *
5643 * If `PositionalArguments` is empty, the `SourceOffsets` for this node should be the collapsed
5644 * position immediately after the parent call node's `callee`.
5645 */
5646 class PositionalArguments extends PositionalArguments_base {
5647 static empty(loc: SourceSpan): PositionalArguments;
5648 get size(): number;
5649 nth(offset: number): ExpressionNode | null;
5650 isEmpty(): boolean;
5651 }
5652 const NamedArguments_base: NodeConstructor<{
5653 entries: readonly NamedArgument[];
5654 } & BaseNodeFields>;
5655 /**
5656 * Corresponds to named arguments.
5657 *
5658 * If `PositionalArguments` and `NamedArguments` are empty, the `SourceOffsets` for this node should
5659 * be the same as the `Args` node that contains this node.
5660 *
5661 * If `PositionalArguments` is not empty but `NamedArguments` is empty, the `SourceOffsets` for this
5662 * node should be the collapsed position immediately after the last positional argument.
5663 */
5664 class NamedArguments extends NamedArguments_base {
5665 static empty(loc: SourceSpan): NamedArguments;
5666 get size(): number;
5667 get(name: string): ExpressionNode | null;
5668 isEmpty(): boolean;
5669 }
5670 /**
5671 * Corresponds to a single named argument.
5672 *
5673 * ```hbs
5674 * x=<expr>
5675 * ```
5676 */
5677 class NamedArgument {
5678 readonly loc: SourceSpan;
5679 readonly name: SourceSlice;
5680 readonly value: ExpressionNode;
5681 constructor(options: {
5682 name: SourceSlice;
5683 value: ExpressionNode;
5684 });
5685 }
5686}
5687interface SymbolTableOptions {
5688 customizeComponentName: (input: string) => string;
5689 lexicalScope: (variable: string) => boolean;
5690}
5691declare abstract class SymbolTable {
5692 static top(locals: readonly string[], keywords: readonly string[], options: SymbolTableOptions): ProgramSymbolTable;
5693 abstract has(name: string): boolean;
5694 abstract get(name: string): [
5695 symbol: number,
5696 isRoot: boolean
5697 ];
5698 abstract hasKeyword(name: string): boolean;
5699 abstract getKeyword(name: string): number;
5700 abstract hasLexical(name: string): boolean;
5701 abstract getLocalsMap(): Dict<number>;
5702 abstract getDebugInfo(): Core.DebugInfo;
5703 abstract setHasDebugger(): void;
5704 abstract allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number;
5705 abstract allocateNamed(name: string): number;
5706 abstract allocateBlock(name: string): number;
5707 abstract allocate(identifier: string): number;
5708 child(locals: string[]): BlockSymbolTable;
5709}
5710declare class ProgramSymbolTable extends SymbolTable {
5711 #private;
5712 private templateLocals;
5713 private keywords;
5714 private options;
5715 constructor(templateLocals: readonly string[], keywords: readonly string[], options: SymbolTableOptions);
5716 symbols: string[];
5717 upvars: string[];
5718 private size;
5719 private named;
5720 private blocks;
5721 private usedTemplateLocals;
5722 hasLexical(name: string): boolean;
5723 hasKeyword(name: string): boolean;
5724 getKeyword(name: string): number;
5725 getUsedTemplateLocals(): string[];
5726 setHasDebugger(): void;
5727 get hasEval(): boolean;
5728 has(name: string): boolean;
5729 get(name: string): [
5730 number,
5731 boolean
5732 ];
5733 getLocalsMap(): Dict<number>;
5734 getDebugInfo(): Core.DebugInfo;
5735 allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number;
5736 allocateNamed(name: string): number;
5737 allocateBlock(name: string): number;
5738 allocate(identifier: string): number;
5739}
5740declare class BlockSymbolTable extends SymbolTable {
5741 #private;
5742 private parent;
5743 symbols: string[];
5744 slots: number[];
5745 constructor(parent: SymbolTable, symbols: string[], slots: number[]);
5746 get locals(): string[];
5747 hasLexical(name: string): boolean;
5748 getKeyword(name: string): number;
5749 hasKeyword(name: string): boolean;
5750 has(name: string): boolean;
5751 get(name: string): [
5752 number,
5753 boolean
5754 ];
5755 getLocalsMap(): Dict<number>;
5756 getDebugInfo(): Core.DebugInfo;
5757 setHasDebugger(): void;
5758 allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number;
5759 allocateNamed(name: string): number;
5760 allocateBlock(name: string): number;
5761 allocate(identifier: string): number;
5762}
5763interface GlimmerSyntaxError extends Error {
5764 location: src.SourceSpan | null;
5765 code: string | null;
5766}
5767declare function generateSyntaxError(message: string, location: src.SourceSpan): GlimmerSyntaxError;
5768interface TraversalError extends Error {
5769 constructor: TraversalErrorConstructor;
5770 key: string;
5771 node: ASTv1.Node;
5772 parent: Nullable<ASTv1.Node>;
5773 stack?: string;
5774}
5775interface TraversalErrorConstructor {
5776 new (message: string, node: ASTv1.Node, parent: Nullable<ASTv1.Node>, key: string): TraversalError;
5777 readonly prototype: TraversalError;
5778}
5779declare const TraversalError: TraversalErrorConstructor;
5780declare function cannotRemoveNode(node: ASTv1.Node, parent: ASTv1.Node, key: string): TraversalError;
5781declare function cannotReplaceNode(node: ASTv1.Node, parent: ASTv1.Node, key: string): TraversalError;
5782interface CallParts {
5783 callee: ASTv2.CalleeNode;
5784 args: ASTv2.Args;
5785}
5786declare class Builder {
5787 // TEMPLATE //
5788 template(symbols: ProgramSymbolTable, body: ASTv2.ContentNode[], loc: SourceSpan): ASTv2.Template;
5789 // INTERNAL (these nodes cannot be reached when doing general-purpose visiting) //
5790 block(symbols: BlockSymbolTable, body: ASTv2.ContentNode[], loc: SourceSpan): ASTv2.Block;
5791 namedBlock(name: SourceSlice, block: ASTv2.Block, loc: SourceSpan): ASTv2.NamedBlock;
5792 simpleNamedBlock(name: SourceSlice, block: ASTv2.Block, loc: SourceSpan): ASTv2.NamedBlock;
5793 slice(chars: string, loc: SourceSpan): SourceSlice;
5794 args(positional: ASTv2.PositionalArguments, named: ASTv2.NamedArguments, loc: SourceSpan): ASTv2.Args;
5795 positional(exprs: ASTv2.ExpressionNode[], loc: SourceSpan): ASTv2.PositionalArguments;
5796 namedArgument(key: SourceSlice, value: ASTv2.ExpressionNode): ASTv2.NamedArgument;
5797 named(entries: ASTv2.NamedArgument[], loc: SourceSpan): ASTv2.NamedArguments;
5798 attr({ name, value, trusting }: {
5799 name: SourceSlice;
5800 value: ASTv2.ExpressionNode;
5801 trusting: boolean;
5802 }, loc: SourceSpan): ASTv2.HtmlAttr;
5803 splatAttr(symbol: number, loc: SourceSpan): ASTv2.SplatAttr;
5804 arg({ name, value, trusting }: {
5805 name: SourceSlice;
5806 value: ASTv2.ExpressionNode;
5807 trusting: boolean;
5808 }, loc: SourceSpan): ASTv2.ComponentArg;
5809 // EXPRESSIONS //
5810 path(head: ASTv2.VariableReference, tail: SourceSlice[], loc: SourceSpan): ASTv2.PathExpression;
5811 keyword(name: string, symbol: number, loc: SourceSpan): ASTv2.KeywordExpression;
5812 self(loc: SourceSpan): ASTv2.VariableReference;
5813 at(name: string, symbol: number, loc: SourceSpan): ASTv2.VariableReference;
5814 freeVar({ name, context, symbol, loc }: {
5815 name: string;
5816 context: ASTv2.FreeVarResolution;
5817 symbol: number;
5818 loc: SourceSpan;
5819 }): ASTv2.FreeVarReference;
5820 localVar(name: string, symbol: number, isTemplateLocal: boolean, loc: SourceSpan): ASTv2.VariableReference;
5821 sexp(parts: CallParts, loc: SourceSpan): ASTv2.CallExpression;
5822 interpolate(parts: ASTv2.ExpressionNode[], loc: SourceSpan): ASTv2.InterpolateExpression;
5823 literal(value: string, loc: SourceSpan): ASTv2.LiteralExpression & {
5824 value: string;
5825 };
5826 literal(value: number, loc: SourceSpan): ASTv2.LiteralExpression & {
5827 value: number;
5828 };
5829 literal(value: boolean, loc: SourceSpan): ASTv2.LiteralExpression & {
5830 value: boolean;
5831 };
5832 literal(value: null, loc: SourceSpan): ASTv2.LiteralExpression & {
5833 value: null;
5834 };
5835 literal(value: undefined, loc: SourceSpan): ASTv2.LiteralExpression & {
5836 value: undefined;
5837 };
5838 literal(value: string | number | boolean | null | undefined, loc: SourceSpan): ASTv2.LiteralExpression;
5839 // STATEMENTS //
5840 append({ table, trusting, value }: {
5841 table: SymbolTable;
5842 trusting: boolean;
5843 value: ASTv2.ExpressionNode;
5844 }, loc: SourceSpan): ASTv2.AppendContent;
5845 modifier({ callee, args }: CallParts, loc: SourceSpan): ASTv2.ElementModifier;
5846 namedBlocks(blocks: ASTv2.NamedBlock[], loc: SourceSpan): ASTv2.NamedBlocks;
5847 blockStatement({ program, inverse, ...call }: {
5848 symbols: SymbolTable;
5849 program: ASTv2.Block;
5850 inverse?: ASTv2.Block | null;
5851 } & CallParts, loc: SourceSpan): ASTv2.InvokeBlock;
5852 element(options: BuildBaseElement): BuildElement;
5853}
5854interface BuildBaseElement {
5855 selfClosing: boolean;
5856 attrs: ASTv2.HtmlOrSplatAttr[];
5857 componentArgs: ASTv2.ComponentArg[];
5858 modifiers: ASTv2.ElementModifier[];
5859 comments: ASTv2.GlimmerComment[];
5860}
5861declare class BuildElement {
5862 readonly base: BuildBaseElement;
5863 readonly builder: Builder;
5864 constructor(base: BuildBaseElement);
5865 simple(tag: SourceSlice, body: ASTv2.ContentNode[], loc: SourceSpan): ASTv2.SimpleElement;
5866 named(name: SourceSlice, block: ASTv2.Block, loc: SourceSpan): ASTv2.NamedBlock;
5867 selfClosingComponent(callee: ASTv2.ExpressionNode, loc: SourceSpan): ASTv2.InvokeComponent;
5868 componentWithDefaultBlock(callee: ASTv2.ExpressionNode, children: ASTv2.ContentNode[], symbols: BlockSymbolTable, loc: SourceSpan): ASTv2.InvokeComponent;
5869 componentWithNamedBlocks(callee: ASTv2.ExpressionNode, blocks: PresentArray<ASTv2.NamedBlock>, loc: SourceSpan): ASTv2.InvokeComponent;
5870}
5871declare function normalize(source: Source, options?: PrecompileOptionsWithLexicalScope): [
5872 ast: ASTv2.Template,
5873 locals: string[]
5874];
5875interface BaseNodeFields {
5876 loc: SourceSpan;
5877}
5878/**
5879 * This is a convenience function for creating ASTv2 nodes, with an optional name and the node's
5880 * options.
5881 *
5882 * ```ts
5883 * export class HtmlText extends node('HtmlText').fields<{ chars: string }>() {}
5884 * ```
5885 *
5886 * This creates a new ASTv2 node with the name `'HtmlText'` and one field `chars: string` (in
5887 * addition to a `loc: SourceOffsets` field, which all nodes have).
5888 *
5889 * ```ts
5890 * export class Args extends node().fields<{
5891 * positional: PositionalArguments;
5892 * named: NamedArguments
5893 * }>() {}
5894 * ```
5895 *
5896 * This creates a new un-named ASTv2 node with two fields (`positional: Positional` and `named:
5897 * Named`, in addition to the generic `loc: SourceOffsets` field).
5898 *
5899 * Once you create a node using `node`, it is instantiated with all of its fields (including `loc`):
5900 *
5901 * ```ts
5902 * new HtmlText({ loc: offsets, chars: someString });
5903 * ```
5904 */
5905declare function node(): {
5906 fields<Fields extends object>(): NodeConstructor<Fields & BaseNodeFields>;
5907};
5908declare function node<T extends string>(name: T): {
5909 fields<Fields extends object>(): TypedNodeConstructor<T, Fields & BaseNodeFields>;
5910};
5911interface NodeConstructor<Fields> {
5912 new (fields: Fields): Readonly<Fields>;
5913}
5914type TypedNode<T extends string, Fields> = {
5915 type: T;
5916} & Readonly<Fields>;
5917interface TypedNodeConstructor<T extends string, Fields> {
5918 new (options: Fields): TypedNode<T, Fields>;
5919}
5920export { build as print, getVoidTags, isVoidTag, sortByLoc, getTemplateLocals, isKeyword, KEYWORDS_TYPES, KeywordType, ASTPlugin, ASTPluginBuilder, ASTPluginEnvironment, PrecompileOptions, PrecompileOptionsWithLexicalScope, preprocess, Syntax, TemplateIdFn, src, SourceSlice, HasSourceSpan, hasSpan, loc, MaybeHasSourceSpan, maybeLoc, SpanList, BlockSymbolTable, ProgramSymbolTable, SymbolTable, generateSyntaxError, GlimmerSyntaxError, cannotRemoveNode, cannotReplaceNode, WalkerPath, traverse, Walker, Walker as Path, ASTv1, ASTv1 as AST, _default as builders, visitorKeys, ASTv2, normalize, node };
5921export type { PreprocessOptions, NodeVisitor };
5922//# sourceMappingURL=index.d.ts.map
\No newline at end of file