@glimmer/syntax
Version:
2,401 lines • 86.3 kB
text/typescript
type Nullable<T> = T | null;
type Optional<T> = T | undefined;
type Maybe<T> = Nullable<T> | Optional<T>;
type Dict<T = unknown> = Record<string, T>;
type PresentArray<T> = [T, ...T[]];
type CurriedComponent = 0;
type CurriedHelper = 1;
type CurriedModifier = 2;
type CurriedType = CurriedComponent | CurriedHelper | CurriedModifier;
// Statements
type AppendOpcode = 1;
type TrustingAppendOpcode = 2;
type CommentOpcode = 3;
type ModifierOpcode = 4;
type BlockOpcode = 6;
type ComponentOpcode = 8;
type OpenElementOpcode = 10;
type OpenElementWithSplatOpcode = 11;
type FlushElementOpcode = 12;
type CloseElementOpcode = 13;
type StaticAttrOpcode = 14;
type DynamicAttrOpcode = 15;
type ComponentAttrOpcode = 16;
type AttrSplatOpcode = 17;
type YieldOpcode = 18;
type TrustingDynamicAttrOpcode = 22;
type TrustingComponentAttrOpcode = 23;
type StaticComponentAttrOpcode = 24;
type DebuggerOpcode = 26;
// Expressions
type UndefinedOpcode = 27;
type CallOpcode = 28;
type ConcatOpcode = 29;
// Get
// Get a local value via symbol
type GetSymbolOpcode = 30; // GetPath + 0-2,
// Lexical symbols are values that are in scope in the template in strict mode
type GetLexicalSymbolOpcode = 32;
// If a free variable is not a lexical symbol in strict mode, it must be a keyword.
// FIXME: Why does this make it to the wire format in the first place?
type GetStrictKeywordOpcode = 31;
// a component or helper (`{{<expr> x}}` in append position)
type GetFreeAsComponentOrHelperHeadOpcode = 35;
// a call head `(x)`
type GetFreeAsHelperHeadOpcode = 37;
type GetFreeAsModifierHeadOpcode = 38;
type GetFreeAsComponentHeadOpcode = 39;
// Keyword Statements
type InElementOpcode = 40;
type IfOpcode = 41;
type EachOpcode = 42;
type LetOpcode = 44;
type WithDynamicVarsOpcode = 45;
type InvokeComponentOpcode = 46;
// Keyword Expressions
type HasBlockOpcode = 48;
type HasBlockParamsOpcode = 49;
type CurryOpcode = 50;
type NotOpcode = 51;
type IfInlineOpcode = 52;
type GetDynamicVarOpcode = 53;
type LogOpcode = 54;
type GetContextualFreeOpcode =
| GetFreeAsComponentOrHelperHeadOpcode
| GetFreeAsHelperHeadOpcode
| GetFreeAsModifierHeadOpcode
| GetFreeAsComponentHeadOpcode
| GetStrictKeywordOpcode;
type AttrOpcode =
| StaticAttrOpcode
| StaticComponentAttrOpcode
| DynamicAttrOpcode
| TrustingDynamicAttrOpcode
| ComponentAttrOpcode
| TrustingComponentAttrOpcode;
type YieldTo = number;
declare namespace Core {
export type Expression = Expressions$1.Expression;
export type DebugSymbols = [locals: Record<string, number>, upvars: Record<string, number>];
export type CallArgs = [Params, Hash];
export type Path = [string, ...string[]];
export type ConcatParams = PresentArray<Expression>;
export type Params = Nullable<ConcatParams>;
export type Hash = Nullable<[PresentArray<string>, PresentArray<Expression>]>;
export type Blocks = Nullable<[string[], SerializedInlineBlock[]]>;
export type Args = [Params, Hash];
export type NamedBlock = [string, SerializedInlineBlock];
export type ElementParameters = Nullable<PresentArray<ElementParameter>>;
export type Syntax = Path | Params | ConcatParams | Hash | Blocks | Args;
}
declare namespace Expressions$1 {
export type Path = Core.Path;
export type Params = Core.Params;
export type Hash = Core.Hash;
export type GetSymbol = [GetSymbolOpcode, number];
export type GetLexicalSymbol = [GetLexicalSymbolOpcode, number];
export type GetStrictFree = [GetStrictKeywordOpcode, number];
export type GetFreeAsComponentOrHelperHead = [GetFreeAsComponentOrHelperHeadOpcode, number];
export type GetFreeAsHelperHead = [GetFreeAsHelperHeadOpcode, number];
export type GetFreeAsModifierHead = [GetFreeAsModifierHeadOpcode, number];
export type GetFreeAsComponentHead = [GetFreeAsComponentHeadOpcode, number];
export type GetContextualFree =
| GetFreeAsComponentOrHelperHead
| GetFreeAsHelperHead
| GetFreeAsModifierHead
| GetFreeAsComponentHead;
export type GetFree = GetStrictFree | GetContextualFree;
export type GetVar = GetSymbol | GetLexicalSymbol | GetFree;
export type GetPathSymbol = [GetSymbolOpcode, number, Path];
export type GetPathTemplateSymbol = [GetLexicalSymbolOpcode, number, Path];
export type GetPathFreeAsComponentOrHelperHead = [
GetFreeAsComponentOrHelperHeadOpcode,
number,
Path,
];
export type GetPathFreeAsHelperHead = [GetFreeAsHelperHeadOpcode, number, Path];
export type GetPathFreeAsModifierHead = [GetFreeAsModifierHeadOpcode, number, Path];
export type GetPathFreeAsComponentHead = [GetFreeAsComponentHeadOpcode, number, Path];
export type GetPathContextualFree =
| GetPathFreeAsComponentOrHelperHead
| GetPathFreeAsHelperHead
| GetPathFreeAsModifierHead
| GetPathFreeAsComponentHead;
export type GetPath = GetPathSymbol | GetPathTemplateSymbol | GetPathContextualFree;
export type Get = GetVar | GetPath;
export type StringValue = string;
export type NumberValue = number;
export type BooleanValue = boolean;
export type NullValue = null;
export type Value = StringValue | NumberValue | BooleanValue | NullValue;
export type Undefined = [UndefinedOpcode];
export type TupleExpression =
| Get
| GetDynamicVar
| Concat
| HasBlock
| HasBlockParams
| Curry
| Helper
| Undefined
| IfInline
| Not
| Log;
// TODO get rid of undefined, which is just here to allow trailing undefined in attrs
// it would be better to handle that as an over-the-wire encoding concern
export type Expression = TupleExpression | Value | undefined;
export type Concat = [ConcatOpcode, Core.ConcatParams];
export type Helper = [CallOpcode, Expression, Nullable<Params>, Hash];
export type HasBlock = [HasBlockOpcode, Expression];
export type HasBlockParams = [HasBlockParamsOpcode, Expression];
export type Curry = [CurryOpcode, Expression, CurriedType, Params, Hash];
export type IfInline = [
op: IfInlineOpcode,
condition: Expression,
truthyValue: Expression,
falsyValue?: Nullable<Expression>,
];
export type Not = [op: NotOpcode, value: Expression];
export type GetDynamicVar = [op: GetDynamicVarOpcode, value: Expression];
export type Log = [op: LogOpcode, positional: Params];
}
type ClassAttr = 0;
type IdAttr = 1;
type ValueAttr = 2;
type NameAttr = 3;
type TypeAttr = 4;
type StyleAttr = 5;
type HrefAttr = 6;
type WellKnownAttrName =
| ClassAttr
| IdAttr
| ValueAttr
| NameAttr
| TypeAttr
| StyleAttr
| HrefAttr;
type DivTag = 0;
type SpanTag = 1;
type PTag = 2;
type ATag = 3;
type WellKnownTagName = DivTag | SpanTag | PTag | ATag;
declare namespace Statements$1 {
export type Expression = Expressions$1.Expression | undefined;
export type Params = Core.Params;
export type Hash = Core.Hash;
export type Blocks = Core.Blocks;
export type Path = Core.Path;
export type Append = [AppendOpcode, Expression];
export type TrustingAppend = [TrustingAppendOpcode, Expression];
export type Comment = [CommentOpcode, string];
export type Modifier = [ModifierOpcode, Expression, Params, Hash];
export type Block = [BlockOpcode, Expression, Params, Hash, Blocks];
export type Component = [
op: ComponentOpcode,
tag: Expression,
parameters: Core.ElementParameters,
args: Hash,
blocks: Blocks,
];
export type OpenElement = [OpenElementOpcode, string | WellKnownTagName];
export type OpenElementWithSplat = [OpenElementWithSplatOpcode, string | WellKnownTagName];
export type FlushElement = [FlushElementOpcode];
export type CloseElement = [CloseElementOpcode];
type Attr<Op extends AttrOpcode> = [
op: Op,
name: string | WellKnownAttrName,
value: Expression,
namespace?: string | undefined,
];
export type StaticAttr = Attr<StaticAttrOpcode>;
export type StaticComponentAttr = Attr<StaticComponentAttrOpcode>;
export type AnyStaticAttr = StaticAttr | StaticComponentAttr;
export type AttrSplat = [AttrSplatOpcode, YieldTo];
export type Yield = [YieldOpcode, YieldTo, Nullable<Params>];
export type DynamicAttr = Attr<DynamicAttrOpcode>;
export type ComponentAttr = Attr<ComponentAttrOpcode>;
export type TrustingDynamicAttr = Attr<TrustingDynamicAttrOpcode>;
export type TrustingComponentAttr = Attr<TrustingComponentAttrOpcode>;
export type AnyDynamicAttr =
| DynamicAttr
| ComponentAttr
| TrustingDynamicAttr
| TrustingComponentAttr;
export type Debugger = [
op: DebuggerOpcode,
locals: Record<string, number>,
upvars: Record<string, number>,
lexical: Record<string, number>,
];
export type InElement = [
op: InElementOpcode,
block: SerializedInlineBlock,
guid: string,
destination: Expression,
insertBefore?: Expression,
];
export type If = [
op: IfOpcode,
condition: Expression,
block: SerializedInlineBlock,
inverse: Nullable<SerializedInlineBlock>,
];
export type Each = [
op: EachOpcode,
condition: Expression,
key: Nullable<Expression>,
block: SerializedInlineBlock,
inverse: Nullable<SerializedInlineBlock>,
];
export type Let = [op: LetOpcode, positional: Core.Params, block: SerializedInlineBlock];
export type WithDynamicVars = [
op: WithDynamicVarsOpcode,
args: Core.Hash,
block: SerializedInlineBlock,
];
export type InvokeComponent = [
op: InvokeComponentOpcode,
definition: Expression,
positional: Core.Params,
named: Core.Hash,
blocks: Blocks | null,
];
/**
* A Handlebars statement
*/
export type Statement =
| Append
| TrustingAppend
| Comment
| Modifier
| Block
| Component
| OpenElement
| OpenElementWithSplat
| FlushElement
| CloseElement
| Attribute
| AttrSplat
| Yield
| Debugger
| InElement
| If
| Each
| Let
| WithDynamicVars
| InvokeComponent;
export type Attribute =
| StaticAttr
| StaticComponentAttr
| DynamicAttr
| TrustingDynamicAttr
| ComponentAttr
| TrustingComponentAttr;
export type ComponentFeature = Modifier | AttrSplat;
export type ElementParameter = Attribute | ComponentFeature;
}
type ElementParameter = Statements$1.ElementParameter;
type SerializedInlineBlock = [statements: Statements$1.Statement[], parameters: number[]];
/**
* This file contains types for the raw AST returned from the Handlebars parser.
* These types were originally imported from
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/handlebars/index.d.ts.
*/
interface CommonNode {
loc: SourceLocation$1;
}
interface SourceLocation$1 {
source: string;
start: Position;
end: Position;
}
interface Position {
line: number;
column: number;
}
interface Program$1 extends CommonNode {
type: 'Program';
body: Statement$1[];
blockParams?: string[];
chained?: boolean;
}
type Statement$1 = MustacheStatement$1 | BlockStatement$1 | DecoratorBlock | PartialStatement | PartialBlockStatement | ContentStatement | CommentStatement$1;
interface CommonMustache extends CommonNode {
path: Expression$1;
params: Expression$1[];
hash: Hash$1;
escaped: boolean;
strip: StripFlags$1;
}
interface MustacheStatement$1 extends CommonMustache {
type: 'MustacheStatement';
}
interface CommonBlock extends CommonNode {
chained: boolean;
path: PathExpression$2 | SubExpression$1;
params: Expression$1[];
hash: Hash$1;
program: Program$1;
inverse?: Program$1;
openStrip?: StripFlags$1;
inverseStrip?: StripFlags$1;
closeStrip?: StripFlags$1;
}
interface BlockStatement$1 extends CommonBlock {
type: 'BlockStatement';
}
interface DecoratorBlock extends CommonBlock {
type: 'DecoratorBlock';
}
interface PartialStatement extends CommonNode {
type: 'PartialStatement';
name: PathExpression$2 | SubExpression$1;
params: Expression$1[];
hash: Hash$1;
indent: string;
strip: StripFlags$1;
}
interface PartialBlockStatement extends CommonNode {
type: 'PartialBlockStatement';
name: PathExpression$2 | SubExpression$1;
params: Expression$1[];
hash: Hash$1;
program: Program$1;
openStrip: StripFlags$1;
closeStrip: StripFlags$1;
}
interface ContentStatement extends CommonNode {
type: 'ContentStatement';
value: string;
original: StripFlags$1;
}
interface CommentStatement$1 extends CommonNode {
type: 'CommentStatement';
value: string;
strip: StripFlags$1;
}
type Expression$1 = SubExpression$1 | PathExpression$2 | Literal$1 | HashLiteral;
interface SubExpression$1 extends CommonNode {
type: 'SubExpression';
path: PathExpression$2 | SubExpression$1;
params: Expression$1[];
hash: Hash$1;
}
interface PathExpression$2 extends CommonNode {
type: 'PathExpression';
data: boolean;
depth: number;
parts: string[];
original: string;
/**
* The upstream parser sets this to a `SubExpression` for sub-expression-rooted
* paths such as `(foo).bar`, which Glimmer does not support.
*/
head?: string | SubExpression$1;
}
/**
* A `key=value` list outside of a mustache's named-argument position, e.g. `(foo=bar)`. The
* upstream parser accepts it, but Glimmer does not support it.
*/
interface HashLiteral extends CommonNode {
type: 'HashLiteral';
pairs: HashPair$1[];
}
type Literal$1 = StringLiteral$2 | BooleanLiteral$1 | NumberLiteral$1 | UndefinedLiteral$1 | NullLiteral$1;
interface StringLiteral$2 extends CommonNode {
type: 'StringLiteral';
value: string;
original: string;
}
interface BooleanLiteral$1 extends CommonNode {
type: 'BooleanLiteral';
value: boolean;
original: boolean;
}
interface NumberLiteral$1 extends CommonNode {
type: 'NumberLiteral';
value: number;
original: number;
}
interface UndefinedLiteral$1 extends CommonNode {
type: 'UndefinedLiteral';
}
interface NullLiteral$1 extends CommonNode {
type: 'NullLiteral';
}
interface Hash$1 extends CommonNode {
pairs: HashPair$1[];
}
interface HashPair$1 extends CommonNode {
key: string;
value: Expression$1;
}
interface StripFlags$1 {
open: boolean;
close: boolean;
}
declare const visitorKeys: {
readonly Template: readonly ["body"];
readonly Block: readonly ["body"];
readonly MustacheStatement: readonly ["path", "params", "hash"];
readonly BlockStatement: readonly ["path", "params", "hash", "program", "inverse"];
readonly ElementModifierStatement: readonly ["path", "params", "hash"];
readonly CommentStatement: readonly [];
readonly MustacheCommentStatement: readonly [];
readonly ElementNode: readonly ["attributes", "modifiers", "children", "comments"];
readonly AttrNode: readonly ["value"];
readonly TextNode: readonly [];
readonly ConcatStatement: readonly ["parts"];
readonly SubExpression: readonly ["path", "params", "hash"];
readonly PathExpression: readonly [];
readonly StringLiteral: readonly [];
readonly BooleanLiteral: readonly [];
readonly NumberLiteral: readonly [];
readonly NullLiteral: readonly [];
readonly UndefinedLiteral: readonly [];
readonly Hash: readonly ["pairs"];
readonly HashPair: readonly ["value"];
};
type VisitorKeysMap = typeof visitorKeys;
type VisitorKeys = {
[P in keyof VisitorKeysMap]: VisitorKeysMap[P][number];
};
type VisitorKey<N extends Node> = VisitorKeys[N['type']] & keyof N;
declare class WalkerPath<N extends Node> {
node: N;
parent: WalkerPath<Node> | null;
parentKey: string | null;
constructor(node: N, parent?: WalkerPath<Node> | null, parentKey?: string | null);
get parentNode(): Node | null;
parents(): Iterable<WalkerPath<Node> | null>;
}
interface FullNodeTraversal<N extends Node> {
enter?(node: N, path: WalkerPath<N>): void;
exit?(node: N, path: WalkerPath<N>): void;
keys?: KeysVisitor<N>;
}
type NodeHandler<N extends Node> = (node: N, path: WalkerPath<N>) => Node | Node[] | undefined | void;
type NodeTraversal<N extends Node> = FullNodeTraversal<N> | NodeHandler<N>;
type NodeVisitor = {
[P in keyof Nodes]?: NodeTraversal<Nodes[P]>;
} & {
All?: NodeTraversal<Node>;
/**
* @deprecated use Template or Block instead
*/
Program?: NodeTraversal<Template$1 | Block$1>;
};
interface FullKeyTraversal<N extends Node, K extends string> {
enter?(node: N, key: K): void;
exit?(node: N, key: K): void;
}
type KeyHandler<N extends Node, K extends VisitorKey<N>> = (node: N, key: K) => void;
type KeyTraversal<N extends Node, K extends VisitorKey<N>> = FullKeyTraversal<N, K> | KeyHandler<N, K>;
type KeysVisitor<N extends Node> = {
[P in VisitorKey<N>]?: KeyTraversal<N, P>;
} & {
All?: KeyTraversal<N, VisitorKey<N>>;
/**
* @deprecated use Template or Block instead
*/
Program?: KeyTraversal<Template$1 | Block$1, 'body'>;
};
declare function traverse(node: Node, visitor: NodeVisitor): void;
type NodeCallback<N extends Node> = (node: N, walker: Walker) => void;
declare class Walker {
order?: unknown | undefined;
stack: unknown[];
constructor(order?: unknown | undefined);
visit<N extends Node>(node: Nullable<N>, visitor: NodeCallback<N>): void;
children<N extends Node>(node: N & Node, callback: NodeCallback<N & Node>): void;
}
type BuilderHead = string | CallableExpression;
type TagDescriptor = string | PathExpression$1 | {
path: PathExpression$1;
selfClosing?: boolean;
} | {
name: string;
selfClosing?: boolean;
};
declare function buildMustache(path: BuilderHead | Literal, params?: Expression[], hash?: Hash, trusting?: boolean, loc?: SourceLocation, strip?: StripFlags): MustacheStatement;
type PossiblyDeprecatedBlock = Block$1 | Template$1;
declare function buildBlock(path: BuilderHead, params: Nullable<Expression[]>, hash: Nullable<Hash>, _defaultBlock: PossiblyDeprecatedBlock, _elseBlock?: Nullable<PossiblyDeprecatedBlock>, loc?: SourceLocation, openStrip?: StripFlags, inverseStrip?: StripFlags, closeStrip?: StripFlags): BlockStatement;
declare function buildElementModifier(path: BuilderHead, params?: Expression[], hash?: Hash, loc?: Nullable<SourceLocation>): ElementModifierStatement;
declare function buildComment(value: string, loc?: SourceLocation): CommentStatement;
declare function buildMustacheComment(value: string, loc?: SourceLocation): MustacheCommentStatement;
declare function buildConcat(parts: (TextNode | MustacheStatement)[], loc?: SourceLocation): ConcatStatement;
interface BuildElementOptions {
attrs?: AttrNode$1[];
modifiers?: ElementModifierStatement[];
children?: Statement[];
comments?: MustacheCommentStatement[];
blockParams?: VarHead[] | string[];
openTag?: SourceLocation;
closeTag?: Maybe<SourceLocation>;
loc?: SourceLocation;
}
declare function buildElement(tag: TagDescriptor, options?: BuildElementOptions): ElementNode$1;
declare function buildAttr(name: string, value: AttrValue, loc?: SourceLocation): AttrNode$1;
declare function buildText(chars?: string, loc?: SourceLocation): TextNode;
declare function buildSexpr(path: BuilderHead, params?: Expression[], hash?: Hash, loc?: SourceLocation): SubExpression;
declare function buildThis(loc?: SourceLocation): ThisHead;
declare function buildAtName(name: string, loc?: SourceLocation): AtHead;
declare function buildVar(name: string, loc?: SourceLocation): VarHead;
declare function buildHeadFromString(original: string, loc?: SourceLocation): PathHead;
declare function buildCleanPath(head: PathHead, tail?: string[], loc?: SourceLocation): PathExpression$1;
declare function buildPath(path: PathExpression$1 | string | {
head: string;
tail: string[];
}, loc?: SourceLocation): PathExpression$1;
declare function buildPath(path: BuilderHead, loc?: SourceLocation): CallableExpression;
declare function buildPath(path: BuilderHead | Literal | Expression, loc?: SourceLocation): Expression;
declare function buildLiteral<T extends Literal>(type: T['type'], value: T['value'], loc?: SourceLocation): T;
declare function buildHash(pairs?: HashPair[], loc?: SourceLocation): Hash;
declare function buildPair(key: string, value: Expression, loc?: SourceLocation): HashPair;
declare function buildProgram(body?: Statement[], blockParams?: string[], loc?: SourceLocation): Template$1 | Block$1;
declare function buildBlockItself(body?: Statement[], params?: Array<VarHead | string>, chained?: boolean, loc?: SourceLocation): Block$1;
declare function buildTemplate(body?: Statement[], blockParams?: string[], loc?: SourceLocation): Template$1;
declare function buildPosition(line: number, column: number): SourcePosition;
declare function buildLoc(loc: Nullable<SourceLocation>): SourceSpan;
declare function buildLoc(startLine: number, startColumn: number, endLine?: number, endColumn?: number, source?: string): SourceSpan;
declare const _default: {
mustache: typeof buildMustache;
block: typeof buildBlock;
comment: typeof buildComment;
mustacheComment: typeof buildMustacheComment;
element: typeof buildElement;
elementModifier: typeof buildElementModifier;
attr: typeof buildAttr;
text: typeof buildText;
sexpr: typeof buildSexpr;
concat: typeof buildConcat;
hash: typeof buildHash;
pair: typeof buildPair;
literal: typeof buildLiteral;
program: typeof buildProgram;
blockItself: typeof buildBlockItself;
template: typeof buildTemplate;
loc: typeof buildLoc;
pos: typeof buildPosition;
path: typeof buildPath;
fullPath: typeof buildCleanPath;
head: typeof buildHeadFromString;
at: typeof buildAtName;
var: typeof buildVar;
this: typeof buildThis;
string: (value: string) => StringLiteral$1;
boolean: (value: boolean) => BooleanLiteral;
number: (value: number) => NumberLiteral;
undefined(): UndefinedLiteral;
null(): NullLiteral;
};
/**
ASTPlugins can make changes to the Glimmer template AST before
compilation begins.
*/
interface ASTPluginBuilder<TEnv extends ASTPluginEnvironment = ASTPluginEnvironment> {
(env: TEnv): ASTPlugin;
}
interface ASTPlugin {
name: string;
visitor: NodeVisitor;
}
interface ASTPluginEnvironment {
meta?: object | undefined;
syntax: Syntax;
}
interface HandlebarsParseOptions {
srcName?: string;
ignoreStandalone?: boolean;
}
interface TemplateIdFn {
(src: string): Nullable<string>;
}
interface PrecompileOptions extends PreprocessOptions {
id?: TemplateIdFn;
/**
* Additional non-native keywords.
*
* Local variables (block params or lexical scope) always takes precedence,
* but otherwise, suitable free variable candidates (e.g. those are not part
* of a path) are matched against this list and turned into keywords.
*
* In strict mode compilation, keywords suppresses the undefined reference
* error and will be resolved by the runtime environment.
*
* In loose mode, keywords are currently ignored and since all free variables
* are already resolved by the runtime environment.
*/
keywords?: readonly string[];
/**
* In loose mode, this hook allows embedding environments to customize the name of an
* angle-bracket component. In practice, this means that `<HelloWorld />` in Ember is
* compiled by Glimmer as an invocation of a component named `hello-world`.
*
* It's a little weird that this is needed in addition to the resolver, but it's a
* classic-only feature and it seems fine to leave it alone for classic consumers.
*/
customizeComponentName?: ((input: string) => string) | undefined;
}
interface PrecompileOptionsWithLexicalScope extends PrecompileOptions {
lexicalScope: (variable: string) => boolean;
}
interface PreprocessOptions {
strictMode?: boolean | undefined;
locals?: string[] | undefined;
meta?: {
moduleName?: string | undefined;
} | undefined;
plugins?: {
ast?: ASTPluginBuilder[] | undefined;
} | undefined;
parseOptions?: HandlebarsParseOptions | undefined;
customizeComponentName?: ((input: string) => string) | undefined;
/**
Useful for specifying a group of options together.
When `'codemod'` we disable all whitespace control in handlebars
(to preserve as much as possible) and we also avoid any
escaping/unescaping of HTML entity codes.
*/
mode?: 'codemod' | 'precompile' | undefined;
}
interface Syntax {
parse: typeof preprocess;
builders: typeof _default;
print: typeof build;
traverse: typeof traverse;
Walker: typeof Walker;
}
declare function preprocess(input: string | Source | Program$1, options?: PreprocessOptions): Template$1;
declare class Source {
#private;
readonly source: string;
readonly module: string;
static from(source: string, options?: PrecompileOptions): Source;
constructor(source: string, module?: string);
/**
* Validate that the character offset represents a position in the source string.
*/
validate(offset: number): boolean;
slice(start: number, end: number): string;
offsetFor(line: number, column: number): SourceOffset;
spanFor({ start, end }: Readonly<SourceLocation>): SourceSpan;
hbsPosFor(offset: number): Nullable<SourcePosition>;
charPosFor({ line, column }: SourcePosition): number | null;
}
/**
* We have already computed the character position of this offset or span.
*/
type CharOffsetKind = 'CharPosition';
/**
* This offset or span was instantiated with a Handlebars SourcePosition or SourceLocation. Its
* character position will be computed on demand.
*/
type HbsPositionKind = 'HbsPosition';
/**
* for (rare) situations where a node is created but there was no source location (e.g. the name
* "default" in default blocks when the word "default" never appeared in source). This is used
* by the internals when there is a legitimate reason for the internals to synthesize a node
* with no location.
*/
type InternalSyntheticKind = 'InternalsSynthetic';
/**
* For situations where a node represents zero parts of the source (for example, empty arguments).
* In general, we attempt to assign these nodes *some* position (empty arguments can be
* positioned immediately after the callee), but it's not always possible
*/
type NonExistentKind = 'NonExistent';
/**
* For situations where a source location was expected, but it didn't correspond to the node in
* the source. This happens if a plugin creates broken locations.
*/
type BrokenKind = 'Broken';
type OffsetKind = CharOffsetKind | HbsPositionKind | InvisibleKind;
/**
* These kinds describe spans that don't have a concrete location in the original source.
*/
type InvisibleKind = BrokenKind | InternalSyntheticKind | NonExistentKind;
type SerializedSourceSlice<Chars extends string = string> = [
chars: Chars,
span: SerializedSourceSpan
];
declare class SourceSlice<Chars extends string = string> {
static synthetic<S extends string>(chars: S): SourceSlice<S>;
static load(source: Source, slice: SerializedSourceSlice): SourceSlice;
readonly chars: Chars;
readonly loc: SourceSpan;
constructor(options: {
loc: SourceSpan;
chars: Chars;
});
getString(): string;
serialize(): SerializedSourceSlice<Chars>;
}
/**
* All spans have these details in common.
*/
interface SpanData {
readonly kind: OffsetKind;
/**
* Convert this span into a string. If the span is broken, return `''`.
*/
asString(): string;
/**
* Gets the module the span was located in.
*/
getModule(): string;
/**
* Get the starting position for this span. Try to avoid creating new position objects, as they
* cache computations.
*/
getStart(): AnyPosition;
/**
* Get the ending position for this span. Try to avoid creating new position objects, as they
* cache computations.
*/
getEnd(): AnyPosition;
/**
* Compute the `SourceLocation` for this span, returned as an instance of `HbsSpan`.
*/
toHbsSpan(): HbsSpan | null;
/**
* For compatibility, whenever the `start` or `end` of a {@see SourceOffset} changes, spans are
* notified of the change so they can update themselves. This shouldn't happen outside of AST
* plugins.
*/
locDidUpdate(changes: {
start?: SourcePosition;
end?: SourcePosition;
}): void;
/**
* Serialize into a {@see SerializedSourceSpan}, which is compact and designed for readability in
* context like AST Explorer. If you need a {@see SourceLocation}, use {@see toJSON}.
*/
serialize(): SerializedSourceSpan;
}
/**
* A `SourceSpan` object represents a span of characters inside of a template source.
*
* There are three kinds of `SourceSpan` objects:
*
* - `ConcreteSourceSpan`, which contains byte offsets
* - `LazySourceSpan`, which contains `SourceLocation`s from the Handlebars AST, which can be
* converted to byte offsets on demand.
* - `InvisibleSourceSpan`, which represent source strings that aren't present in the source,
* because:
* - they were created synthetically
* - their location is nonsensical (the span is broken)
* - they represent nothing in the source (this currently happens only when a bug in the
* upstream Handlebars parser fails to assign a location to empty blocks)
*
* At a high level, all `SourceSpan` objects provide:
*
* - byte offsets
* - source in column and line format
*
* And you can do these operations on `SourceSpan`s:
*
* - collapse it to a `SourceSpan` representing its starting or ending position
* - slice out some characters, optionally skipping some characters at the beginning or end
* - create a new `SourceSpan` with a different starting or ending offset
*
* All SourceSpan objects implement `SourceLocation`, for compatibility. All SourceSpan
* objects have a `toJSON` that emits `SourceLocation`, also for compatibility.
*
* For compatibility, subclasses of `AbstractSourceSpan` must implement `locDidUpdate`, which
* happens when an AST plugin attempts to modify the `start` or `end` of a span directly.
*
* The goal is to avoid creating any problems for use-cases like AST Explorer.
*/
declare class SourceSpan implements SourceLocation {
private data;
static get NON_EXISTENT(): SourceSpan;
static load(source: Source, serialized: SerializedSourceSpan): SourceSpan;
static forHbsLoc(source: Source, loc: SourceLocation): SourceSpan;
static forCharPositions(source: Source, startPos: number, endPos: number): SourceSpan;
static synthetic(chars: string): SourceSpan;
static broken(pos?: SourceLocation): SourceSpan;
readonly isInvisible: boolean;
constructor(data: SpanData & AnySpan);
getStart(): SourceOffset;
getEnd(): SourceOffset;
get loc(): SourceLocation;
get module(): string;
/**
* Get the starting `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
*/
get startPosition(): SourcePosition;
/**
* Get the ending `SourcePosition` for this `SourceSpan`, lazily computing it if needed.
*/
get endPosition(): SourcePosition;
/**
* Support converting ASTv1 nodes into a serialized format using JSON.stringify.
*/
toJSON(): SourceLocation;
/**
* Create a new span with the current span's end and a new beginning.
*/
withStart(other: SourceOffset): SourceSpan;
/**
* Create a new span with the current span's beginning and a new ending.
*/
withEnd(other: SourceOffset): SourceSpan;
asString(): string;
/**
* Convert this `SourceSpan` into a `SourceSlice`.
*/
toSlice(expected?: string): SourceSlice;
/**
* For compatibility with SourceLocation in AST plugins
*
* @deprecated use startPosition instead
*/
get start(): SourcePosition;
/**
* For compatibility with SourceLocation in AST plugins
*
* @deprecated use withStart instead
*/
set start(position: SourcePosition);
/**
* For compatibility with SourceLocation in AST plugins
*
* @deprecated use endPosition instead
*/
get end(): SourcePosition;
/**
* For compatibility with SourceLocation in AST plugins
*
* @deprecated use withEnd instead
*/
set end(position: SourcePosition);
/**
* For compatibility with SourceLocation in AST plugins
*
* @deprecated use module instead
*/
get source(): string;
collapse(where: 'start' | 'end'): SourceSpan;
extend(other: SourceSpan): SourceSpan;
serialize(): SerializedSourceSpan;
slice({ skipStart, skipEnd }: {
skipStart?: number;
skipEnd?: number;
}): SourceSpan;
sliceStartChars({ skipStart, chars }: {
skipStart?: number;
chars: number;
}): SourceSpan;
sliceEndChars({ skipEnd, chars }: {
skipEnd?: number;
chars: number;
}): SourceSpan;
}
type AnySpan = HbsSpan | CharPositionSpan | InvisibleSpan;
declare class CharPositionSpan implements SpanData {
#private;
readonly source: Source;
readonly charPositions: {
start: CharPosition;
end: CharPosition;
};
readonly kind: "CharPosition";
constructor(source: Source, charPositions: {
start: CharPosition;
end: CharPosition;
});
wrap(): SourceSpan;
asString(): string;
getModule(): string;
getStart(): AnyPosition;
getEnd(): AnyPosition;
locDidUpdate(): void;
toHbsSpan(): HbsSpan | null;
serialize(): SerializedSourceSpan;
toCharPosSpan(): this;
}
declare class HbsSpan implements SpanData {
#private;
readonly source: Source;
readonly hbsPositions: {
start: HbsPosition;
end: HbsPosition;
};
readonly kind: "HbsPosition";
constructor(source: Source, hbsPositions: {
start: HbsPosition;
end: HbsPosition;
}, providedHbsLoc?: SourceLocation | null);
serialize(): SerializedConcreteSourceSpan;
wrap(): SourceSpan;
private updateProvided;
locDidUpdate({ start, end }: {
start?: SourcePosition;
end?: SourcePosition;
}): void;
asString(): string;
getModule(): string;
getStart(): AnyPosition;
getEnd(): AnyPosition;
toHbsLoc(): SourceLocation;
toHbsSpan(): this;
toCharPosSpan(): CharPositionSpan | null;
}
declare class InvisibleSpan implements SpanData {
readonly kind: InvisibleKind;
readonly loc: SourceLocation;
readonly string: string | null;
constructor(kind: InvisibleKind, loc: SourceLocation, string?: string | null);
serialize(): SerializedConcreteSourceSpan;
wrap(): SourceSpan;
asString(): string;
locDidUpdate({ start, end }: {
start?: SourcePosition;
end?: SourcePosition;
}): void;
getModule(): string;
getStart(): AnyPosition;
getEnd(): AnyPosition;
toCharPosSpan(): this;
toHbsSpan(): null;
toHbsLoc(): SourceLocation;
}
type SerializedConcreteSourceSpan = /** collapsed */ number | /** normal */ [start: number, size: number] | /** synthetic */ string;
type SerializedSourceSpan = SerializedConcreteSourceSpan;
interface SourceLocation {
start: SourcePosition;
end: SourcePosition;
}
interface SourcePosition {
/** >= 1 */
line: number;
/** >= 0 */
column: number;
}
declare const UNKNOWN_POSITION: Readonly<{
readonly line: 1;
readonly column: 0;
}>;
declare const SYNTHETIC_LOCATION: Readonly<{
readonly source: "(synthetic)";
readonly start: Readonly<{
readonly line: 1;
readonly column: 0;
}>;
readonly end: Readonly<{
readonly line: 1;
readonly column: 0;
}>;
}>;
declare const NON_EXISTENT_LOCATION: Readonly<{
readonly source: "(nonexistent)";
readonly start: Readonly<{
readonly line: 1;
readonly column: 0;
}>;
readonly end: Readonly<{
readonly line: 1;
readonly column: 0;
}>;
}>;
/**
* All positions have these details in common. Most notably, all three kinds of positions can
* must be able to attempt to convert themselves into {@see CharPosition}.
*/
interface PositionData {
readonly kind: OffsetKind;
toCharPos(): CharPosition | null;
toJSON(): SourcePosition;
}
/**
* Used to indicate that an attempt to convert a `SourcePosition` to a character offset failed. It
* is separate from `null` so that `null` can be used to indicate that the computation wasn't yet
* attempted (and therefore to cache the failure)
*/
declare const BROKEN = "BROKEN";
type BROKEN = 'BROKEN';
type AnyPosition = HbsPosition | CharPosition | InvisiblePosition;
/**
* A `SourceOffset` represents a single position in the source.
*
* There are three kinds of backing data for `SourceOffset` objects:
*
* - `CharPosition`, which contains a character offset into the raw source string
* - `HbsPosition`, which contains a `SourcePosition` from the Handlebars AST, which can be
* converted to a `CharPosition` on demand.
* - `InvisiblePosition`, which represents a position not in source (@see {InvisiblePosition})
*/
declare class SourceOffset {
readonly data: PositionData & AnyPosition;
/**
* Create a `SourceOffset` from a Handlebars `SourcePosition`. It's stored as-is, and converted
* into a character offset on demand, which avoids unnecessarily computing the offset of every
* `SourceLocation`, but also means that broken `SourcePosition`s are not always detected.
*/
static forHbsPos(source: Source, pos: SourcePosition): SourceOffset;
/**
* Create a `SourceOffset` that corresponds to a broken `SourcePosition`. This means that the
* calling code determined (or knows) that the `SourceLocation` doesn't correspond correctly to
* any part of the source.
*/
static broken(pos?: SourcePosition): SourceOffset;
constructor(data: PositionData & AnyPosition);
/**
* Get the character offset for this `SourceOffset`, if possible.
*/
get offset(): number | null;
/**
* Compare this offset with another one.
*
* If both offsets are `HbsPosition`s, they're equivalent as long as their lines and columns are
* the same. This avoids computing offsets unnecessarily.
*
* Otherwise, two `SourceOffset`s are equivalent if their successfully computed character offsets
* are the same.
*/
eql(right: SourceOffset): boolean;
/**
* Create a span that starts from this source offset and ends with another source offset. Avoid
* computing character offsets if both `SourceOffset`s are still lazy.
*/
until(other: SourceOffset): SourceSpan;
/**
* Create a `SourceOffset` by moving the character position represented by this source offset
* forward or backward (if `by` is negative), if possible.
*
* If this `SourceOffset` can't compute a valid character offset, `move` returns a broken offset.
*
* If the resulting character offset is less than 0 or greater than the size of the source, `move`
* returns a broken offset.
*/
move(by: number): SourceOffset;
/**
* Create a new `SourceSpan` that represents a collapsed range at this source offset. Avoid
* computing the character offset if it has not already been computed.
*/
collapsed(): SourceSpan;
/**
* Convert this `SourceOffset` into a Handlebars {@see SourcePosition} for compatibility with
* existing plugins.
*/
toJSON(): SourcePosition;
}
declare class CharPosition implements PositionData {
readonly source: Source;
readonly charPos: number;
readonly kind: "CharPosition";
/** Computed from char offset */
_locPos: HbsPosition | BROKEN | null;
constructor(source: Source, charPos: number);
/**
* This is already a `CharPosition`.
*
* {@see HbsPosition} for the alternative.
*/
toCharPos(): this;
/**
* Produce a Handlebars {@see SourcePosition} for this `CharPosition`. If this `CharPosition` was
* computed using {@see SourceOffset#move}, this will compute the `SourcePosition` for the offset.
*/
toJSON(): SourcePosition;
wrap(): SourceOffset;
/**
* A `CharPosition` always has an offset it can produce without any additional computation.
*/
get offset(): number;
/**
* Convert the current character offset to an `HbsPosition`, if it was not already computed. Once
* a `CharPosition` has computed its `HbsPosition`, it will not need to do compute it again, and
* the same `CharPosition` is retained when used as one of the ends of a `SourceSpan`, so
* computing the `HbsPosition` should be a one-time operation.
*/
toHbsPos(): HbsPosition | null;
}
declare class HbsPosition implements PositionData {
readonly source: Source;
readonly hbsPos: SourcePosition;
readonly kind: "HbsPosition";
_charPos: CharPosition | BROKEN | null;
constructor(source: Source, hbsPos: SourcePosition, charPos?: number | null);
/**
* Lazily compute the character offset from the {@see SourcePosition}. Once an `HbsPosition` has
* computed its `CharPosition`, it will not need to do compute it again, and the same
* `HbsPosition` is retained when used as one of the ends of a `SourceSpan`, so computing the
* `CharPosition` should be a one-time operation.
*/
toCharPos(): CharPosition | null;
/**
* Return the {@see SourcePosition} that this `HbsPosition` was instantiated with. This operation
* does not need to compute anything.
*/
toJSON(): SourcePosition;
wrap(): SourceOffset;
/**
* This is already an `HbsPosition`.
*
* {@see CharPosition} for the alternative.
*/
toHbsPos(): this;
}
declare class InvisiblePosition implements PositionData {
readonly kind: BrokenKind | InternalSyntheticKind | NonExistentKind;
readonly pos: SourcePosition;
constructor(kind: BrokenKind | InternalSyntheticKind | NonExistentKind, pos: SourcePosition);
/**
* A broken position cannot be turned into a {@see CharacterPosition}.
*/
toCharPos(): null;
/**
* The serialization of an `InvisiblePosition is whatever Handlebars {@see SourcePosition} was
* originally identified as broken, non-existent or synthetic.
*
* If an `InvisiblePosition` never had an source offset at all, this method returns
* {@see UNKNOWN_POSITION} for compatibility.
*/
toJSON(): SourcePosition;
wrap(): SourceOffset;
get offset(): null;
}
declare class SpanList {
static range(span: PresentArray<HasSourceSpan>): SourceSpan;
static range(span: HasSourceSpan[], fallback: SourceSpan): SourceSpan;
_span: SourceSpan[];
constructor(span?: SourceSpan[]);
add(offset: SourceSpan): void;
getRangeOffset(fallback: SourceSpan): SourceSpan;
}
type HasSourceSpan = {
loc: SourceSpan;
} | SourceSpan | [HasSourceSpan, ...HasSourceSpan[]];
declare function loc(span: HasSourceSpan): SourceSpan;
type MaybeHasSourceSpan = {
loc: SourceSpan;
} | SourceSpan | MaybeHasSourceSpan[];
declare function hasSpan(span: MaybeHasSourceSpan): span is HasSourceSpan;
declare function maybeLoc(location: MaybeHasSourceSpan, fallback: SourceSpan): SourceSpan;
type api$2_HasSourceSpan = HasSourceSpan;
type api$2_MaybeHasSourceSpan = MaybeHasSourceSpan;
declare const api$2_NON_EXISTENT_LOCATION: typeof NON_EXISTENT_LOCATION;
declare const api$2_SYNTHETIC_LOCATION: typeof SYNTHETIC_LOCATION;
type api$2_SerializedSourceSpan = SerializedSourceSpan;
type api$2_Source = Source;
declare const api$2_Source: typeof Source;
type api$2_SourceLocation = SourceLocation;
type api$2_SourceOffset = SourceOffset;
declare const api$2_SourceOffset: typeof SourceOffset;
type api$2_SourcePosition = SourcePosition;
type api$2_SourceSlice<Chars extends string = string> = SourceSlice<Chars>;
declare const api$2_SourceSlice: typeof SourceSlice;
type api$2_SourceSpan = SourceSpan;
declare const api$2_SourceSpan: typeof SourceSpan;
type api$2_SpanList = SpanList;
declare const api$2_SpanList: typeof SpanList;
declare const api$2_UNKNOWN_POSITION: typeof UNKNOWN_POSITION;
declare const api$2_hasSpan: typeof hasSpan;
declare const api$2_loc: typeof loc;
declare const api$2_maybeLoc: typeof maybeLoc;
declare namespace api$2 {
export { api$2_NON_EXISTENT_LOCATION as NON_EXISTENT_LOCATION, api$2_SYNTHETIC_LOCATION as SYNTHETIC_LOCATION, api$2_Source as Source, api$2_SourceOffset as SourceOffset, api$2_SourceSlice as SourceSlice, api$2_SourceSpan as SourceSpan, api$2_SpanList as SpanList, api$2_UNKNOWN_POSITION as UNKNOWN_POSITION, api$2_hasSpan as hasSpan, api$2_loc as loc, api$2_maybeLoc as maybeLoc };
export type { api$2_HasSourceSpan as HasSourceSpan, api$2_MaybeHasSourceSpan as MaybeHasSourceSpan, api$2_SerializedSourceSpan as SerializedSourceSpan, api$2_SourceLocation as SourceLocation, api$2_SourcePosition as SourcePosition };
}
interface BaseNode {
type: NodeType;
loc: SourceSpan;
}
interface CommonProgram extends BaseNode {
body: Statement[];
}
interface Block$1 extends CommonProgram {
type: 'Block';
params: VarHead[];
chained?: boolean;
/**
* string accessor for params.name
*/
blockParams: string[];
}
type EntityEncodingState = 'transformed' | 'raw';
interface Template$1 extends CommonProgram {
type: 'Template';
blockParams: string[];
}
/**
* @deprecated use Template or Block instead
*/
type Program = Template$1 | Block$1;
type CallableExpression = SubExpression | PathExpression$1;
interface CallParts {
path: CallableExpression;
params: Expression[];
hash: Hash;
loc: SourceSpan;
}
type CallNode$1 = MustacheStatement | BlockStatement | ElementModifierStatement | SubExpression;
interface MustacheStatement extends BaseNode {
type: 'MustacheStatement';
path: Expression;
params: Expression[];
hash: Hash;
trusting: boolean;
strip: StripFlags;
/**
* @deprecated use trusting instead
*/
escaped: boolean;
}
interface BlockStatement extends BaseNode {
type: 'BlockStatement';
path: CallableExpression;
params: Expression[];
hash: Hash;
program: Block$1;
inverse?: Nullable<Block$1>;
openStrip: StripFlags;
inverseStrip: StripFlags;
closeStrip: StripFlags;
chained?: boolean;
}
interface ElementModifierStatement extends BaseNode {
type: 'ElementModifierStatement';
path: CallableExpression;
params: Expression[];
hash: Hash;
}
interface CommentStatement extends BaseNode {
type: 'CommentStatement';
value: string;
}
interface MustacheCommentStatement extends BaseNode {
type: 'MustacheCommentStatement';
value: string;
}
interface ElementNode$1 extends BaseNode {
type: 'ElementNode';
path: PathExpression$1;
selfClosing: boolean;
attributes: AttrNode$1[];
params: VarHead[];
modifiers: ElementModifierStatement[];
comments: MustacheCommentStatement[];
children: Statement[];
/**
* span for the open tag
*/
openTag: SourceSpan;
/**
* span for the close tag, null for void or self-closing tags
*/
closeTag: Nullable<SourceSpan>;
/**
* string accessor for path.original
*/
tag: string;
/**
* string accessor for params.name
*/
blockParams: string[];
}
type StatementName = 'MustacheStatement' | 'CommentStatement' | 'BlockStatement' | 'MustacheCommentStatement' | 'TextNode' | 'ElementNode';
interface AttrNode$1 extends BaseNode {
type: 'AttrNode';
name: string;
value: AttrValue;
}
type AttrValue = TextNode | MustacheStatement | ConcatStatement;
type AttrPart = TextNode | MustacheStatement;
interface TextNode extends BaseNode {
type: 'TextNode';
chars: string;
}
interface ConcatStatement extends BaseNode {
type: 'ConcatStatement';
parts: PresentArray<TextNode | MustacheStatement>;
}
type ExpressionName = 'SubExpression' | 'PathExpression' | LiteralName;
interface SubExpression extends BaseNode {
type: 'SubExpression';
path: CallableExpression;
params: Expression[];
hash: Hash;
}
interface ThisHead {
type: 'ThisHead';
original: 'this';
loc: SourceSpan;
}
interface AtHead {
type: 'AtHead';
name: string;
loc: SourceSpan;
/**
* alias for name
*/
original: string;
}
interface VarHead {
type: 'VarHead';
name: string;
loc: SourceSpan;
/**
* alias for name
*/
original: string;
}
type PathHead = ThisHead | AtHead | VarHead;
interface MinimalPathExpression extends BaseNode {
type: 'PathExpression';
head: PathHead;
tail: string[];
}
interface PathExpression$1 extends MinimalPathExpression {
type: 'PathExpression';
original: string;
head: PathHead;
tail: string[];
/**
* @deprecated use `head` and `tail` instead
*/
parts: readonly string[];
/**
* @deprecated use `head.type` instead
*/
readonly this: boolean;
/**
* @deprecated use `head.type' instead
*/
readonly data: boolean;
}
type LiteralName = 'StringLiteral' | 'BooleanLiteral' | 'NumberLiteral' | 'UndefinedLiteral' | 'NullLiteral';
interface StringLiteral$1 extends BaseNode {
type: 'StringLiteral';
value: string;
/**
* @deprecated use value instead
*/
original: string;
}
interface BooleanLiteral extends BaseNode {
type: 'BooleanLiteral';
value: boolean;
/**
* @deprecated use value instead
*/
original: boolean;
}
interface NumberLiteral extends BaseNode {
type: 'NumberLiteral';
value: number;
/**
* @deprecated use value instead
*/
original: number;
}
interface UndefinedLiteral extends BaseNode {
type: 'UndefinedLiteral';
value: undefined;
/**
* @deprecated use value instead
*/
original: undefined;
}
interface NullLiteral extends BaseNode {
type: 'NullLiteral';
value: null;
/**
* @deprecated use value instead
*/
original: null;
}
interface Hash extends BaseNode {
type: 'Hash';
pairs: HashPair[];
}
interface HashPair extends BaseNode {
type: 'HashPair';
key: string;
value: Expression;
}
interface StripFlags {
open: boolean;
close: boolean;
}
type Nodes = {
Template: Template$1;
Block: Block$1;
MustacheStatement: MustacheStatement;
BlockStatement: BlockStatement;
ElementModifierStatement: ElementModifierStatement;
CommentStatement: CommentStatement;
MustacheCommentStatement: MustacheCommentStatement;
ElementNode: ElementNode$1;
AttrNode: AttrNode$1;
TextNode: TextNode;
ConcatStatement: ConcatStatement;
SubExpression: SubExpression;
PathExpression: PathExpression$1;
StringLiteral: StringLiteral$1;
BooleanLiteral: BooleanLiteral;
NumberLiteral: NumberLiteral;
NullLiteral: NullLiteral;
UndefinedLiteral: UndefinedLiteral;
Hash: Hash;
HashPair: HashPair;
};
type NodeType = keyof Nodes;
type Node = Nodes[NodeType];
type SubNodes = {
ThisHead: ThisHead;
AtHead: AtHead;
VarHead: VarHead;
};
type SubNodeType = keyof SubNodes;
type SubNode = SubNodes[SubNodeType];
type Statement = Nodes[StatementName];
type Statements = Pick<Nodes, StatementName>;
type Literal = Nodes[LiteralName];
type Expression = Nodes[ExpressionName];
type Expressions = Pick<Nodes, ExpressionName>;
type TopLevelStatement = Statement | Nodes['Block'];
type ParentNode = Template$1 | Block$1 | ElementNode$1;
type api$1_AtHead = AtHead;
type api$1_AttrPart = AttrPart;
type api$1_AttrValue = AttrValue;
type api$1_BaseNode = BaseNode;
type api$1_BlockStatement = BlockStatement;
type api$1_BooleanLiteral = BooleanLiteral;
type api$1_CallParts = CallParts;
type api$1_CallableExpression = CallableExpression;
type api$1_CommentStatement = CommentStatement;
type api$1_CommonProgram = CommonProgram;
type api$1_ConcatStatement = ConcatStatement;
type api$1_ElementModifierStatement = ElementModifierStatement;
type api$1_EntityEncodingState = EntityEncodingState;
type api$1_Expression = Expression;
type api$1_ExpressionName = ExpressionName;
type api$1_Expressions = Expressions;
type api$1_Hash = Hash;
type api$1_HashPair = HashPair;
type api$1_Literal = Literal;
type api$1_LiteralName = LiteralName;
type api$1_MinimalPathExpression = MinimalPathExpression;
type api$1_MustacheCommentStatement = MustacheCommentStatement;
type api$1_MustacheStatement = MustacheStatement;
type api$1_Node = Node;
type api$1_NodeType = NodeType;
type api$1_Nodes = Nodes;
type api$1_NullLiteral = NullLiteral;
type api$1_NumberLiteral = NumberLiteral;
type api$1_ParentNode = ParentNode;
type api$1_PathHead = PathHead;
type api$1_Program = Program;
type api$1_SourceLocation = SourceLocation;
type api$1_SourcePosition = SourcePosition;
type api$1_Statement = Statement;
type api$1_StatementName = StatementName;
type api$1_Statements = Statements;
type api$1_StripFlags = StripFlags;
type api$1_SubExpression = SubExpression;
type api$1_SubNode = SubNode;
type api$1_SubNodeType = SubNodeType;
type api$1_SubNodes = SubNodes;
type api$1_TextNode = TextNode;
type api$1_ThisHead = ThisHead;
type api$1_TopLevelStatement = TopLevelStatement;
type api$1_UndefinedLiteral = UndefinedLiteral;
type api$1_VarHead = VarHead;
declare namespace api$1 {
export type { api$1_AtHead as AtHead, AttrNode$1 as AttrNode, api$1_AttrPart as AttrPart, api$1_AttrValue as AttrValue, api$1_BaseNode as BaseNode, Block$1 as Block, api$1_BlockStatement as BlockStatement, api$1_BooleanLiteral as BooleanLiteral, CallNode$1 as CallNode, api$1_CallParts as CallParts, api$1_CallableExpression as CallableExpression, api$1_CommentStatement as CommentStatement, api$1_CommonProgram as CommonProgram, api$1_ConcatStatement as ConcatStatement, api$1_ElementModifierStatement as ElementModifierStatement, ElementNode$1 as ElementNode, api$1_EntityEncodingState as EntityEncodingState, api$1_Expression as Expression, api$1_ExpressionName as ExpressionName, api$1_Expressions as Expressions, api$1_Hash as Hash, api$1_HashPair as HashPair, api$1_Literal as Literal, api$1_LiteralName as LiteralName, api$1_MinimalPathExpression as MinimalPathExpression, api$1_MustacheCommentStatement as MustacheCommentStatement, api$1_MustacheStatement as MustacheStatement, api$1_Node as Node, api$1_NodeType as NodeType, api$1_Nodes as Nodes, api$1_NullLiteral as NullLiteral, api$1_NumberLiteral as NumberLiteral, api$1_ParentNode as ParentNode, PathExpression$1 as PathExpression, api$1_PathHead as PathHead, SourcePosition as Position, api$1_Program as Program, api$1_SourceLocation as SourceLocation, api$1_SourcePosition as SourcePosition, api$1_Statement as Statement, api$1_StatementName as StatementName, api$1_Statements as Statements, StringLiteral$1 as StringLiteral, api$1_StripFlags as StripFlags, api$1_SubExpression as SubExpression, api$1_SubNode as SubNode, api$1_SubNodeType as SubNodeType, api$1_SubNodes as SubNodes, Template$1 as Template, api$1_TextNode as TextNode, api$1_ThisHead as ThisHead, api$1_TopLevelStatement as TopLevelStatement, api$1_UndefinedLiteral as UndefinedLiteral, api$1_VarHead as VarHead };
}
declare function getVoidTags(): string[];
interface PrinterOptions {
entityEncoding: EntityEncodingState;
/**
* Used to override the mechanism of printing a given AST.Node.
*
* This will generally only be useful to source -> source codemods
* where you would like to specialize/override the way a given node is
* printed (e.g. you would like to preserve as much of the original
* formatting as possible).
*
* When the provided override returns undefined, the default built in printing
* will be done for the AST.Node.
*
* @param ast the ast node to be printed
* @param options the options specified during the print() invocation
*/
override?(ast: Node, options: PrinterOptions): void | string;
}
/**
* Examples when true:
* - link
* - liNK
*
* Examples when false:
* - Link (component)
*/
declare function isVoidTag(tag: string): boolean;
declare function build(ast: Node, options?: PrinterOptions): string;
declare function sortByLoc(a: Node, b: Node): -1 | 0 | 1;
interface GetTemplateLocalsOptions {
includeKeywords?: boolean;
includeHtmlElements?: boolean;
}
/**
* Parses and traverses a given template to extract all template locals
* referenced that could possible come from the parent scope. Can exclude known keywords
* optionally.
*/
declare function getTemplateLocals(html: string, options?: GetTemplateLocalsOptions): string[];
type Keywords = keyof typeof KEYWORDS_TYPES;
type KeywordType = 'Call' | 'Modifier' | 'Append' | 'Block';
declare function isKeyword(word: string): word is Keywords;
declare function isKeyword(word: string, type: KeywordType): boolean;
/**
* This includes the full list of keywords currently in use in the template
* language, and where their valid usages are.
*/
declare const KEYWORDS_TYPES: {
component: ("Call" | "Append" | "Block")[];
debugger: "Append"[];
'each-in': "Block"[];
each: "Block"[];
'has-block-params': ("Call" | "Append")[];
'has-block': ("Call" | "Append")[];
helper: ("Call" | "Append")[];
if: ("Call" | "Append" | "Block")[];
'in-element': "Block"[];
let: "Block"[];
log: ("Call" | "Append")[];
modifier: ("Call" | "Modifier")[];
mount: "Append"[];
mut: ("Call" | "Append")[];
outlet: "Append"[];
readonly: ("Call" | "Append")[];
unbound: ("Call" | "Append")[];
unless: ("Call" | "Append" | "Block")[];
yield: "Append"[];
};
interface BaseNodeFields {
loc: SourceSpan;
}
/**
* This is a convenience function for creating ASTv2 nodes, with an optional name and the node's
* options.
*
* ```ts
* export class HtmlText extends node('HtmlText').fields<{ chars: string }>() {}
* ```
*
* This creates a new ASTv2 node with the name `'HtmlText'` and one field `chars: string` (in
* addition to a `loc: SourceOffsets` field, which all nodes have).
*
* ```ts
* export class Args extends node().fields<{
* positional: PositionalArguments;
* named: NamedArguments
* }>() {}
* ```
*
* This creates a new un-named ASTv2 node with two fields (`positional: Positional` and `named:
* Named`, in addition to the generic `loc: SourceOffsets` field).
*
* Once you create a node using `node`, it is instantiated with all of its fields (including `loc`):
*
* ```ts
* new HtmlText({ loc: offsets, chars: someString });
* ```
*/
declare function node(): {
fields<Fields extends object>(): NodeConstructor<Fields & BaseNodeFields>;
};
declare function node<T extends string>(name: T): {
fields<Fields extends object>(): TypedNodeConstructor<T, Fields & BaseNodeFields>;
};
interface NodeConstructor<Fields> {
new (fields: Fields): Readonly<Fields>;
}
type TypedNode<T extends string, Fields> = {
type: T;
} & Readonly<Fields>;
interface TypedNodeConstructor<T extends string, Fields> {
new (options: Fields): TypedNode<T, Fields>;
}
/**
* Attr nodes look like HTML attributes, but are classified as:
*
* 1. `HtmlAttr`, which means a regular HTML attribute in Glimmer
* 2. `SplatAttr`, which means `...attributes`
* 3. `ComponentArg`, which means an attribute whose name begins with `@`, and it is therefore a
* component argument.
*/
type AttrNode = HtmlAttr | SplatAttr | ComponentArg;
/**
* `HtmlAttr` and `SplatAttr` are grouped together because the order of the `SplatAttr` node,
* relative to other attributes, matters.
*/
type HtmlOrSplatAttr = HtmlAttr | SplatAttr;
/**
* "Attr Block" nodes are allowed inside an open element tag in templates. They interact with the
* element (or component).
*/
type AttrBlockNode = AttrNode | ElementModifier;
declare const HtmlAttr_base: TypedNodeConstructor<"HtmlAttr", AttrNodeOptions & BaseNodeFields>;
/**
* `HtmlAttr` nodes are valid HTML attributes, with or without a value.
*
* Exceptions:
*
* - `...attributes` is `SplatAttr`
* - `@x=<value>` is `ComponentArg`
*/
declare class HtmlAttr extends HtmlAttr_base {
}
declare const SplatAttr_base: TypedNodeConstructor<"SplatAttr", {
symbol: number;
} & BaseNodeFields>;
declare class SplatAttr extends SplatAttr_base {
}
declare const ComponentArg_base: NodeConstructor<AttrNodeOptions & BaseNodeFields>;
/**
* Corresponds to an argument passed by a component (`@x=<value>`)
*/
declare class ComponentArg extends ComponentArg_base {
/**
* Convert the component argument into a named argument node
*/
toNamedArgument(): NamedArgument;
}
declare const ElementModifier_base: TypedNodeConstructor<"ElementModifier", CallFields & BaseNodeFields>;
/**
* An `ElementModifier` is just a normal call node in modifier position.
*/
declare class ElementModifier extends ElementModifier_base {
}
interface AttrNodeOptions {
name: SourceSlice;
value: ExpressionNode;
trusting: boolean;
}
declare const Template_base: NodeConstructor<{
table: ProgramSymbolTable;
} & GlimmerParentNodeOptions & BaseNodeFields>;
/**
* Corresponds to an entire template.
*/
declare class Template extends Template_base {
}
declare const Block_base: NodeConstructor<{
scope: BlockSymbolTable;
} & GlimmerParentNodeOptions & BaseNodeFields>;
/**
* Represents a block. In principle this could be merged with `NamedBlock`, because all cases
* involving blocks have at least a notional name.
*/
declare class Block extends Block_base {
}
declare const NamedBlocks_base: NodeConstructor<{
blocks: readonly NamedBlock[];
} & BaseNodeFields>;
/**
* Corresponds to a collection of named blocks.
*/
declare class NamedBlocks extends NamedBlocks_base {
/**
* Get the `NamedBlock` for a given name.
*/
get(name: 'default'): NamedBlock;
get(name: string): NamedBlock | null;
}
interface NamedBlockFields extends BaseNodeFields {
name: SourceSlice;
block: Block;
attrs: readonly HtmlOrSplatAttr[];
componentArgs: readonly ComponentArg[];
modifiers: readonly ElementModifier[];
}
declare const NamedBlock_base: NodeConstructor<NamedBlockFields & BaseNodeFields>;
/**
* Corresponds to a single named block. This is used for anonymous named blocks (`default` and
* `else`).
*/
declare class NamedBlock extends NamedBlock_base {
get args(): Args;
}
/**
* Content Nodes are allowed in content positions in templates. They correspond to behavior in the
* [Data][data] tokenization state in HTML.
*
* [data]: https://html.spec.whatwg.org/multipage/parsing.html#data-state
*/
type ContentNode = HtmlText | HtmlComment | AppendContent | InvokeBlock | InvokeComponent | SimpleElement | GlimmerComment;
declare const GlimmerComment_base: TypedNodeConstructor<"GlimmerComment", {
text: SourceSlice;
} & BaseNodeFields>;
declare class GlimmerComment extends GlimmerComment_base {
}
declare const HtmlText_base: TypedNodeConstructor<"HtmlText", {
chars: string;
} & BaseNodeFields>;
declare class HtmlText extends HtmlText_base {
}
declare const HtmlComment_base: TypedNodeConstructor<"HtmlComment", {
text: SourceSlice;
} & BaseNodeFields>;
declare class HtmlComment extends HtmlComment_base {
}
declare const AppendContent_base: TypedNodeConstructor<"AppendContent", {
value: ExpressionNode;
trusting: boolean;
table: SymbolTable;
} & BaseNodeFields>;
declare class AppendContent extends AppendContent_base {
get callee(): ExpressionNode;
get args(): Args;
}
declare const InvokeBlock_base: TypedNodeConstructor<"InvokeBlock", CallFields & {
blocks: NamedBlocks;
} & BaseNodeFields>;
declare class InvokeBlock extends InvokeBlock_base {
}
interface InvokeComponentFields {
callee: ExpressionNode;
blocks: NamedBlocks;
attrs: readonly HtmlOrSplatAttr[];
componentArgs: readonly ComponentArg[];
modifiers: readonly ElementModifier[];
}
declare const InvokeComponent_base: TypedNodeConstructor<"InvokeComponent", InvokeComponentFields & BaseNodeFields>;
/**
* Corresponds to a component invocation. When the content of a component invocation contains no
* named blocks, `blocks` contains a single named block named `"default"`. When a component
* invocation is self-closing, `blocks` is empty.
*/
declare class InvokeComponent extends InvokeComponent_base {
get args(): Args;
}
interface SimpleElementOptions extends BaseNodeFields {
tag: SourceSlice;
body: readonly ContentNode[];
attrs: readonly HtmlOrSplatAttr[];
componentArgs: readonly ComponentArg[];
modifiers: readonly ElementModifier[];
}
declare const SimpleElement_base: TypedNodeConstructor<"SimpleElement", SimpleElementOptions & BaseNodeFields>;
/**
* Corresponds to a simple HTML element. The AST allows component arguments and modifiers to support
* future extensions.
*/
declare class SimpleElement extends SimpleElement_base {
get args(): Args;
}
type ElementNode = NamedBlock | InvokeComponent | SimpleElement;
interface SerializedBaseNode {
loc: SerializedSourceSpan;
}
interface GlimmerParentNodeOptions extends BaseNodeFields {
body: readonly ContentNode[];
}
interface CallFields extends BaseNodeFields {
callee: CalleeNode;
args: Args;
}
type CalleeNode = KeywordExpression | PathExpression | CallExpression;
type CallNode = CallExpression | InvokeBlock | AppendContent | InvokeComponent | ElementModifier;
type HELPER_VAR_NS = 'Helper';
declare const HELPER_VAR_NS: HELPER_VAR_NS;
type MODIFIER_VAR_NS = 'Modifier';
declare const MODIFIER_VAR_NS: MODIFIER_VAR_NS;
type COMPONENT_VAR_NS = 'Component';
declare const COMPONENT_VAR_NS: COMPONENT_VAR_NS;
type FreeVarNamespace = HELPER_VAR_NS | MODIFIER_VAR_NS | COMPONENT_VAR_NS;
/**
* A free variable is resolved according to a resolution rule:
*
* 1. Strict resolution
* 2. Namespaced resolution
*/
/**
* Strict resolution is used:
*
* 1. in a strict mode template
* 2. in an local variable invocation with dot paths
*/
declare const STRICT_RESOLUTION: {
resolution: () => GetContextualFreeOpcode;
serialize: () => SerializedResolution;
isAngleBracket: false;
};
type StrictResolution = typeof STRICT_RESOLUTION;
declare const HTML_RESOLUTION: {
isAngleBracket: true;
resolution: () => GetContextualFreeOpcode;
serialize: () => SerializedResolution;
};
type HtmlResolution = typeof HTML_RESOLUTION;
declare function isStrictResolution(value: unknown): value is StrictResolution;
/**
* A `LooseModeResolution` includes one or more namespaces to resolve the variable in
*
* In practice, there are a limited number of possible combinations of these degrees of freedom,
* and they are captured by the `Namespaces` union below.
*/
declare class LooseModeResolution {
readonly namespaces: Namespaces;
readonly isAngleBracket: boolean;
/**
* Namespaced resolution is used in an unambiguous syntax position:
*
* 1. `(sexp)` (namespace: `Helper`)
* 2. `{{#block}}` (namespace: `Component`)
* 3. `<a {{modifier}}>` (namespace: `Modifier`)
* 4. `<Component />` (namespace: `Component`)
*/
static namespaced(namespace: FreeVarNamespace, isAngleBracket?: boolean): LooseModeResolution;
/**
* Append resolution is used when the variable should be resolved in both the `component` and
* `helper` namespaces.
*
* ```hbs
* {{x}}
* ```
*
* ```hbs
* {{x y}}
* ```
*
* ^ In either case, `x` should be resolved in the `component` and `helper` namespaces.
*/
static append(): LooseModeResolution;
/**
* Trusting append resolution is used when the variable should be resolved only in the
* `helper` namespaces.
*
* ```hbs
* {{{x}}}
* ```
*
* ```hbs
* {{{x y}}}
* ```
*
* ^ In either case, `x` should be resolved in the `helper` namespace.
*/
static trustingAppend(): LooseModeResolution;
constructor(namespaces: Namespaces, isAngleBracket?: boolean);
resolution(): GetContextualFreeOpcode;
serialize(): SerializedResolution;
}
declare const HELPER_NAMESPACE: "Helper";
declare const MODIFIER_NAMESPACE: "Modifier";
declare const COMPONENT_NAMESPACE: "Component";
/**
* A `Namespaced` must be resolved in one or more namespaces.
*
* ```hbs
* <X />
* ```
*
* ^ `X` is resolved in the `component` namespace
*
* ```hbs
* (x)
* ```
*
* ^ `x` is resolved in the `helper` namespace
*
* ```hbs
* <a {{x}} />
* ```
*
* ^ `x` is resolved in the `modifier` namespace
*/
type Namespaces = [HELPER_VAR_NS] | [MODIFIER_VAR_NS] | [COMPONENT_VAR_NS] | [COMPONENT_VAR_NS, HELPER_VAR_NS];
type FreeVarResolution = StrictResolution | HtmlResolution | LooseModeResolution;
type SerializedResolution = 'Strict' | 'Helper' | 'Modifier' | 'Component' | 'ComponentOrHelper';
declare function loadResolution(resolution: SerializedResolution): FreeVarResolution;
declare const ThisReference_base: TypedNodeConstructor<"This", object & BaseNodeFields>;
/**
* Corresponds to `this` at the head of an expression.
*/
declare class ThisReference extends ThisReference_base {
}
declare const ArgReference_base: TypedNodeConstructor<"Arg", {
name: SourceSlice;
symbol: number;
} & BaseNodeFields>;
/**
* Corresponds to `@<ident>` at the beginning of an expression.
*/
declare class ArgReference extends ArgReference_base {
}
declare const LocalVarReference_base: TypedNodeConstructor<"Local", {
name: string;
isTemplateLocal: boolean;
symbol: number;
} & BaseNodeFields>;
/**
* Corresponds to `<ident>` at the beginning of an expression, when `<ident>` is in the current
* block's scope.
*/
declare class LocalVarReference extends LocalVarReference_base {
}
declare const FreeVarReference_base: TypedNodeConstructor<"Free", {
name: string;
resolution: FreeVarResolution;
symbol: number;
} & BaseNodeFields>;
/**
* Corresponds to `<ident>` at the beginning of an expression, when `<ident>` is *not* in the
* current block's scope.
*
* The `resolution: FreeVarResolution` field describes how to resolve the free variable.
*
* Note: In strict mode, it must always be a variable that is in a concrete JavaScript scope that
* the template will be installed into.
*/
declare class FreeVarReference extends FreeVarReference_base {
}
type VariableReference = ThisReference | ArgReference | LocalVarReference | FreeVarReference;
/**
* A Handlebars literal.
*
* {@link https://handlebarsjs.com/guide/expressions.html#literal-segments}
*/
type LiteralValue = string | boolean | number | undefined | null;
interface LiteralTypes {
string: string;
boolean: boolean;
number: number;
null: null;
undefined: undefined;
}
declare const LiteralExpression_base: TypedNodeConstructor<"Literal", {
value: LiteralValue;
} & BaseNodeFields>;
/**
* Corresponds to a Handlebars literal.
*
* @see {LiteralValue}
*/
declare class LiteralExpression extends LiteralExpression_base {
toSlice(this: StringLiteral): SourceSlice;
}
type StringLiteral = LiteralExpression & {
value: string;
};
/**
* Returns true if an input {@see ExpressionNode} is a literal.
*/
declare function isLiteral<K extends keyof LiteralTypes = keyof LiteralTypes>(node: ExpressionNode, kind?: K): node is StringLiteral;
declare const PathExpression_base: TypedNodeConstructor<"Path", {
ref: VariableReference;
tail: readonly SourceSlice[];
} & BaseNodeFields>;
/**
* Corresponds to a path in expression position.
*
* ```hbs
* this
* this.x
* @x
* @x.y
* x
* x.y
* ```
*/
declare class PathExpression extends PathExpression_base {
}
declare const KeywordExpression_base: TypedNodeConstructor<"Keyword", {
name: string;
symbol: number;
} & BaseNodeFields>;
/**
* Corresponds to a known strict-mode keyword. It behaves similarly to a
* PathExpression with a FreeVarReference, but implies StrictResolution and
* is guaranteed to not have a tail, since `{{outlet.foo}}` would have been
* illegal.
*/
declare class KeywordExpression extends KeywordExpression_base {
}
declare const CallExpression_base: TypedNodeConstructor<"Call", CallFields & BaseNodeFields>;
/**
* Corresponds to a parenthesized call expression.
*
* ```hbs
* (x)
* (x.y)
* (x y)
* (x.y z)
* ```
*/
declare class CallExpression extends CallExpression_base {
}
declare const InterpolateExpression_base: TypedNodeConstructor<"Interpolate", {
parts: PresentArray<ExpressionNode>;
} & BaseNodeFields>;
/**
* Corresponds to an interpolation in attribute value position.
*
* ```hbs
* <a href="{{url}}.html"
* ```
*/
declare class InterpolateExpression extends InterpolateExpression_base {
}
type ExpressionNode = LiteralExpression | PathExpression | KeywordExpression | CallExpression | InterpolateExpression;
declare const Args_base: NodeConstructor<{
positional: PositionalArguments;
named: NamedArguments;
} & BaseNodeFields>;
/**
* Corresponds to syntaxes with positional and named arguments:
*
* - SubExpression
* - Invoking Append
* - Invoking attributes
* - InvokeBlock
*
* If `Args` is empty, the `SourceOffsets` for this node should be the collapsed position
* immediately after the parent call node's `callee`.
*/
declare class Args extends Args_base {
static empty(loc: SourceSpan): Args;
static named(named: NamedArguments): Args;
nth(offset: number): ExpressionNode | null;
get(name: string): ExpressionNode | null;
isEmpty(): boolean;
}
declare const PositionalArguments_base: NodeConstructor<{
exprs: readonly ExpressionNode[];
} & BaseNodeFields>;
/**
* Corresponds to positional arguments.
*
* If `PositionalArguments` is empty, the `SourceOffsets` for this node should be the collapsed
* position immediately after the parent call node's `callee`.
*/
declare class PositionalArguments extends PositionalArguments_base {
static empty(loc: SourceSpan): PositionalArguments;
get size(): number;
nth(offset: number): ExpressionNode | null;
isEmpty(): boolean;
}
declare const NamedArguments_base: NodeConstructor<{
entries: readonly NamedArgument[];
} & BaseNodeFields>;
/**
* Corresponds to named arguments.
*
* If `PositionalArguments` and `NamedArguments` are empty, the `SourceOffsets` for this node should
* be the same as the `Args` node that contains this node.
*
* If `PositionalArguments` is not empty but `NamedArguments` is empty, the `SourceOffsets` for this
* node should be the collapsed position immediately after the last positional argument.
*/
declare class NamedArguments extends NamedArguments_base {
static empty(loc: SourceSpan): NamedArguments;
get size(): number;
get(name: string): ExpressionNode | null;
isEmpty(): boolean;
}
/**
* Corresponds to a single named argument.
*
* ```hbs
* x=<expr>
* ```
*/
declare class NamedArgument {
readonly loc: SourceSpan;
readonly name: SourceSlice;
readonly value: ExpressionNode;
constructor(options: {
name: SourceSlice;
value: ExpressionNode;
});
}
type api_AppendContent = AppendContent;
declare const api_AppendContent: typeof AppendContent;
type api_ArgReference = ArgReference;
declare const api_ArgReference: typeof ArgReference;
type api_Args = Args;
declare const api_Args: typeof Args;
type api_AttrBlockNode = AttrBlockNode;
type api_AttrNode = AttrNode;
type api_AttrNodeOptions = AttrNodeOptions;
type api_BaseNodeFields = BaseNodeFields;
type api_Block = Block;
declare const api_Block: typeof Block;
declare const api_COMPONENT_NAMESPACE: typeof COMPONENT_NAMESPACE;
type api_CallExpression = CallExpression;
declare const api_CallExpression: typeof CallExpression;
type api_CallFields = CallFields;
type api_CallNode = CallNode;
type api_CalleeNode = CalleeNode;
type api_ComponentArg = ComponentArg;
declare const api_ComponentArg: typeof ComponentArg;
type api_ContentNode = ContentNode;
type api_ElementModifier = ElementModifier;
declare const api_ElementModifier: typeof ElementModifier;
type api_ElementNode = ElementNode;
type api_ExpressionNode = ExpressionNode;
type api_FreeVarReference = FreeVarReference;
declare const api_FreeVarReference: typeof FreeVarReference;
type api_FreeVarResolution = FreeVarResolution;
type api_GlimmerComment = GlimmerComment;
declare const api_GlimmerComment: typeof GlimmerComment;
type api_GlimmerParentNodeOptions = GlimmerParentNodeOptions;
declare const api_HELPER_NAMESPACE: typeof HELPER_NAMESPACE;
declare const api_HTML_RESOLUTION: typeof HTML_RESOLUTION;
type api_HtmlAttr = HtmlAttr;
declare const api_HtmlAttr: typeof HtmlAttr;
type api_HtmlComment = HtmlComment;
declare const api_HtmlComment: typeof HtmlComment;
type api_HtmlOrSplatAttr = HtmlOrSplatAttr;
type api_HtmlResolution = HtmlResolution;
type api_HtmlText = HtmlText;
declare const api_HtmlText: typeof HtmlText;
type api_InterpolateExpression = InterpolateExpression;
declare const api_InterpolateExpression: typeof InterpolateExpression;
type api_InvokeBlock = InvokeBlock;
declare const api_InvokeBlock: typeof InvokeBlock;
type api_InvokeComponent = InvokeComponent;
declare const api_InvokeComponent: typeof InvokeComponent;
type api_KeywordExpression = KeywordExpression;
declare const api_KeywordExpression: typeof KeywordExpression;
type api_LiteralExpression = LiteralExpression;
declare const api_LiteralExpression: typeof LiteralExpression;
type api_LiteralTypes = LiteralTypes;
type api_LiteralValue = LiteralValue;
type api_LocalVarReference = LocalVarReference;
declare const api_LocalVarReference: typeof LocalVarReference;
type api_LooseModeResolution = LooseModeResolution;
declare const api_LooseModeResolution: typeof LooseModeResolution;
declare const api_MODIFIER_NAMESPACE: typeof MODIFIER_NAMESPACE;
type api_NamedArgument = NamedArgument;
declare const api_NamedArgument: typeof NamedArgument;
type api_NamedArguments = NamedArguments;
declare const api_NamedArguments: typeof NamedArguments;
type api_NamedBlock = NamedBlock;
declare const api_NamedBlock: typeof NamedBlock;
type api_NamedBlockFields = NamedBlockFields;
type api_NamedBlocks = NamedBlocks;
declare const api_NamedBlocks: typeof NamedBlocks;
type api_NodeConstructor<Fields> = NodeConstructor<Fields>;
type api_PathExpression = PathExpression;
declare const api_PathExpression: typeof PathExpression;
type api_PositionalArguments = PositionalArguments;
declare const api_PositionalArguments: typeof PositionalArguments;
declare const api_STRICT_RESOLUTION: typeof STRICT_RESOLUTION;
type api_SerializedBaseNode = SerializedBaseNode;
type api_SerializedResolution = SerializedResolution;
type api_SimpleElement = SimpleElement;
declare const api_SimpleElement: typeof SimpleElement;
type api_SplatAttr = SplatAttr;
declare const api_SplatAttr: typeof SplatAttr;
type api_StrictResolution = StrictResolution;
type api_StringLiteral = StringLiteral;
type api_Template = Template;
declare const api_Template: typeof Template;
type api_ThisReference = ThisReference;
declare const api_ThisReference: typeof ThisReference;
type api_TypedNodeConstructor<T extends string, Fields> = TypedNodeConstructor<T, Fields>;
type api_VariableReference = VariableReference;
declare const api_isLiteral: typeof isLiteral;
declare const api_isStrictResolution: typeof isStrictResolution;
declare const api_loadResolution: typeof loadResolution;
declare const api_node: typeof node;
declare namespace api {
export { api_AppendContent as AppendContent, api_ArgReference as ArgReference, api_Args as Args, api_Block as Block, api_COMPONENT_NAMESPACE as COMPONENT_NAMESPACE, api_CallExpression as CallExpression, api_ComponentArg as ComponentArg, api_ElementModifier as ElementModifier, api_FreeVarReference as FreeVarReference, api_GlimmerComment as GlimmerComment, api_HELPER_NAMESPACE as HELPER_NAMESPACE, api_HTML_RESOLUTION as HTML_RESOLUTION, api_HtmlAttr as HtmlAttr, api_HtmlComment as HtmlComment, api_HtmlText as HtmlText, api_InterpolateExpression as InterpolateExpression, api_InvokeBlock as InvokeBlock, api_InvokeComponent as InvokeComponent, api_KeywordExpression as KeywordExpression, api_LiteralExpression as LiteralExpression, api_LocalVarReference as LocalVarReference, api_LooseModeResolution as LooseModeResolution, api_MODIFIER_NAMESPACE as MODIFIER_NAMESPACE, api_NamedArgument as NamedArgument, api_NamedArguments as NamedArguments, api_NamedBlock as NamedBlock, api_NamedBlocks as NamedBlocks, api_PathExpression as PathExpression, api_PositionalArguments as PositionalArguments, api_STRICT_RESOLUTION as STRICT_RESOLUTION, api_SimpleElement as SimpleElement, api_SplatAttr as SplatAttr, api_Template as Template, api_ThisReference as ThisReference, api_isLiteral as isLiteral, api_isStrictResolution as isStrictResolution, api_loadResolution as loadResolution, api_node as node };
export type { api_AttrBlockNode as AttrBlockNode, api_AttrNode as AttrNode, api_AttrNodeOptions as AttrNodeOptions, api_BaseNodeFields as BaseNodeFields, api_CallFields as CallFields, api_CallNode as CallNode, api_CalleeNode as CalleeNode, api_ContentNode as ContentNode, api_ElementNode as ElementNode, api_ExpressionNode as ExpressionNode, api_FreeVarResolution as FreeVarResolution, api_GlimmerParentNodeOptions as GlimmerParentNodeOptions, api_HtmlOrSplatAttr as HtmlOrSplatAttr, api_HtmlResolution as HtmlResolution, api_LiteralTypes as LiteralTypes, api_LiteralValue as LiteralValue, api_NamedBlockFields as NamedBlockFields, api_NodeConstructor as NodeConstructor, api_SerializedBaseNode as SerializedBaseNode, api_SerializedResolution as SerializedResolution, api_StrictResolution as StrictResolution, api_StringLiteral as StringLiteral, api_TypedNodeConstructor as TypedNodeConstructor, api_VariableReference as VariableReference };
}
interface SymbolTableOptions {
customizeComponentName: (input: string) => string;
lexicalScope: (variable: string) => boolean;
}
declare abstract class SymbolTable {
static top(locals: readonly string[], keywords: readonly string[], options: SymbolTableOptions): ProgramSymbolTable;
abstract root(): ProgramSymbolTable;
abstract has(name: string): boolean;
abstract get(name: string): [symbol: number, isRoot: boolean];
abstract hasKeyword(name: string): boolean;
abstract getKeyword(name: string): number;
abstract hasLexical(name: string): boolean;
abstract getLocalsMap(): Dict<number>;
abstract getDebugInfo(): Core.DebugSymbols;
abstract allocateFree(name: string, resolution: FreeVarResolution): number;
abstract allocateNamed(name: string): number;
abstract allocateBlock(name: string): number;
abstract allocate(identifier: string): number;
child(locals: string[]): BlockSymbolTable;
}
declare class ProgramSymbolTable extends SymbolTable {
private templateLocals;
private keywords;
private options;
constructor(templateLocals: readonly string[], keywords: readonly string[], options: SymbolTableOptions);
readonly symbols: string[];
readonly upvars: string[];
private size;
readonly named: Dict<number>;
readonly blocks: Dict<number>;
readonly usedTemplateLocals: string[];
root(): this;
hasLexical(name: string): boolean;
hasKeyword(name: string): boolean;
getKeyword(name: string): number;
getUsedTemplateLocals(): string[];
has(name: string): boolean;
get(name: string): [number, boolean];
getLocalsMap(): Dict<number>;
getDebugInfo(): Core.DebugSymbols;
allocateFree(name: string, resolution: FreeVarResolution): number;
allocateNamed(name: string): number;
allocateBlock(name: string): number;
allocate(identifier: string): number;
}
declare class BlockSymbolTable extends SymbolTable {
#private;
private parent;
symbols: string[];
slots: number[];
constructor(parent: SymbolTable, symbols: string[], slots: number[]);
root(): ProgramSymbolTable;
get locals(): string[];
hasLexical(name: string): boolean;
getKeyword(name: string): number;
hasKeyword(name: string): boolean;
has(name: string): boolean;
get(name: string): [number, boolean];
getLocalsMap(): Dict<number>;
getDebugInfo(): [locals: Record<string, number>, upvars: Record<string, number>];
allocateFree(name: string, resolution: FreeVarResolution): number;
allocateNamed(name: string): number;
allocateBlock(name: string): number;
allocate(identifier: string): number;
}
interface GlimmerSyntaxError extends Error {
location: SourceSpan | null;
code: string | null;
}
declare function generateSyntaxError(message: string, location: SourceSpan): GlimmerSyntaxError;
interface TraversalErrorConstructor {
new (message: string, node: Node, parent: Nullable<Node>, key: string): TraversalError;
readonly prototype: TraversalError;
}
interface TraversalError extends Error {
constructor: TraversalErrorConstructor;
key: string;
node: Node;
parent: Nullable<Node>;
stack?: string;
}
declare const TraversalError: TraversalErrorConstructor;
declare function cannotRemoveNode(node: Node, parent: Node, key: string): TraversalError;
declare function cannotReplaceNode(node: Node, parent: Node, key: string): TraversalError;
declare function normalize(source: Source, options?: PrecompileOptionsWithLexicalScope): [ast: Template, locals: string[]];
export { api$1 as AST, api$1 as ASTv1, api as ASTv2, BlockSymbolTable, KEYWORDS_TYPES, Walker as Path, ProgramSymbolTable, SourceSlice, SpanList, SymbolTable, Walker, WalkerPath, _default as builders, cannotRemoveNode, cannotReplaceNode, generateSyntaxError, getTemplateLocals, getVoidTags, hasSpan, isKeyword, isVoidTag, loc, maybeLoc, node, normalize, preprocess, build as print, sortByLoc, api$2 as src, traverse, visitorKeys };
export type { ASTPlugin, ASTPluginBuilder, ASTPluginEnvironment, GlimmerSyntaxError, HasSourceSpan, KeywordType, MaybeHasSourceSpan, NodeVisitor, PrecompileOptions, PrecompileOptionsWithLexicalScope, PreprocessOptions, Syntax, TemplateIdFn };