UNPKG

15.9 kBTypeScriptView Raw
1import { PresentArray } from '../array';
2import { Dict, Option } from '../core';
3import { CurriedType } from '../curry';
4
5export type TupleSyntax = Statement | TupleExpression;
6
7type JsonValue = string | number | boolean | JsonObject | JsonArray;
8
9interface JsonObject extends Dict<JsonValue> {}
10interface JsonArray extends Array<JsonValue> {}
11
12export type TemplateReference = Option<SerializedBlock>;
13export type YieldTo = number;
14
15/**
16 * A VariableResolutionContext explains how a variable name should be resolved.
17 */
18export const enum VariableResolutionContext {
19 Strict = 0,
20 AmbiguousAppend = 1,
21 AmbiguousAppendInvoke = 2,
22 AmbiguousInvoke = 3,
23 LooseFreeVariable = 4,
24 ResolveAsCallHead = 5,
25 ResolveAsModifierHead = 6,
26 ResolveAsComponentHead = 7,
27}
28
29export const enum SexpOpcodes {
30 // Statements
31 Append = 1,
32 TrustingAppend = 2,
33 Comment = 3,
34 Modifier = 4,
35 StrictModifier = 5,
36 Block = 6,
37 StrictBlock = 7,
38 Component = 8,
39
40 OpenElement = 10,
41 OpenElementWithSplat = 11,
42 FlushElement = 12,
43 CloseElement = 13,
44 StaticAttr = 14,
45 DynamicAttr = 15,
46 ComponentAttr = 16,
47
48 AttrSplat = 17,
49 Yield = 18,
50 Partial = 19,
51
52 DynamicArg = 20,
53 StaticArg = 21,
54 TrustingDynamicAttr = 22,
55 TrustingComponentAttr = 23,
56 StaticComponentAttr = 24,
57
58 Debugger = 26,
59
60 // Expressions
61 Undefined = 27,
62 Call = 28,
63 Concat = 29,
64
65 // Get
66 // Get a local value via symbol
67 GetSymbol = 30, // GetPath + 0-2,
68 // Template symbol are values that are in scope in the template in strict mode
69 GetTemplateSymbol = 32,
70 // Free variables are only keywords in strict mode
71 GetStrictFree = 31,
72
73 // falls back to `this.` (or locals in the case of partials), but
74 // never turns into a component or helper invocation
75 GetFreeAsFallback = 33,
76 // `{{x}}` in append position (might be a helper or component invocation, otherwise fall back to `this`)
77 GetFreeAsComponentOrHelperHeadOrThisFallback = 34,
78 // a component or helper (`{{<expr> x}}` in append position)
79 GetFreeAsComponentOrHelperHead = 35,
80 // a helper or `this` fallback `attr={{x}}`
81 GetFreeAsHelperHeadOrThisFallback = 36,
82 // a helper or `this` fallback (deprecated) `@arg={{x}}`
83 GetFreeAsDeprecatedHelperHeadOrThisFallback = 99,
84 // a call head `(x)`
85 GetFreeAsHelperHead = 37,
86 GetFreeAsModifierHead = 38,
87 GetFreeAsComponentHead = 39,
88
89 // Keyword Statements
90 InElement = 40,
91 If = 41,
92 Each = 42,
93 With = 43,
94 Let = 44,
95 WithDynamicVars = 45,
96 InvokeComponent = 46,
97
98 // Keyword Expressions
99 HasBlock = 48,
100 HasBlockParams = 49,
101 Curry = 50,
102 Not = 51,
103 IfInline = 52,
104 GetDynamicVar = 53,
105 Log = 54,
106
107 GetStart = GetSymbol,
108 GetEnd = GetFreeAsComponentHead,
109 GetLooseFreeStart = GetFreeAsComponentOrHelperHeadOrThisFallback,
110 GetLooseFreeEnd = GetFreeAsComponentHead,
111 GetContextualFreeStart = GetFreeAsComponentOrHelperHeadOrThisFallback,
112}
113
114export type GetContextualFreeOp =
115 | SexpOpcodes.GetFreeAsComponentOrHelperHeadOrThisFallback
116 | SexpOpcodes.GetFreeAsComponentOrHelperHead
117 | SexpOpcodes.GetFreeAsHelperHeadOrThisFallback
118 | SexpOpcodes.GetFreeAsHelperHead
119 | SexpOpcodes.GetFreeAsModifierHead
120 | SexpOpcodes.GetFreeAsComponentHead
121 | SexpOpcodes.GetFreeAsFallback
122 | SexpOpcodes.GetStrictFree;
123
124export type AttrOp =
125 | SexpOpcodes.StaticAttr
126 | SexpOpcodes.StaticComponentAttr
127 | SexpOpcodes.DynamicAttr
128 | SexpOpcodes.TrustingDynamicAttr
129 | SexpOpcodes.ComponentAttr
130 | SexpOpcodes.TrustingComponentAttr;
131
132export type StatementSexpOpcode = Statement[0];
133export type StatementSexpOpcodeMap = {
134 [TSexpOpcode in Statement[0]]: Extract<Statement, { 0: TSexpOpcode }>;
135};
136export type ExpressionSexpOpcode = TupleExpression[0];
137export type ExpressionSexpOpcodeMap = {
138 [TSexpOpcode in TupleExpression[0]]: Extract<TupleExpression, { 0: TSexpOpcode }>;
139};
140
141export interface SexpOpcodeMap extends ExpressionSexpOpcodeMap, StatementSexpOpcodeMap {}
142export type SexpOpcode = keyof SexpOpcodeMap;
143
144export namespace Core {
145 export type Expression = Expressions.Expression;
146
147 export type CallArgs = [Params, Hash];
148 export type Path = [string, ...string[]];
149 export type ConcatParams = PresentArray<Expression>;
150 export type Params = Option<ConcatParams>;
151 export type Hash = Option<[PresentArray<string>, PresentArray<Expression>]>;
152 export type Blocks = Option<[string[], SerializedInlineBlock[]]>;
153 export type Args = [Params, Hash];
154 export type NamedBlock = [string, SerializedInlineBlock];
155 export type EvalInfo = number[];
156 export type ElementParameters = Option<PresentArray<ElementParameter>>;
157
158 export type Syntax = Path | Params | ConcatParams | Hash | Blocks | Args | EvalInfo;
159}
160
161export type CoreSyntax = Core.Syntax;
162
163export namespace Expressions {
164 export type Path = Core.Path;
165 export type Params = Core.Params;
166 export type Hash = Core.Hash;
167
168 export type GetSymbol = [SexpOpcodes.GetSymbol, number];
169 export type GetTemplateSymbol = [SexpOpcodes.GetTemplateSymbol, number];
170 export type GetStrictFree = [SexpOpcodes.GetStrictFree, number];
171 export type GetFreeAsFallback = [SexpOpcodes.GetFreeAsFallback, number];
172 export type GetFreeAsComponentOrHelperHeadOrThisFallback = [
173 SexpOpcodes.GetFreeAsComponentOrHelperHeadOrThisFallback,
174 number
175 ];
176 export type GetFreeAsComponentOrHelperHead = [SexpOpcodes.GetFreeAsComponentOrHelperHead, number];
177 export type GetFreeAsHelperHeadOrThisFallback = [
178 SexpOpcodes.GetFreeAsHelperHeadOrThisFallback,
179 number
180 ];
181 export type GetFreeAsDeprecatedHelperHeadOrThisFallback = [
182 SexpOpcodes.GetFreeAsDeprecatedHelperHeadOrThisFallback,
183 number
184 ];
185 export type GetFreeAsHelperHead = [SexpOpcodes.GetFreeAsHelperHead, number];
186 export type GetFreeAsModifierHead = [SexpOpcodes.GetFreeAsModifierHead, number];
187 export type GetFreeAsComponentHead = [SexpOpcodes.GetFreeAsComponentHead, number];
188
189 export type GetContextualFree =
190 | GetFreeAsFallback
191 | GetFreeAsComponentOrHelperHeadOrThisFallback
192 | GetFreeAsComponentOrHelperHead
193 | GetFreeAsHelperHeadOrThisFallback
194 | GetFreeAsDeprecatedHelperHeadOrThisFallback
195 | GetFreeAsHelperHead
196 | GetFreeAsModifierHead
197 | GetFreeAsComponentHead;
198 export type GetFree = GetStrictFree | GetContextualFree;
199 export type GetVar = GetSymbol | GetTemplateSymbol | GetFree;
200
201 export type GetPathSymbol = [SexpOpcodes.GetSymbol, number, Path];
202 export type GetPathTemplateSymbol = [SexpOpcodes.GetTemplateSymbol, number, Path];
203 export type GetPathStrictFree = [SexpOpcodes.GetStrictFree, number, Path];
204 export type GetPathFreeAsFallback = [SexpOpcodes.GetFreeAsFallback, number, Path];
205 export type GetPathFreeAsComponentOrHelperHeadOrThisFallback = [
206 SexpOpcodes.GetFreeAsComponentOrHelperHeadOrThisFallback,
207 number,
208 Path
209 ];
210 export type GetPathFreeAsComponentOrHelperHead = [
211 SexpOpcodes.GetFreeAsComponentOrHelperHead,
212 number,
213 Path
214 ];
215 export type GetPathFreeAsHelperHeadOrThisFallback = [
216 SexpOpcodes.GetFreeAsHelperHeadOrThisFallback,
217 number,
218 Path
219 ];
220 export type GetPathFreeAsDeprecatedHelperHeadOrThisFallback = [
221 SexpOpcodes.GetFreeAsDeprecatedHelperHeadOrThisFallback,
222 number,
223 Path
224 ];
225 export type GetPathFreeAsHelperHead = [SexpOpcodes.GetFreeAsHelperHead, number, Path];
226 export type GetPathFreeAsModifierHead = [SexpOpcodes.GetFreeAsModifierHead, number, Path];
227 export type GetPathFreeAsComponentHead = [SexpOpcodes.GetFreeAsComponentHead, number, Path];
228
229 export type GetPathContextualFree =
230 | GetPathFreeAsFallback
231 | GetPathFreeAsComponentOrHelperHeadOrThisFallback
232 | GetPathFreeAsComponentOrHelperHead
233 | GetPathFreeAsHelperHeadOrThisFallback
234 | GetPathFreeAsDeprecatedHelperHeadOrThisFallback
235 | GetPathFreeAsHelperHead
236 | GetPathFreeAsModifierHead
237 | GetPathFreeAsComponentHead;
238 export type GetPathFree = GetPathStrictFree | GetPathContextualFree;
239 export type GetPath = GetPathSymbol | GetPathTemplateSymbol | GetPathFree;
240
241 export type Get = GetVar | GetPath;
242
243 export type StringValue = string;
244 export type NumberValue = number;
245 export type BooleanValue = boolean;
246 export type NullValue = null;
247 export type Value = StringValue | NumberValue | BooleanValue | NullValue;
248 export type Undefined = [SexpOpcodes.Undefined];
249
250 export type TupleExpression =
251 | Get
252 | GetDynamicVar
253 | Concat
254 | HasBlock
255 | HasBlockParams
256 | Curry
257 | Helper
258 | Undefined
259 | IfInline
260 | Not
261 | Log;
262
263 // TODO get rid of undefined, which is just here to allow trailing undefined in attrs
264 // it would be better to handle that as an over-the-wire encoding concern
265 export type Expression = TupleExpression | Value | undefined;
266
267 export type Concat = [SexpOpcodes.Concat, Core.ConcatParams];
268 export type Helper = [SexpOpcodes.Call, Expression, Option<Params>, Hash];
269 export type HasBlock = [SexpOpcodes.HasBlock, Expression];
270 export type HasBlockParams = [SexpOpcodes.HasBlockParams, Expression];
271 export type Curry = [SexpOpcodes.Curry, Expression, CurriedType, Params, Hash];
272
273 export type IfInline = [
274 op: SexpOpcodes.IfInline,
275 condition: Expression,
276 truthyValue: Expression,
277 falsyValue?: Option<Expression>
278 ];
279
280 export type Not = [op: SexpOpcodes.Not, value: Expression];
281
282 export type GetDynamicVar = [op: SexpOpcodes.GetDynamicVar, value: Expression];
283
284 export type Log = [op: SexpOpcodes.Log, positional: Params];
285}
286
287export type Expression = Expressions.Expression;
288export type Get = Expressions.GetVar;
289
290export type TupleExpression = Expressions.TupleExpression;
291
292export const enum WellKnownAttrName {
293 class = 0,
294 id = 1,
295 value = 2,
296 name = 3,
297 type = 4,
298 style = 5,
299 href = 6,
300}
301
302export const enum WellKnownTagName {
303 div = 0,
304 span = 1,
305 p = 2,
306 a = 3,
307}
308
309export namespace Statements {
310 export type Expression = Expressions.Expression | undefined;
311 export type Params = Core.Params;
312 export type Hash = Core.Hash;
313 export type Blocks = Core.Blocks;
314 export type Path = Core.Path;
315
316 export type Append = [SexpOpcodes.Append, Expression];
317 export type TrustingAppend = [SexpOpcodes.TrustingAppend, Expression];
318 export type Comment = [SexpOpcodes.Comment, string];
319 export type Modifier = [SexpOpcodes.Modifier, Expression, Params, Hash];
320 export type Block = [SexpOpcodes.Block, Expression, Params, Hash, Blocks];
321 export type Component = [
322 op: SexpOpcodes.Component,
323 tag: Expression,
324 parameters: Core.ElementParameters,
325 args: Hash,
326 blocks: Blocks
327 ];
328 export type OpenElement = [SexpOpcodes.OpenElement, string | WellKnownTagName];
329 export type OpenElementWithSplat = [SexpOpcodes.OpenElementWithSplat, string | WellKnownTagName];
330 export type FlushElement = [SexpOpcodes.FlushElement];
331 export type CloseElement = [SexpOpcodes.CloseElement];
332 export type StaticAttr = [
333 SexpOpcodes.StaticAttr,
334 string | WellKnownAttrName,
335 Expression,
336 string?
337 ];
338 export type StaticComponentAttr = [
339 SexpOpcodes.StaticComponentAttr,
340 string | WellKnownAttrName,
341 Expression,
342 string?
343 ];
344
345 export type AnyStaticAttr = StaticAttr | StaticComponentAttr;
346
347 export type AttrSplat = [SexpOpcodes.AttrSplat, YieldTo];
348 export type Yield = [SexpOpcodes.Yield, YieldTo, Option<Params>];
349 export type Partial = [SexpOpcodes.Partial, Expression, Core.EvalInfo];
350 export type DynamicArg = [SexpOpcodes.DynamicArg, string, Expression];
351 export type StaticArg = [SexpOpcodes.StaticArg, string, Expression];
352
353 export type DynamicAttr = [
354 SexpOpcodes.DynamicAttr,
355 string | WellKnownAttrName,
356 Expression,
357 string?
358 ];
359 export type ComponentAttr = [
360 SexpOpcodes.ComponentAttr,
361 string | WellKnownAttrName,
362 Expression,
363 string?
364 ];
365 export type TrustingDynamicAttr = [
366 SexpOpcodes.TrustingDynamicAttr,
367 string | WellKnownAttrName,
368 Expression,
369 string?
370 ];
371 export type TrustingComponentAttr = [
372 SexpOpcodes.TrustingComponentAttr,
373 string | WellKnownAttrName,
374 Expression,
375 string?
376 ];
377
378 export type AnyDynamicAttr =
379 | DynamicAttr
380 | ComponentAttr
381 | TrustingDynamicAttr
382 | TrustingComponentAttr;
383
384 export type Debugger = [SexpOpcodes.Debugger, Core.EvalInfo];
385 export type InElement = [
386 op: SexpOpcodes.InElement,
387 block: SerializedInlineBlock,
388 guid: string,
389 destination: Expression,
390 insertBefore?: Expression
391 ];
392
393 export type If = [
394 op: SexpOpcodes.If,
395 condition: Expression,
396 block: SerializedInlineBlock,
397 inverse: Option<SerializedInlineBlock>
398 ];
399
400 export type Each = [
401 op: SexpOpcodes.Each,
402 condition: Expression,
403 key: Option<Expression>,
404 block: SerializedInlineBlock,
405 inverse: Option<SerializedInlineBlock>
406 ];
407
408 export type With = [
409 op: SexpOpcodes.With,
410 value: Expression,
411 block: SerializedInlineBlock,
412 inverse: Option<SerializedInlineBlock>
413 ];
414
415 export type Let = [op: SexpOpcodes.Let, positional: Core.Params, block: SerializedInlineBlock];
416
417 export type WithDynamicVars = [
418 op: SexpOpcodes.WithDynamicVars,
419 args: Core.Hash,
420 block: SerializedInlineBlock
421 ];
422
423 export type InvokeComponent = [
424 op: SexpOpcodes.InvokeComponent,
425 definition: Expression,
426 positional: Core.Params,
427 named: Core.Hash,
428 blocks: Blocks | null
429 ];
430
431 /**
432 * A Handlebars statement
433 */
434 export type Statement =
435 | Append
436 | TrustingAppend
437 | Comment
438 | Modifier
439 | Block
440 | Component
441 | OpenElement
442 | OpenElementWithSplat
443 | FlushElement
444 | CloseElement
445 | Attribute
446 | AttrSplat
447 | Yield
448 | Partial
449 | StaticArg
450 | DynamicArg
451 | Debugger
452 | InElement
453 | If
454 | Each
455 | With
456 | Let
457 | WithDynamicVars
458 | InvokeComponent;
459
460 export type Attribute =
461 | StaticAttr
462 | StaticComponentAttr
463 | DynamicAttr
464 | TrustingDynamicAttr
465 | ComponentAttr
466 | TrustingComponentAttr;
467
468 export type ComponentFeature = Modifier | AttrSplat;
469 export type Argument = StaticArg | DynamicArg;
470
471 export type ElementParameter = Attribute | Argument | ComponentFeature;
472}
473
474/** A Handlebars statement */
475export type Statement = Statements.Statement;
476export type Attribute = Statements.Attribute;
477export type Argument = Statements.Argument;
478export type ElementParameter = Statements.ElementParameter;
479
480export type SexpSyntax = Statement | TupleExpression;
481// TODO this undefined is related to the other TODO in this file
482export type Syntax = SexpSyntax | Expressions.Value | undefined;
483
484export type SyntaxWithInternal =
485 | Syntax
486 | CoreSyntax
487 | SerializedTemplateBlock
488 | Core.CallArgs
489 | Core.NamedBlock
490 | Core.ElementParameters;
491
492/**
493 * A JSON object that the Block was serialized into.
494 */
495export type SerializedBlock = [statements: Statements.Statement[]];
496
497export type SerializedInlineBlock = [statements: Statements.Statement[], parameters: number[]];
498
499/**
500 * A JSON object that the compiled TemplateBlock was serialized into.
501 */
502export type SerializedTemplateBlock = [
503 // statements
504 Statements.Statement[],
505 // symbols
506 string[],
507 // hasEval
508 boolean,
509 // upvars
510 string[]
511];
512
513/**
514 * A JSON object that the compiled Template was serialized into.
515 */
516export interface SerializedTemplate {
517 block: SerializedTemplateBlock;
518 id?: Option<string>;
519 moduleName: string;
520}
521
522/**
523 * A string of JSON containing a SerializedTemplateBlock
524 */
525export type SerializedTemplateBlockJSON = string;
526
527/**
528 * A JSON object containing the SerializedTemplateBlock as JSON and TemplateMeta.
529 */
530export interface SerializedTemplateWithLazyBlock {
531 id?: Option<string>;
532 block: SerializedTemplateBlockJSON;
533 moduleName: string;
534 scope: (() => unknown[]) | undefined | null;
535 isStrictMode: boolean;
536}
537
538/**
539 * A string of Javascript containing a SerializedTemplateWithLazyBlock to be
540 * concatenated into a Javascript module.
541 */
542export type TemplateJavascript = string;
543
\No newline at end of file