From f50bf9b06486d804ed376984e15e0cb481110c82 Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Fri, 13 Dec 2024 00:33:44 +0100 Subject: [PATCH] refactor node handling --- cli/js/40_lint.js | 3896 +++++-------------------------------- cli/tools/lint/ast_buf.rs | 16 +- cli/tools/lint/swc.rs | 392 ++-- 3 files changed, 764 insertions(+), 3540 deletions(-) diff --git a/cli/js/40_lint.js b/cli/js/40_lint.js index 5e40b6724d..edd5abd311 100644 --- a/cli/js/40_lint.js +++ b/cli/js/40_lint.js @@ -42,20 +42,16 @@ export class Context { } report(data) { - let start, end; - - if (data.node) { - start = data.node.range[0] - 1; - end = data.node.range[1] - 1; - } else if (data.range) { - start = data.range[0] - 1; - end = data.range[1] - 1; - } else { + const range = data.node ? data.node.range : data.range ? data.range : null; + if (range == null) { throw new Error( "Either `node` or `span` must be provided when reporting an error", ); } + const start = range[0] - 1; + const end = range[1] - 1; + op_lint_report( this.id, this.fileName, @@ -314,14 +310,17 @@ const AstProp = [ "closingFragment", "computed", "consequent", + "cooked", "declarations", "declare", "definite", "delegate", - "discrimininant", + "discriminant", "elements", + "elementTypes", "expression", "expressions", + "exported", "finalizer", "flags", "generator", @@ -332,6 +331,7 @@ const AstProp = [ "kind", "label", "left", + "local", "members", "meta", "method", @@ -342,6 +342,7 @@ const AstProp = [ "openingFragment", "operator", "optional", + "param", "params", "pattern", "prefix", @@ -362,14 +363,53 @@ const AstProp = [ "typeAnnotation", "typeArguments", "typeParameters", + "types", "update", "value", ]; const AST_PROP_PARENT = AstProp.indexOf("parent"); const AST_PROP_TYPE = AstProp.indexOf("type"); +const AST_PROP_BODY = AstProp.indexOf("body"); +const AST_PROP_CHILDREN = AstProp.indexOf("children"); +const AST_PROP_ELEMENTS = AstProp.indexOf("elements"); +const AST_PROP_PROPERTIES = AstProp.indexOf("properties"); +const AST_PROP_ARGUMENTS = AstProp.indexOf("arguments"); +const AST_PROP_PARAMS = AstProp.indexOf("params"); +const AST_PROP_EXPRESSIONS = AstProp.indexOf("expressions"); +const AST_PROP_QUASIS = AstProp.indexOf("quasis"); const AST_PROP_RANGE = AstProp.indexOf("range"); const AST_PROP_INTERNAL_FLAGS = AstProp.indexOf("_InternalFlags"); const AST_PROP_ATTRIBUTE = AstProp.indexOf("attribute"); +const AST_PROP_CONSEQUENT = AstProp.indexOf("consequent"); +const AST_PROP_CASES = AstProp.indexOf("cases"); +const AST_PROP_SPECIFIERS = AstProp.indexOf("specifiers"); +const AST_PROP_DECLARATIONS = AstProp.indexOf("declarations"); +const AST_PROP_MEMBERS = AstProp.indexOf("members"); + +/** + * @param {number} type + * @param {number} propId + * @returns {boolean} + */ +function isArrayProp(type, propId) { + switch (type) { + case AstType.Program: + case AstType.BlockStatement: + // case AstType.StaticBlock: + return propId === AST_PROP_BODY; + case AstType.JSXOpeningElement: + return propId === AST_PROP_ATTRIBUTE; + case AstType.SwitchCase: + return propId === AST_PROP_CONSEQUENT; + default: + return propId === AST_PROP_CHILDREN || propId === AST_PROP_ELEMENTS || + propId === AST_PROP_PROPERTIES || propId === AST_PROP_PARAMS || + propId === AST_PROP_ARGUMENTS || propId === AST_PROP_EXPRESSIONS || + propId === AST_PROP_QUASIS || propId === AST_PROP_CASES || + propId === AST_PROP_SPECIFIERS || + propId === AST_PROP_DECLARATIONS || propId === AST_PROP_MEMBERS; + } +} /** * @param {AstContext} ctx @@ -379,7 +419,6 @@ const AST_PROP_ATTRIBUTE = AstProp.indexOf("attribute"); function readValue(ctx, offset, propId) { const { buf } = ctx; - // FIXME if (propId === AST_PROP_TYPE) { const type = buf[offset]; return AstTypeName[type]; @@ -394,1039 +433,98 @@ function readValue(ctx, offset, propId) { const target = ctx.idTable[id]; return new Node(ctx, target); } else if (propId === AST_PROP_INTERNAL_FLAGS) { - // - } else { - const type = buf[offset]; + // FIXME + return 0; + } - // type + parentId + SpanLo + SpanHi - offset += 1 + 4 + 4 + 4; + const type = buf[offset]; - // Check for arrays - if (propId === AST_PROP_ATTRIBUTE && type === AstType.JSXOpeningElement) { + // type + parentId + SpanLo + SpanHi + offset += 1 + 4 + 4 + 4; + + const propCount = buf[offset]; + offset += 1; + + for (let i = 0; i < propCount; i++) { + const searchProp = buf[offset]; + offset += 1; + + const isArray = isArrayProp(type, searchProp); + if (searchProp === propId) { + // Check for arrays + if (isArray) { + const len = readU32(buf, offset); + offset += 4; + + const nodes = new Array(len).fill(null); + for (let j = 0; j < len; j++) { + nodes.push(new Node(ctx, offset)); + offset += 4; + } + return nodes; + } + + const id = readU32(buf, offset); + if (id === 0) return null; + + const target = ctx.idTable[id]; + return new Node(ctx, target); } - // - const target = 0; - return new Node(ctx, target); + if (searchProp === AST_PROP_INTERNAL_FLAGS) { + offset += 1; + } else if (isArray) { + const len = readU32(buf, offset); + offset += 4 + (len * 4); + } else { + offset += 4; + } } + + return 0; } -class Node { - #ctx; - #offset; +const INTERNAL_CTX = Symbol("ctx"); +const INTERNAL_OFFSET = Symbol("offset"); - static { - for (let i = 0; i < AstProp.length; i++) { - const name = AstProp[i]; - Object.defineProperty(this, name, { - get() { - return readValue(this.#ctx, this.#offset, i); - }, - }); - } - } +class Node { + [INTERNAL_CTX]; + [INTERNAL_OFFSET]; /** * @param {AstContext} ctx * @param {number} offset */ constructor(ctx, offset) { - this.#ctx = ctx; - this.#offset = offset; + this[INTERNAL_CTX] = ctx; + this[INTERNAL_OFFSET] = offset; } } -/** - * @param {AstContext} ctx - * @param {number[]} ids - * @returns {any[]} - */ -function createChildNodes(ctx, ids) { - /** @type {any[]} */ - const out = []; - for (let i = 0; i < ids.length; i++) { - const id = ids[i]; - out.push(createAstNode(ctx, id)); - } - - return out; +for (let i = 0; i < AstProp.length; i++) { + const name = AstProp[i]; + Object.defineProperty(Node.prototype, name, { + get() { + return readValue(this[INTERNAL_CTX], this[INTERNAL_OFFSET], i); + }, + }); } -/** @implements {Deno.Program} */ -class Program extends Node { - type = /** @type {const} */ ("Program"); - range; - get body() { - return createChildNodes(this.#ctx, this.#childIds); - } +// /** @implements {Deno.AssignmentExpression} */ +// class AssignmentExpression extends Node { - #ctx; - #childIds; +// operator; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {Deno.Program["sourceType"]} sourceType - * @param {number[]} childIds - */ - constructor(ctx, parentId, range, sourceType, childIds) { - super(ctx, parentId); - this.#ctx = ctx; - this.range = range; - this.sourceType = sourceType; - this.#childIds = childIds; - } -} +// constructor(ctx, parentId, range, flags, leftId, rightId) { +// super(ctx, parentId); -// Declarations -/** @implements {Deno.FunctionDeclaration} */ -class FunctionDeclaration extends Node { - type = /** @type {const} */ ("FunctionDeclaration"); - range; - - get id() { - if (this.#identId === 0) return null; - return /** @type {*} */ (createAstNode(this.#ctx, this.#identId)); - } - - get typeParameters() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#typeParamsId)); - } - - get params() { - return createChildNodes(this.#ctx, this.#paramIds); - } - - get body() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#bodyId)); - } - - get returnType() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#returnTypeId)); - } - - declare = false; // FIXME - - #ctx; - #identId; - #typeParamsId; - #paramIds; - #returnTypeId; - #bodyId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} identId - * @param {number} typeParamsId - * @param {number[]} paramIds - * @param {number} returnTypeId - * @param {number} bodyId - */ - constructor( - ctx, - parentId, - range, - flags, - identId, - typeParamsId, - paramIds, - returnTypeId, - bodyId, - ) { - super(ctx, parentId); - this.#ctx = ctx; - this.range = range; - - // FIXME: Flags - this.#identId = identId; - this.#typeParamsId = typeParamsId; - this.#paramIds = paramIds; - this.#returnTypeId = returnTypeId; - this.#bodyId = bodyId; - } -} - -/** @implements {Deno.VariableDeclaration} */ -class VariableDeclaration extends Node { - type = /** @type {const} */ ("VariableDeclaration"); - range; - get declarations() { - return createChildNodes(this.#ctx, this.#childIds); - } - - #ctx; - #childIds; - kind; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number[]} childIds - */ - constructor(ctx, parentId, range, flags, childIds) { - super(ctx, parentId); - this.#ctx = ctx; - this.range = range; - this.kind = (Flags.VarConst & flags) != 0 - ? /** @type {const} */ ("const") - : (Flags.VarLet & flags) != 0 - ? /** @type {const} */ ("let") - : /** @type {const} */ ("var"); - - // FIXME: Declare - this.#childIds = childIds; - } -} - -/** @implements {Deno.VariableDeclarator} */ -class VariableDeclarator extends Node { - type = /** @type {const} */ ("VariableDeclarator"); - range; - - get id() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#nameId)); - } - - get init() { - if (this.#initId === 0) return null; - return /** @type {*} */ (createAstNode(this.#ctx, this.#initId)); - } - - #ctx; - #nameId; - #initId; - definite = false; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} nameId - * @param {number} initId - */ - constructor(ctx, parentId, range, nameId, initId) { - // FIXME: Definite - super(ctx, parentId); - this.#ctx = ctx; - this.range = range; - this.#nameId = nameId; - this.#initId = initId; - } -} - -// Statements - -/** @implements {Deno.BlockStatement} */ -class BlockStatement extends Node { - type = /** @type {const} */ ("BlockStatement"); - get body() { - return createChildNodes(this.#ctx, this.#childIds); - } - range; - - #ctx; - #childIds; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number[]} childIds - */ - constructor(ctx, parentId, range, childIds) { - super(ctx, parentId); - this.#ctx = ctx; - this.range = range; - this.#childIds = childIds; - } -} - -/** @implements {Deno.BreakStatement} */ -class BreakStatement extends Node { - type = /** @type {const} */ ("BreakStatement"); - get label() { - if (this.#labelId === 0) return null; - return /** @type {Deno.Identifier} */ (createAstNode( - this.#ctx, - this.#labelId, - )); - } - range; - - #ctx; - #labelId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} labelId - */ - constructor(ctx, parentId, range, labelId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#labelId = labelId; - this.range = range; - } -} - -/** @implements {Deno.ContinueStatement} */ -class ContinueStatement extends Node { - type = /** @type {const} */ ("ContinueStatement"); - range; - get label() { - return /** @type {Deno.Identifier} */ (createAstNode( - this.#ctx, - this.#labelId, - )); - } - - #ctx; - #labelId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} labelId - */ - constructor(ctx, parentId, range, labelId) { - super(ctx, parentId); - this.#ctx = ctx; - this.#labelId = labelId; - this.range = range; - } -} - -/** @implements {Deno.DebuggerStatement} */ -class DebuggerStatement extends Node { - type = /** @type {const} */ ("DebuggerStatement"); - range; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - */ - constructor(ctx, parentId, range) { - super(ctx, parentId); - this.range = range; - } -} - -/** @implements {Deno.DoWhileStatement} */ -class DoWhileStatement extends Node { - type = /** @type {const} */ ("DoWhileStatement"); - range; - get test() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#exprId, - )); - } - get body() { - return /** @type {Deno.Statement} */ (createAstNode( - this.#ctx, - this.#bodyId, - )); - } - - #ctx; - #exprId = 0; - #bodyId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} exprId - * @param {number} bodyId - */ - constructor(ctx, parentId, range, exprId, bodyId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#exprId = exprId; - this.#bodyId = bodyId; - this.range = range; - } -} - -/** @implements {Deno.ExpressionStatement} */ -class ExpressionStatement extends Node { - type = /** @type {const} */ ("ExpressionStatement"); - range; - get expression() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#exprId, - )); - } - - #ctx; - #exprId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} exprId - */ - constructor(ctx, parentId, range, exprId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#exprId = exprId; - this.range = range; - } -} - -/** @implements {Deno.ForInStatement} */ -class ForInStatement extends Node { - type = /** @type {const} */ ("ForInStatement"); - range; - get left() { - return /** @type {Deno.Expression | Deno.VariableDeclaration} */ (createAstNode( - this.#ctx, - this.#leftId, - )); - } - get right() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#rightId, - )); - } - get body() { - return /** @type {Deno.Statement} */ (createAstNode( - this.#ctx, - this.#bodyId, - )); - } - - #ctx; - #leftId = 0; - #rightId = 0; - #bodyId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} leftId - * @param {number} rightId - * @param {number} bodyId - */ - constructor(ctx, parentId, range, leftId, rightId, bodyId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#leftId = leftId; - this.#rightId = rightId; - this.#bodyId = bodyId; - this.range = range; - } -} - -/** @implements {Deno.ForOfStatement} */ -class ForOfStatement extends Node { - type = /** @type {const} */ ("ForOfStatement"); - range; - get left() { - return /** @type {Deno.Expression | Deno.VariableDeclaration | Deno.UsingDeclaration} */ (createAstNode( - this.#ctx, - this.#leftId, - )); - } - get right() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#rightId, - )); - } - get body() { - return /** @type {Deno.Statement} */ (createAstNode( - this.#ctx, - this.#bodyId, - )); - } - - await; - - #ctx; - #leftId = 0; - #rightId = 0; - #bodyId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {boolean} isAwait - * @param {number} leftId - * @param {number} rightId - * @param {number} bodyId - */ - constructor(ctx, parentId, range, isAwait, leftId, rightId, bodyId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#leftId = leftId; - this.#rightId = rightId; - this.#bodyId = bodyId; - this.range = range; - this.await = isAwait; - } -} - -/** @implements {Deno.ForStatement} */ -class ForStatement extends Node { - type = /** @type {const} */ ("ForStatement"); - range; - get init() { - if (this.#initId === 0) return null; - - return /** @type {Deno.Expression | Deno.VariableDeclaration} */ (createAstNode( - this.#ctx, - this.#initId, - )); - } - get test() { - if (this.#initId === 0) return null; - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#testId, - )); - } - get update() { - if (this.#updateId === 0) return null; - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#updateId, - )); - } - get body() { - return /** @type {Deno.Statement} */ (createAstNode( - this.#ctx, - this.#bodyId, - )); - } - - #ctx; - #initId = 0; - #testId = 0; - #updateId = 0; - #bodyId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} initId - * @param {number} testId - * @param {number} updateId - * @param {number} bodyId - */ - constructor(ctx, parentId, range, initId, testId, updateId, bodyId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#initId = initId; - this.#testId = testId; - this.#updateId = updateId; - this.#bodyId = bodyId; - this.range = range; - } -} - -/** @implements {Deno.IfStatement} */ -class IfStatement extends Node { - type = /** @type {const} */ ("IfStatement"); - range; - get test() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#testId, - )); - } - get consequent() { - return /** @type {Deno.Statement} */ (createAstNode( - this.#ctx, - this.#consequentId, - )); - } - get alternate() { - if (this.#alternateId === 0) return null; - return /** @type {Deno.Statement} */ (createAstNode( - this.#ctx, - this.#alternateId, - )); - } - - #ctx; - #testId = 0; - #consequentId = 0; - #alternateId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} testId - * @param {number} updateId - * @param {number} alternateId - */ - constructor(ctx, parentId, range, testId, updateId, alternateId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#testId = testId; - this.#consequentId = updateId; - this.#alternateId = alternateId; - this.range = range; - } -} - -/** @implements {Deno.LabeledStatement} */ -class LabeledStatement extends Node { - type = /** @type {const} */ ("LabeledStatement"); - range; - get label() { - return /** @type {Deno.Identifier} */ (createAstNode( - this.#ctx, - this.#labelId, - )); - } - get body() { - return /** @type {Deno.Statement} */ (createAstNode( - this.#ctx, - this.#bodyId, - )); - } - - #ctx; - #labelId = 0; - #bodyId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} testId - * @param {number} bodyId - */ - constructor(ctx, parentId, range, testId, bodyId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#labelId = testId; - this.#bodyId = bodyId; - this.range = range; - } -} - -/** @implements {Deno.ReturnStatement} */ -class ReturnStatement extends Node { - type = /** @type {const} */ ("ReturnStatement"); - range; - get argument() { - if (this.#exprId === 0) return null; - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#exprId, - )); - } - - #ctx; - #exprId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} argId - */ - constructor(ctx, parentId, range, argId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#exprId = argId; - this.range = range; - } -} - -/** @implements {Deno.SwitchStatement} */ -class SwitchStatement extends Node { - type = /** @type {const} */ ("SwitchStatement"); - range; - get discriminant() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#discriminantId, - )); - } - get cases() { - return createChildNodes(this.#ctx, this.#caseIds); - } - - #ctx; - #discriminantId = 0; - #caseIds; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} discriminantId - * @param {number[]} caseIds - */ - constructor(ctx, parentId, range, discriminantId, caseIds) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#discriminantId = discriminantId; - this.#caseIds = caseIds; - this.range = range; - } -} - -/** @implements {Deno.SwitchCase} */ -class SwitchCase extends Node { - type = /** @type {const} */ ("SwitchCase"); - range; - get test() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#testId, - )); - } - get consequent() { - return createChildNodes(this.#ctx, this.#consIds); - } - - #ctx; - #testId = 0; - #consIds; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} testId - * @param {number[]} consIds - */ - constructor(ctx, parentId, range, testId, consIds) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#testId = testId; - this.#consIds = consIds; - this.range = range; - } -} - -/** @implements {Deno.ThrowStatement} */ -class ThrowStatement extends Node { - type = /** @type {const} */ ("ThrowStatement"); - range; - get argument() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#argId, - )); - } - - #ctx; - #argId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} argId - */ - constructor(ctx, parentId, range, argId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#argId = argId; - this.range = range; - } -} - -/** @implements {Deno.TryStatement} */ -class TryStatement extends Node { - type = /** @type {const} */ ("TryStatement"); - range; - get block() { - return /** @type {Deno.BlockStatement} */ (createAstNode( - this.#ctx, - this.#blockId, - )); - } - get finalizer() { - if (this.#finalizerId === 0) return null; - return /** @type {Deno.BlockStatement} */ (createAstNode( - this.#ctx, - this.#finalizerId, - )); - } - get handler() { - if (this.#handlerId === 0) return null; - return /** @type {Deno.CatchClause} */ (createAstNode( - this.#ctx, - this.#handlerId, - )); - } - - #ctx; - #blockId = 0; - #finalizerId = 0; - #handlerId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} blockId - * @param {number} finalizerId - * @param {number} handlerId - */ - constructor(ctx, parentId, range, blockId, finalizerId, handlerId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#blockId = blockId; - this.#finalizerId = finalizerId; - this.#handlerId = handlerId; - this.range = range; - } -} - -/** @implements {Deno.WhileStatement} */ -class WhileStatement extends Node { - type = /** @type {const} */ ("WhileStatement"); - range; - get test() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#testId, - )); - } - get body() { - return /** @type {Deno.Statement} */ (createAstNode( - this.#ctx, - this.#bodyId, - )); - } - - #ctx; - #testId = 0; - #bodyId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} testId - * @param {number} bodyId - */ - constructor(ctx, parentId, range, testId, bodyId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#testId = testId; - this.#bodyId = bodyId; - this.range = range; - } -} - -/** @implements {Deno.WithStatement} */ -class WithStatement { - type = /** @type {const} */ ("WithStatement"); - range; - get body() { - return /** @type {Deno.Statement} */ (createAstNode( - this.#ctx, - this.#bodyId, - )); - } - get object() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#objectId, - )); - } - - #ctx; - #bodyId = 0; - #objectId = 0; - - /** - * @param {AstContext} ctx - * @param {Deno.Range} range - * @param {number} bodyId - * @param {number} objectId - */ - constructor(ctx, range, bodyId, objectId) { - this.#ctx = ctx; - this.#bodyId = bodyId; - this.#objectId = objectId; - this.range = range; - } -} - -// Expressions - -/** @implements {Deno.ArrayExpression} */ -class ArrayExpression extends Node { - type = /** @type {const} */ ("ArrayExpression"); - range; - get elements() { - return createChildNodes(this.#ctx, this.#elemIds); - } - - #ctx; - #elemIds; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number[]} elemIds - */ - constructor(ctx, parentId, range, elemIds) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#elemIds = elemIds; - } -} - -/** @implements {Deno.ArrowFunctionExpression} */ -class ArrowFunctionExpression extends Node { - type = /** @type {const} */ ("ArrowFunctionExpression"); - range; - async = false; - generator = false; - - get body() { - return /** @type {*} */ (createAstNode( - this.#ctx, - this.#bodyId, - )); - } - - get params() { - return createChildNodes(this.#ctx, this.#paramIds); - } - - get returnType() { - if (this.#returnTypeId === 0) return null; - return /** @type {*} */ (createAstNode( - this.#ctx, - this.#returnTypeId, - )); - } - - get typeParameters() { - if (this.#typeParamId === 0) return null; - return /** @type {*} */ (createAstNode( - this.#ctx, - this.#typeParamId, - )); - } - - #ctx; - #bodyId; - #typeParamId; - #paramIds; - #returnTypeId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {boolean} isAsync - * @param {boolean} isGenerator - * @param {number} typeParamId - * @param {number[]} paramIds - * @param {number} bodyId - * @param {number} returnTypeId - */ - constructor( - ctx, - parentId, - range, - isAsync, - isGenerator, - typeParamId, - paramIds, - bodyId, - returnTypeId, - ) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#bodyId = bodyId; - this.#typeParamId = typeParamId; - this.#paramIds = paramIds; - this.#returnTypeId = returnTypeId; - this.asnyc = isAsync; - this.generator = isGenerator; - this.range = range; - } -} - -/** @implements {Deno.AssignmentExpression} */ -class AssignmentExpression extends Node { - type = /** @type {const} */ ("AssignmentExpression"); - range; - get left() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#leftId, - )); - } - get right() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#rightId, - )); - } - - operator; - - #ctx; - #leftId = 0; - #rightId = 0; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} leftId - * @param {number} rightId - */ - constructor(ctx, parentId, range, flags, leftId, rightId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#leftId = leftId; - this.#rightId = rightId; - this.range = range; - this.operator = getAssignOperator(flags); - } -} +// this.#ctx = ctx; +// this.#leftId = leftId; +// this.#rightId = rightId; +// this.range = range; +// this.operator = getAssignOperator(flags); +// } +// } /** * @param {number} n @@ -1471,107 +569,52 @@ function getAssignOperator(n) { } } -/** @implements {Deno.AwaitExpression} */ -class AwaitExpression extends Node { - type = /** @type {const} */ ("AwaitExpression"); - range; - get argument() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#argId, - )); - } +// /** @implements {Deno.UpdateExpression} */ +// class UpdateExpression extends Node { +// type = /** @type {const} */ ("UpdateExpression"); +// range; +// prefix; +// operator; - #ctx; - #argId; +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} flags +// * @param {number} argId +// */ +// constructor(ctx, parentId, range, flags, argId) { +// super(ctx, parentId); +// this.range = range; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} argId - */ - constructor(ctx, parentId, range, argId) { - super(ctx, parentId); - this.#ctx = ctx; - this.#argId = argId; - this.range = range; - } -} +// this.prefix = (flags & Flags.UpdatePrefix) !== 0; +// this.operator = (flags & Flags.UpdatePlusPlus) !== 0 +// ? /** @type {const} */ ("++") +// : /** @type {const} */ ("--"); +// } +// } -/** @implements {Deno.UpdateExpression} */ -class UpdateExpression extends Node { - type = /** @type {const} */ ("UpdateExpression"); - range; - get argument() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#argId)); - } +// /** @implements {Deno.BinaryExpression} */ +// class BinaryExpression extends Node { +// type = /** @type {const} */ ("BinaryExpression"); - #ctx; - #argId; - prefix; - operator; +// operator; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} argId - */ - constructor(ctx, parentId, range, flags, argId) { - super(ctx, parentId); - this.#ctx = ctx; - this.#argId = argId; - this.range = range; +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} flags +// * @param {number} leftId +// * @param {number} rightId +// */ +// constructor(ctx, parentId, range, flags, leftId, rightId) { +// super(ctx, parentId); - this.prefix = (flags & Flags.UpdatePrefix) !== 0; - this.operator = (flags & Flags.UpdatePlusPlus) !== 0 - ? /** @type {const} */ ("++") - : /** @type {const} */ ("--"); - } -} - -/** @implements {Deno.BinaryExpression} */ -class BinaryExpression extends Node { - type = /** @type {const} */ ("BinaryExpression"); - range; - get left() { - return /** @type {Deno.Expression | Deno.PrivateIdentifier} */ (createAstNode( - this.#ctx, - this.#leftId, - )); - } - get right() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#rightId, - )); - } - - operator; - #ctx; - #leftId; - #rightId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} leftId - * @param {number} rightId - */ - constructor(ctx, parentId, range, flags, leftId, rightId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#leftId = leftId; - this.#rightId = rightId; - this.operator = getBinaryOperator(flags); - this.range = range; - } -} +// this.operator = getBinaryOperator(flags); +// this.range = range; +// } +// } /** * @param {number} n @@ -1628,257 +671,63 @@ function getBinaryOperator(n) { } } -/** @implements {Deno.CallExpression} */ -class CallExpression extends Node { - type = /** @type {const} */ ("CallExpression"); - range; - get callee() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#calleeId, - )); - } - get arguments() { - return createChildNodes(this.#ctx, this.#argumentIds); - } - get typeArguments() { - if (this.#typeArgId === 0) return null; - return createAstNode(this.#ctx, this.#typeArgId); - } +// /** @implements {Deno.CallExpression} */ +// class CallExpression extends Node { +// this.optional = (flags & Flags.FnOptional) !== 0; +// this.#ctx = ctx; +// this.#calleeId = calleeId; +// this.range = range; +// this.#typeArgId = typeArgId; +// this.#argumentIds = argumentIds; +// } +// } - optional = false; +// /** @implements {Deno.FunctionExpression} */ +// class FunctionExpression extends Node { +// constructor( +// ) { +// super(ctx, parentId); - #ctx; - #calleeId; - #typeArgId; - #argumentIds; +// this.async = (flags & Flags.FnAsync) !== 0; +// this.generator = (flags & Flags.FnGenerator) !== 0; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} calleeId - * @param {number} typeArgId - * @param {number[]} argumentIds - */ - constructor(ctx, parentId, range, flags, calleeId, typeArgId, argumentIds) { - super(ctx, parentId); +// } +// } - this.optional = (flags & Flags.FnOptional) !== 0; - this.#ctx = ctx; - this.#calleeId = calleeId; - this.range = range; - this.#typeArgId = typeArgId; - this.#argumentIds = argumentIds; - } -} +// /** @implements {Deno.Identifier} */ +// class Identifier extends Node { +// type = /** @type {const} */ ("Identifier"); +// range; +// name = ""; -/** @implements {Deno.ChainExpression} */ -class ChainExpression extends Node { - type = /** @type {const} */ ("ChainExpression"); - range; +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} nameId +// */ +// constructor(ctx, parentId, range, nameId) { +// super(ctx, parentId); - get expression() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#exprId)); - } +// this.name = getString(ctx, nameId); +// this.range = range; +// } +// } - #ctx; - #exprId; +// /** @implements {Deno.LogicalExpression} */ +// class LogicalExpression extends Node { +// type = /** @type {const} */ ("LogicalExpression"); - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} exprId - */ - constructor(ctx, parentId, range, exprId) { - super(ctx, parentId); - this.#ctx = ctx; - this.range = range; - this.#exprId = exprId; - } -} +// constructor(ctx, parentId, range, flags, leftId, rightId) { +// super(ctx, parentId); -/** @implements {Deno.ConditionalExpression} */ -class ConditionalExpression extends Node { - type = /** @type {const} */ ("ConditionalExpression"); - range; - get test() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#testId, - )); - } - get consequent() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#consequentId, - )); - } - get alternate() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#alternateId, - )); - } - - #ctx; - #testId; - #consequentId; - #alternateId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} testId - * @param {number} consequentId - * @param {number} alternateId - */ - constructor(ctx, parentId, range, testId, consequentId, alternateId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.#testId = testId; - this.#consequentId = consequentId; - this.#alternateId = alternateId; - this.range = range; - } -} - -/** @implements {Deno.FunctionExpression} */ -class FunctionExpression extends Node { - type = /** @type {const} */ ("FunctionExpression"); - range; - - get body() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#bodyId)); - } - - get returnType() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#returnId)); - } - - get id() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#identId)); - } - - get params() { - return createChildNodes(this.#ctx, this.#paramIds); - } - - get typeParameters() { - if (this.#typeParamId === null) return null; - return /** @type {*} */ (createAstNode(this.#ctx, this.#typeParamId)); - } - - async = false; - generator = false; - - #ctx; - #identId; - #typeParamId; - #returnId; - #bodyId; - #paramIds; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} identId - * @param {number} typeParamId - * @param {number} returnId - * @param {number} bodyId - * @param {number[]} paramIds - */ - constructor( - ctx, - parentId, - range, - flags, - identId, - typeParamId, - returnId, - bodyId, - paramIds, - ) { - super(ctx, parentId); - - this.async = (flags & Flags.FnAsync) !== 0; - this.generator = (flags & Flags.FnGenerator) !== 0; - - this.#ctx = ctx; - this.range = range; - this.#identId = identId; - this.#typeParamId = typeParamId; - this.#returnId = returnId; - this.#bodyId = bodyId; - this.#paramIds = paramIds; - } -} - -/** @implements {Deno.Identifier} */ -class Identifier extends Node { - type = /** @type {const} */ ("Identifier"); - range; - name = ""; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} nameId - */ - constructor(ctx, parentId, range, nameId) { - super(ctx, parentId); - - this.name = getString(ctx, nameId); - this.range = range; - } -} - -/** @implements {Deno.LogicalExpression} */ -class LogicalExpression extends Node { - type = /** @type {const} */ ("LogicalExpression"); - range; - get left() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#leftId, - )); - } - get right() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#rightId, - )); - } - - #ctx; - #leftId; - #rightId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} leftId - * @param {number} rightId - */ - constructor(ctx, parentId, range, flags, leftId, rightId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.operator = getLogicalOperator(flags); - this.#leftId = leftId; - this.#rightId = rightId; - this.range = range; - } -} +// this.#ctx = ctx; +// this.operator = getLogicalOperator(flags); +// this.#leftId = leftId; +// this.#rightId = rightId; +// this.range = range; +// } +// } /** * @param {number} n @@ -1896,407 +745,73 @@ function getLogicalOperator(n) { throw new Error(`Unknown operator: ${n}`); } -/** @implements {Deno.MemberExpression} */ -class MemberExpression extends Node { - type = /** @type {const} */ ("MemberExpression"); - range; - get object() { - return /** @type {*} */ (createAstNode( - this.#ctx, - this.#objId, - )); - } - get property() { - return /** @type {*} */ (createAstNode( - this.#ctx, - this.#propId, - )); - } - optional = false; - computed = false; +// /** @implements {Deno.MemberExpression} */ +// class MemberExpression extends Node { +// constructor(ctx, parentId, range, flags, objId, propId) { +// super(ctx, parentId); - #ctx; - #objId; - #propId; +// this.#ctx = ctx; +// this.computed = (flags & Flags.MemberComputed) !== 0; +// this.optional = (flags & Flags.MemberOptional) !== 0; +// this.#objId = objId; +// this.#propId = propId; +// this.range = range; +// } +// } - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} objId - * @param {number} propId - */ - constructor(ctx, parentId, range, flags, objId, propId) { - super(ctx, parentId); +// /** @implements {Deno.PrivateIdentifier} */ +// class PrivateIdentifier extends Node { +// type = /** @type {const} */ ("PrivateIdentifier"); +// range; +// #ctx; +// name; - this.#ctx = ctx; - this.computed = (flags & Flags.MemberComputed) !== 0; - this.optional = (flags & Flags.MemberOptional) !== 0; - this.#objId = objId; - this.#propId = propId; - this.range = range; - } -} +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} nameId +// */ +// constructor(ctx, parentId, range, nameId) { +// super(ctx, parentId); -/** @implements {Deno.MetaProperty} */ -class MetaProperty { - type = /** @type {const} */ ("MetaProperty"); - range; - get meta() { - return /** @type {Deno.Identifier} */ (createAstNode( - this.#ctx, - this.#metaId, - )); - } - get property() { - return /** @type {Deno.Identifier} */ (createAstNode( - this.#ctx, - this.#propId, - )); - } +// this.#ctx = ctx; +// this.range = range; +// this.name = getString(ctx, nameId); +// } +// } - #ctx; - #metaId; - #propId; +// /** @implements {Deno.Property} */ +// class Property extends Node { +// type = /** @type {const} */ ("Property"); +// range; - /** - * @param {AstContext} ctx - * @param {Deno.Range} range - * @param {number} metaId - * @param {number} propId - */ - constructor(ctx, range, metaId, propId) { - this.#ctx = ctx; - this.#metaId = metaId; - this.#propId = propId; - this.range = range; - } -} +// constructor(ctx, parentId, range, keyId, valueId) { +// super(ctx, parentId); -/** @implements {Deno.NewExpression} */ -class NewExpression extends Node { - type = /** @type {const} */ ("NewExpression"); - range; - get arguments() { - return createChildNodes(this.#ctx, this.#childIds); - } - get callee() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#calleeId, - )); - } +// // FIXME flags - #ctx; - #calleeId; - #childIds; +// this.#ctx = ctx; +// this.range = range; +// this.#keyId = keyId; +// this.#valueId = valueId; +// } +// } - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} calleeId - * @param {number[]} childIds - */ - constructor(ctx, parentId, range, calleeId, childIds) { - super(ctx, parentId); +// /** @implements {Deno.UnaryExpression} */ +// class UnaryExpression extends Node { +// type = /** @type {const} */ ("UnaryExpression"); +// range; - this.#ctx = ctx; - this.#calleeId = calleeId; - this.#childIds = childIds; - this.range = range; - } -} +// constructor(ctx, parentId, range, flags, exprId) { +// super(ctx, parentId); -/** @implements {Deno.ObjectExpression} */ -class ObjectExpression extends Node { - type = /** @type {const} */ ("ObjectExpression"); - range; - get properties() { - return createChildNodes(this.#ctx, this.#elemIds); - } - - #ctx; - #elemIds; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number[]} elemIds - */ - constructor(ctx, parentId, range, elemIds) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#elemIds = elemIds; - } -} - -/** @implements {Deno.ParenthesisExpression} */ -class ParenthesisExpression extends Node { - type = /** @type {const} */ ("ParenthesisExpression"); - range; - #ctx; - #exprId; - - get expression() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#exprId)); - } - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} exprId - */ - constructor(ctx, parentId, range, exprId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#exprId = exprId; - } -} - -/** @implements {Deno.PrivateIdentifier} */ -class PrivateIdentifier extends Node { - type = /** @type {const} */ ("PrivateIdentifier"); - range; - #ctx; - name; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} nameId - */ - constructor(ctx, parentId, range, nameId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.name = getString(ctx, nameId); - } -} - -/** @implements {Deno.Property} */ -class Property extends Node { - type = /** @type {const} */ ("Property"); - range; - #ctx; - - get key() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#keyId)); - } - - get value() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#valueId)); - } - - #keyId; - #valueId; - - // FIXME - computed = false; - method = false; - shorthand = false; - kind = /** @type {const} */ ("get"); - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} keyId - * @param {number} valueId - */ - constructor(ctx, parentId, range, keyId, valueId) { - super(ctx, parentId); - - // FIXME flags - - this.#ctx = ctx; - this.range = range; - this.#keyId = keyId; - this.#valueId = valueId; - } -} - -/** @implements {Deno.RestElement} */ -class RestElement extends Node { - type = /** @type {const} */ ("RestElement"); - range; - #ctx; - #exprId; - #typeId; - - get argument() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#exprId)); - } - - get typeAnnotation() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#typeId)); - } - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} exprId - * @param {number} typeId - */ - constructor(ctx, parentId, range, exprId, typeId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#exprId = exprId; - this.#typeId = typeId; - } -} - -/** @implements {Deno.SequenceExpression} */ -class SequenceExpression extends Node { - type = /** @type {const} */ ("SequenceExpression"); - range; - #ctx; - #childIds; - - get expressions() { - return createChildNodes(this.#ctx, this.#childIds); - } - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number[]} childIds - */ - constructor(ctx, parentId, range, childIds) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#childIds = childIds; - } -} - -/** @implements {Deno.SpreadElement} */ -class SpreadElement extends Node { - type = /** @type {const} */ ("SpreadElement"); - range; - #ctx; - #exprId; - - get argument() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#exprId)); - } - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} exprId - */ - constructor(ctx, parentId, range, exprId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#exprId = exprId; - } -} - -/** @implements {Deno.Super} */ -class Super extends Node { - type = /** @type {const} */ ("Super"); - range; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - */ - constructor(ctx, parentId, range) { - super(ctx, parentId); - this.range = range; - } -} - -/** @implements {Deno.TaggedTemplateExpression} */ -class TaggedTemplateExpression extends Node { - type = /** @type {const} */ ("TaggedTemplateExpression"); - range; - - get tag() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#tagId)); - } - - get quasi() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#quasiId)); - } - - get typeArguments() { - if (this.#typeParamId === 0) return null; - return /** @type {*} */ (createAstNode(this.#ctx, this.#typeParamId)); - } - - #ctx; - #tagId; - #typeParamId; - #quasiId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} tagId - * @param {number} typeParamId - * @param {number} quasiId - */ - constructor(ctx, parentId, range, tagId, typeParamId, quasiId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#tagId = tagId; - this.#typeParamId = typeParamId; - this.#quasiId = quasiId; - } -} - -/** @implements {Deno.UnaryExpression} */ -class UnaryExpression extends Node { - type = /** @type {const} */ ("UnaryExpression"); - range; - - get argument() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#exprId)); - } - - #ctx; - #exprId; - operator; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} exprId - */ - constructor(ctx, parentId, range, flags, exprId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.operator = getUnaryOperator(flags); - this.#exprId = exprId; - } -} +// this.#ctx = ctx; +// this.range = range; +// this.operator = getUnaryOperator(flags); +// this.#exprId = exprId; +// } +// } /** * @param {number} n @@ -2321,759 +836,244 @@ function getUnaryOperator(n) { } } -/** @implements {Deno.YieldExpression} */ -class YieldExpression extends Node { - type = /** @type {const} */ ("YieldExpression"); - range; - get argument() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#argId, - )); - } +// /** @implements {Deno.YieldExpression} */ +// class YieldExpression extends Node { +// type = /** @type {const} */ ("YieldExpression"); +// range; +// get argument() { +// return /** @type {Deno.Expression} */ (createAstNode( +// this.#ctx, +// this.#argId, +// )); +// } - delegate = false; +// delegate = false; - #ctx; - #argId; +// #ctx; +// #argId; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number} argId - */ - constructor(ctx, parentId, range, flags, argId) { - super(ctx, parentId); - this.#ctx = ctx; - this.#argId = argId; - this.range = range; +// constructor(ctx, parentId, range, flags, argId) { +// super(ctx, parentId); +// this.#ctx = ctx; +// this.#argId = argId; +// this.range = range; - this.delegate = (flags & Flags.YieldDelegate) !== 0; - } -} +// this.delegate = (flags & Flags.YieldDelegate) !== 0; +// } +// } // Literals -/** @implements {Deno.BooleanLiteral} */ -class BooleanLiteral extends Node { - type = /** @type {const} */ ("BooleanLiteral"); - range; - value = false; +// /** @implements {Deno.BooleanLiteral} */ +// class BooleanLiteral extends Node { +// type = /** @type {const} */ ("BooleanLiteral"); +// range; +// value = false; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - */ - constructor(ctx, parentId, range, flags) { - super(ctx, parentId); - this.value = flags === 1; - this.range = range; - } -} +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} flags +// */ +// constructor(ctx, parentId, range, flags) { +// super(ctx, parentId); +// this.value = flags === 1; +// this.range = range; +// } +// } -/** @implements {Deno.BigIntLiteral} */ -class BigIntLiteral extends Node { - type = /** @type {const} */ ("BigIntLiteral"); - range; - value; +// /** @implements {Deno.BigIntLiteral} */ +// class BigIntLiteral extends Node { +// type = /** @type {const} */ ("BigIntLiteral"); +// range; +// value; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} strId - */ - constructor(ctx, parentId, range, strId) { - super(ctx, parentId); - this.range = range; - this.value = BigInt(getString(ctx, strId)); - } -} +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} strId +// */ +// constructor(ctx, parentId, range, strId) { +// super(ctx, parentId); +// this.range = range; +// this.value = BigInt(getString(ctx, strId)); +// } +// } -/** @implements {Deno.NullLiteral} */ -class NullLiteral extends Node { - type = /** @type {const} */ ("NullLiteral"); - range; - value = null; +// /** @implements {Deno.NullLiteral} */ +// class NullLiteral extends Node { +// type = /** @type {const} */ ("NullLiteral"); +// range; +// value = null; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - */ - constructor(ctx, parentId, range) { - super(ctx, parentId); - this.range = range; - } -} +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// */ +// constructor(ctx, parentId, range) { +// super(ctx, parentId); +// this.range = range; +// } +// } -/** @implements {Deno.NumericLiteral} */ -class NumericLiteral extends Node { - type = /** @type {const} */ ("NumericLiteral"); - range; - value = 0; +// /** @implements {Deno.NumericLiteral} */ +// class NumericLiteral extends Node { +// type = /** @type {const} */ ("NumericLiteral"); +// range; +// value = 0; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} strId - */ - constructor(ctx, parentId, range, strId) { - super(ctx, parentId); - this.range = range; - this.value = Number(getString(ctx, strId)); - } -} +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} strId +// */ +// constructor(ctx, parentId, range, strId) { +// super(ctx, parentId); +// this.range = range; +// this.value = Number(getString(ctx, strId)); +// } +// } -/** @implements {Deno.RegExpLiteral} */ -class RegExpLiteral extends Node { - type = /** @type {const} */ ("RegExpLiteral"); - range; - pattern = ""; - flags = ""; +// /** @implements {Deno.RegExpLiteral} */ +// class RegExpLiteral extends Node { +// type = /** @type {const} */ ("RegExpLiteral"); +// range; +// pattern = ""; +// flags = ""; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} patternId - * @param {number} flagsId - */ - constructor(ctx, parentId, range, patternId, flagsId) { - super(ctx, parentId); +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} patternId +// * @param {number} flagsId +// */ +// constructor(ctx, parentId, range, patternId, flagsId) { +// super(ctx, parentId); - this.range = range; - this.pattern = getString(ctx, patternId); - this.flags = getString(ctx, flagsId); - } -} +// this.range = range; +// this.pattern = getString(ctx, patternId); +// this.flags = getString(ctx, flagsId); +// } +// } -/** @implements {Deno.StringLiteral} */ -class StringLiteral extends Node { - type = /** @type {const} */ ("StringLiteral"); - range; - value = ""; +// /** @implements {Deno.StringLiteral} */ +// class StringLiteral extends Node { +// type = /** @type {const} */ ("StringLiteral"); +// range; +// value = ""; - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} strId - */ - constructor(ctx, parentId, range, strId) { - super(ctx, parentId); - this.range = range; - this.value = getString(ctx, strId); - } -} +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} strId +// */ +// constructor(ctx, parentId, range, strId) { +// super(ctx, parentId); +// this.range = range; +// this.value = getString(ctx, strId); +// } +// } -/** @implements {Deno.TemplateLiteral} */ -class TemplateLiteral extends Node { - type = /** @type {const} */ ("TemplateLiteral"); - range; +// /** @implements {Deno.TemplateElement} */ +// class TemplateElement extends Node { +// type = /** @type {const} */ ("TemplateElement"); +// range; - #ctx; - #exprIds; - #quasiIds; +// tail = false; +// value; - get expressions() { - return createChildNodes(this.#ctx, this.#exprIds); - } +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} rawId +// * @param {number} cookedId +// * @param {boolean} tail +// */ +// constructor(ctx, parentId, range, rawId, cookedId, tail) { +// super(ctx, parentId); - get quasis() { - return createChildNodes(this.#ctx, this.#quasiIds); - } - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number[]} quasiIds - * @param {number[]} exprIds - */ - constructor(ctx, parentId, range, quasiIds, exprIds) { - super(ctx, parentId); - this.#ctx = ctx; - this.#quasiIds = quasiIds; - this.#exprIds = exprIds; - this.range = range; - } -} - -/** @implements {Deno.TemplateElement} */ -class TemplateElement extends Node { - type = /** @type {const} */ ("TemplateElement"); - range; - - tail = false; - value; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} rawId - * @param {number} cookedId - * @param {boolean} tail - */ - constructor(ctx, parentId, range, rawId, cookedId, tail) { - super(ctx, parentId); - - const raw = getString(ctx, rawId); - this.value = { - raw, - cooked: cookedId === 0 ? raw : getString(ctx, cookedId), - }; - this.tail = tail; - this.range = range; - } -} +// const raw = getString(ctx, rawId); +// this.value = { +// raw, +// cooked: cookedId === 0 ? raw : getString(ctx, cookedId), +// }; +// this.tail = tail; +// this.range = range; +// } +// } // Patterns -/** @implements {Deno.AssignmentPattern} */ -class AssignmentPattern extends Node { - type = /** @type {const} */ ("AssignmentPattern"); - range; - - get left() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#leftId)); - } - get right() { - return /** @type {*} */ (createAstNode(this.#ctx, this.#rightId)); - } - - #ctx; - #leftId; - #rightId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} leftId - * @param {number} rightId - */ - constructor(ctx, parentId, range, leftId, rightId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - - this.#leftId = leftId; - this.#rightId = rightId; - } -} - -/** @implements {Deno.ArrayPattern} */ -class ArrayPattern extends Node { - type = /** @type {const} */ ("ArrayPattern"); - range; - - get elements() { - return createChildNodes(this.#ctx, this.#elemIds); - } - - get typeAnnotation() { - if (this.#typeId === 0) return 0; - return /** @type {*} */ (createAstNode(this.#ctx, this.#typeId)); - } - - #ctx; - #elemIds; - #typeId; - optional = false; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number[]} elemIds - * @param {number} typeId - */ - constructor(ctx, parentId, range, flags, elemIds, typeId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - - this.optional = (flags & Flags.ParamOptional) !== 0; - this.#elemIds = elemIds; - this.#typeId = typeId; - } -} - -/** @implements {Deno.ObjectPattern} */ -class ObjectPattern extends Node { - type = /** @type {const} */ ("ObjectPattern"); - range; - - get properties() { - return createChildNodes(this.#ctx, this.#elemIds); - } - - get typeAnnotation() { - if (this.#typeId === 0) return 0; - return /** @type {*} */ (createAstNode(this.#ctx, this.#typeId)); - } - - #ctx; - #elemIds; - #typeId; - optional = false; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} flags - * @param {number[]} elemIds - * @param {number} typeId - */ - constructor(ctx, parentId, range, flags, elemIds, typeId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - - this.optional = (flags & Flags.ParamOptional) !== 0; - this.#elemIds = elemIds; - this.#typeId = typeId; - } -} - -// JSX - -/** @implements {Deno.JSXAttribute} */ -class JSXAttribute extends Node { - type = /** @type {const} */ ("JSXAttribute"); - range; - get name() { - return /** @type {Deno.JSXIdentifier | Deno.JSXNamespacedName} */ (createAstNode( - this.#ctx, - this.#nameId, - )); - } - get value() { - if (this.#valueId === 0) return null; - return /** @type {Deno.JSXElement | Deno.JSXExpressionContainer | Deno.JSXSpreadChild | Deno.Literal} */ (createAstNode( - this.#ctx, - this.#valueId, - )); - } - - #ctx; - #nameId; - #valueId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} nameId - * @param {number} valueId - */ - constructor(ctx, parentId, range, nameId, valueId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#nameId = nameId; - this.#valueId = valueId; - } -} - -/** @implements {Deno.JSXClosingElement} */ -class JSXClosingElement extends Node { - type = /** @type {const} */ ("JSXClosingElement"); - range; - get name() { - return /** @type {Deno.JSXIdentifier | Deno.JSXMemberExpression | Deno.JSXNamespacedName} */ (createAstNode( - this.#ctx, - this.#nameId, - )); - } - - #ctx; - #nameId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} nameId - */ - constructor(ctx, parentId, range, nameId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#nameId = nameId; - } -} - -/** @implements {Deno.JSXClosingFragment} */ -class JSXClosingFragment extends Node { - type = /** @type {const} */ ("JSXClosingFragment"); - range; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - */ - constructor(ctx, parentId, range) { - super(ctx, parentId); - - this.range = range; - } -} - -/** @implements {Deno.JSXElement} */ -class JSXElement extends Node { - type = /** @type {const} */ ("JSXElement"); - range; - get children() { - return createChildNodes(this.#ctx, this.#childIds); - } - - get openingElement() { - return /** @type {Deno.JSXOpeningElement} */ (createAstNode( - this.#ctx, - this.#openId, - )); - } - get closingElement() { - return /** @type {Deno.JSXClosingElement} */ (createAstNode( - this.#ctx, - this.#closingId, - )); - } - - #ctx; - #openId; - #closingId; - #childIds; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} openId - * @param {number} closingId - * @param {number[]} childIds - */ - constructor(ctx, parentId, range, openId, closingId, childIds) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#openId = openId; - this.#closingId = closingId; - this.#childIds = childIds; - } -} - -/** @implements {Deno.JSXEmptyExpression} */ -class JSXEmptyExpression extends Node { - type = /** @type {const} */ ("JSXEmptyExpression"); - range; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - */ - constructor(ctx, parentId, range) { - super(ctx, parentId); - this.range = range; - } -} - -/** @implements {Deno.JSXExpressionContainer} */ -class JSXExpressionContainer extends Node { - type = /** @type {const} */ ("JSXExpressionContainer"); - range; - get expression() { - return /** @type {Deno.Expression | Deno.JSXEmptyExpression} */ (createAstNode( - this.#ctx, - this.#exprId, - )); - } - - #ctx; - #exprId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} exprId - */ - constructor(ctx, parentId, range, exprId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#exprId = exprId; - } -} - -/** @implements {Deno.JSXFragment} */ -class JSXFragment extends Node { - type = /** @type {const} */ ("JSXFragment"); - range; - get children() { - return createChildNodes(this.#ctx, this.#childIds); - } - - get openingFragment() { - return /** @type {*} */ (createAstNode( - this.#ctx, - this.#openId, - )); - } - get closingFragment() { - return /** @type {*} */ (createAstNode( - this.#ctx, - this.#closingId, - )); - } - - #ctx; - #childIds; - #openId; - #closingId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} openId - * @param {number} closingId - * @param {number[]} childIds - */ - constructor(ctx, parentId, range, openId, closingId, childIds) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#openId = openId; - this.#closingId = closingId; - this.#childIds = childIds; - } -} - -/** @implements {Deno.JSXIdentifier} */ -class JSXIdentifier extends Node { - type = /** @type {const} */ ("JSXIdentifier"); - range; - name; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} nameId - */ - constructor(ctx, parentId, range, nameId) { - super(ctx, parentId); - - this.range = range; - this.name = getString(ctx, nameId); - } -} - -/** @implements {Deno.JSXMemberExpression} */ -class JSXMemberExpression extends Node { - type = /** @type {const} */ ("JSXMemberExpression"); - range; - get object() { - return /** @type {Deno.JSXMemberExpression["object"]} */ (createAstNode( - this.#ctx, - this.#objId, - )); - } - get property() { - return /** @type {Deno.JSXIdentifier} */ (createAstNode( - this.#ctx, - this.#propertyId, - )); - } - - #ctx; - #objId; - #propertyId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} objId - * @param {number} propId - */ - constructor(ctx, parentId, range, objId, propId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#objId = objId; - this.#propertyId = propId; - } -} - -/** @implements {Deno.JSXNamespacedName} */ -class JSXNamespacedName extends Node { - type = /** @type {const} */ ("JSXNamespacedName"); - range; - get name() { - return /** @type {Deno.JSXIdentifier} */ (createAstNode( - this.#ctx, - this.#nameId, - )); - } - get namespace() { - return /** @type {Deno.JSXIdentifier} */ (createAstNode( - this.#ctx, - this.#namespaceId, - )); - } - - #ctx; - #nameId; - #namespaceId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} nameId - * @param {number} nsId - */ - constructor(ctx, parentId, range, nameId, nsId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#nameId = nameId; - this.#namespaceId = nsId; - } -} - -/** @implements {Deno.JSXOpeningElement} */ -class JSXOpeningElement extends Node { - type = /** @type {const} */ ("JSXOpeningElement"); - range; - get attributes() { - return createChildNodes(this.#ctx, this.#attrIds); - } - get name() { - return /** @type {Deno.JSXIdentifier} */ (createAstNode( - this.#ctx, - this.#nameId, - )); - } - - #ctx; - #nameId; - #attrIds; - selfClosing = false; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {boolean} isSelfClosing - * @param {number} nameId - * @param {number[]} attrIds - */ - constructor(ctx, parentId, range, isSelfClosing, nameId, attrIds) { - super(ctx, parentId); - - this.#ctx = ctx; - this.selfClosing = isSelfClosing; - this.#nameId = nameId; - this.#attrIds = attrIds; - this.range = range; - } -} - -/** @implements {Deno.JSXOpeningFragment} */ -class JSXOpeningFragment extends Node { - type = /** @type {const} */ ("JSXOpeningFragment"); - range; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - */ - constructor(ctx, parentId, range) { - super(ctx, parentId); - - this.range = range; - } -} - -/** @implements {Deno.JSXSpreadAttribute} */ -class JSXSpreadAttribute extends Node { - type = /** @type {const} */ ("JSXSpreadAttribute"); - range; - - get argument() { - return /** @type {Deno.Expression} */ (createAstNode( - this.#ctx, - this.#argId, - )); - } - - #ctx; - #argId; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} argId - */ - constructor(ctx, parentId, range, argId) { - super(ctx, parentId); - - this.#ctx = ctx; - this.range = range; - this.#argId = argId; - } -} - -/** @implements {Deno.JSXText} */ -class JSXText extends Node { - type = /** @type {const} */ ("JSXText"); - range; - - value = ""; - raw = ""; - - /** - * @param {AstContext} ctx - * @param {number} parentId - * @param {Deno.Range} range - * @param {number} valueId - * @param {number} rawId - */ - constructor(ctx, parentId, range, valueId, rawId) { - super(ctx, parentId); - - this.range = range; - this.value = getString(ctx, valueId); - this.raw = getString(ctx, rawId); - } -} +// /** @implements {Deno.ArrayPattern} */ +// class ArrayPattern extends Node { +// constructor(ctx, parentId, range, flags, elemIds, typeId) { +// super(ctx, parentId); + +// this.#ctx = ctx; +// this.range = range; + +// this.optional = (flags & Flags.ParamOptional) !== 0; +// this.#elemIds = elemIds; +// this.#typeId = typeId; +// } +// } + +// /** @implements {Deno.ObjectPattern} */ +// class ObjectPattern extends Node { +// type = /** @type {const} */ ("ObjectPattern"); +// range; + +// constructor(ctx, parentId, range, flags, elemIds, typeId) { +// super(ctx, parentId); + +// this.#ctx = ctx; +// this.range = range; + +// this.optional = (flags & Flags.ParamOptional) !== 0; +// this.#elemIds = elemIds; +// this.#typeId = typeId; +// } +// } + +// /** @implements {Deno.JSXIdentifier} */ +// class JSXIdentifier extends Node { +// type = /** @type {const} */ ("JSXIdentifier"); +// range; +// name; + +// /** +// * @param {AstContext} ctx +// * @param {number} parentId +// * @param {Deno.Range} range +// * @param {number} nameId +// */ +// constructor(ctx, parentId, range, nameId) { +// super(ctx, parentId); + +// this.range = range; +// this.name = getString(ctx, nameId); +// } +// } + +// /** @implements {Deno.JSXOpeningElement} */ +// class JSXOpeningElement extends Node { +// constructor(ctx, parentId, range, isSelfClosing, nameId, attrIds) { +// super(ctx, parentId); + +// this.#ctx = ctx; +// this.selfClosing = isSelfClosing; +// this.#nameId = nameId; +// this.#attrIds = attrIds; +// this.range = range; +// } +// } const DECODER = new TextDecoder(); @@ -3096,29 +1096,6 @@ function readU32(buf, i) { buf[i + 3]; } -/** - * @param {Uint8Array} buf - * @param {number} offset - * @returns {number[]} - */ -function readChildIds(buf, offset) { - const count = readU32(buf, offset); - offset += 4; - // console.log("read children count:", count, offset); - - /** @type {number[]} */ - const out = new Array(count); - - for (let i = 0; i < count; i++) { - out[i] = readU32(buf, offset); - offset += 4; - } - - // console.log("read children", out); - - return out; -} - /** * @param {AstContext} ctx * @param {number} id @@ -3133,557 +1110,11 @@ function getString(ctx, id) { return name; } -/** - * @param {AstContext} ctx - * @param {number} id - * @returns {Deno.AstNode} - */ -function createAstNode(ctx, id) { - const { buf, idTable } = ctx; - - let offset = idTable[id]; - if (offset >= buf.length) { - throw new Error( - `Could not find id: ${id}. Offset ${offset} bigger than buffer length: ${buf.length}`, - ); - } - - // console.log({ id, offset }); - /** @type {AstType} */ - const kind = buf[offset]; - console.log("creating node", id, kind); - - const parentId = readU32(buf, offset + 1); - const rangeStart = readU32(buf, offset + 5); - const rangeEnd = readU32(buf, offset + 9); - const range = /** @type {Deno.Range} */ ([rangeStart, rangeEnd]); - - offset += 13; - - switch (kind) { - case AstType.Program: { - const moduleType = buf[offset] === 1 ? "module" : "script"; - const childIds = readChildIds(buf, offset + 1); - return new Program(ctx, parentId, range, moduleType, childIds); - } - case AstType.Import: - case AstType.ImportDecl: - case AstType.ExportDecl: - case AstType.ExportNamed: - case AstType.ExportDefaultDecl: - case AstType.ExportDefaultExpr: - case AstType.ExportAll: - throw new Error("FIXME"); - - // Declarations - case AstType.FunctionDeclaration: { - const flags = buf[offset]; - const identId = readU32(buf, offset + 1); - const typeParamsId = readU32(buf, offset + 5); - const returnTypeId = readU32(buf, offset + 9); - const bodyId = readU32(buf, offset + 13); - const paramIds = readChildIds(buf, offset + 17); - return new FunctionDeclaration( - ctx, - parentId, - range, - flags, - identId, - typeParamsId, - paramIds, - returnTypeId, - bodyId, - ); - } - case AstType.VariableDeclaration: { - const flags = buf[offset]; - const childIds = readChildIds(buf, offset + 1); - return new VariableDeclaration(ctx, parentId, range, flags, childIds); - } - case AstType.VariableDeclarator: { - const nameId = readU32(buf, offset); - const initId = readU32(buf, offset + 4); - return new VariableDeclarator(ctx, parentId, range, nameId, initId); - } - - // Statements - case AstType.BlockStatement: { - const childIds = readChildIds(buf, offset); - return new BlockStatement(ctx, parentId, range, childIds); - } - case AstType.BreakStatement: { - const labelId = readU32(buf, offset); - return new BreakStatement(ctx, parentId, range, labelId); - } - case AstType.ContinueStatement: { - const labelId = readU32(buf, offset); - return new ContinueStatement(ctx, parentId, range, labelId); - } - case AstType.DebuggerStatement: - return new DebuggerStatement(ctx, parentId, range); - case AstType.DoWhileStatement: { - const exprId = readU32(buf, offset); - const bodyId = readU32(buf, offset + 4); - return new DoWhileStatement(ctx, parentId, range, exprId, bodyId); - } - case AstType.ExpressionStatement: { - const exprId = readU32(buf, offset); - return new ExpressionStatement(ctx, parentId, range, exprId); - } - case AstType.ForInStatement: { - const leftId = readU32(buf, offset); - const rightId = readU32(buf, offset + 4); - const bodyId = readU32(buf, offset + 8); - return new ForInStatement(ctx, parentId, range, leftId, rightId, bodyId); - } - case AstType.ForOfStatement: { - const flags = buf[offset]; - const isAwait = (flags & Flags.ForAwait) !== 0; - const leftId = readU32(buf, offset + 1); - const rightId = readU32(buf, offset + 5); - const bodyId = readU32(buf, offset + 9); - return new ForOfStatement( - ctx, - parentId, - range, - isAwait, - leftId, - rightId, - bodyId, - ); - } - case AstType.ForStatement: { - const initId = readU32(buf, offset); - const testId = readU32(buf, offset + 4); - const updateId = readU32(buf, offset + 8); - const bodyId = readU32(buf, offset + 12); - return new ForStatement( - ctx, - parentId, - range, - initId, - testId, - updateId, - bodyId, - ); - } - case AstType.IfStatement: { - const testId = readU32(buf, offset); - const consequentId = readU32(buf, offset + 4); - const alternateId = readU32(buf, offset + 8); - return new IfStatement( - ctx, - parentId, - range, - testId, - consequentId, - alternateId, - ); - } - case AstType.LabeledStatement: { - const labelId = readU32(buf, offset); - const stmtId = readU32(buf, offset + 4); - return new LabeledStatement(ctx, parentId, range, labelId, stmtId); - } - case AstType.ReturnStatement: { - const argId = readU32(buf, offset); - return new ReturnStatement(ctx, parentId, range, argId); - } - case AstType.SwitchStatement: { - const exprId = readU32(buf, offset); - const caseIds = readChildIds(buf, offset + 4); - return new SwitchStatement(ctx, parentId, range, exprId, caseIds); - } - case AstType.SwitchCase: { - const testId = readU32(buf, offset); - const consIds = readChildIds(buf, offset + 4); - return new SwitchCase(ctx, parentId, range, testId, consIds); - } - case AstType.ThrowStatement: { - const argId = readU32(buf, offset); - return new ThrowStatement(ctx, parentId, range, argId); - } - case AstType.TryStatement: { - const blockId = readU32(buf, offset); - const catchId = readU32(buf, offset + 4); - const finalId = readU32(buf, offset + 8); - return new TryStatement(ctx, parentId, range, blockId, catchId, finalId); - } - case AstType.WhileStatement: { - const testId = readU32(buf, offset); - const stmtId = readU32(buf, offset + 4); - return new WhileStatement(ctx, parentId, range, testId, stmtId); - } - case AstType.WithStatement: - return new WithStatement(ctx, range, 0, 0); - - // Expressions - case AstType.ArrayExpression: { - const elemIds = readChildIds(buf, offset); - return new ArrayExpression(ctx, parentId, range, elemIds); - } - case AstType.ArrowFunctionExpression: { - const flags = buf[offset]; - offset += 1; - - const isAsync = (flags & Flags.FnAsync) !== 0; - const isGenerator = (flags & Flags.FnGenerator) !== 0; - - const typeParamId = readU32(buf, offset); - offset += 4; - const paramIds = readChildIds(buf, offset); - offset += 4; - offset += paramIds.length * 4; - - const bodyId = readU32(buf, offset); - offset += 4; - - const returnTypeId = readU32(buf, offset); - offset += 4; - - return new ArrowFunctionExpression( - ctx, - parentId, - range, - isAsync, - isGenerator, - typeParamId, - paramIds, - bodyId, - returnTypeId, - ); - } - case AstType.AssignmentExpression: { - const flags = buf[offset]; - const leftId = readU32(buf, offset + 1); - const rightId = readU32(buf, offset + 5); - return new AssignmentExpression( - ctx, - parentId, - range, - flags, - leftId, - rightId, - ); - } - case AstType.AwaitExpression: { - const argId = readU32(buf, offset); - return new AwaitExpression(ctx, parentId, range, argId); - } - case AstType.BinaryExpression: { - const flags = buf[offset]; - const leftId = readU32(buf, offset + 1); - const rightId = readU32(buf, offset + 5); - return new BinaryExpression(ctx, parentId, range, flags, leftId, rightId); - } - case AstType.CallExpression: { - const flags = buf[offset]; - offset += 1; - const calleeId = readU32(buf, offset); - const typeArgId = readU32(buf, offset + 4); - const childIds = readChildIds(buf, offset + 8); - return new CallExpression( - ctx, - parentId, - range, - flags, - calleeId, - typeArgId, - childIds, - ); - } - case AstType.ChainExpression: { - const argId = readU32(buf, offset); - return new ChainExpression(ctx, parentId, range, argId); - } - case AstType.ConditionalExpression: { - const testId = readU32(buf, offset); - const consId = readU32(buf, offset + 4); - const altId = readU32(buf, offset + 8); - return new ConditionalExpression( - ctx, - parentId, - range, - testId, - consId, - altId, - ); - } - case AstType.FunctionExpression: { - const flags = buf[offset]; - const identId = readU32(buf, offset + 1); - const typeParamId = readU32(buf, offset + 5); - const returnTypeId = readU32(buf, offset + 9); - const bodyId = readU32(buf, offset + 13); - const paramIds = readChildIds(buf, offset + 17); - return new FunctionExpression( - ctx, - parentId, - range, - flags, - identId, - typeParamId, - returnTypeId, - bodyId, - paramIds, - ); - } - case AstType.Identifier: { - const strId = readU32(buf, offset); - return new Identifier(ctx, parentId, range, strId); - } - case AstType.LogicalExpression: { - const flags = buf[offset]; - const leftId = readU32(buf, offset + 1); - const rightId = readU32(buf, offset + 5); - return new LogicalExpression( - ctx, - parentId, - range, - flags, - leftId, - rightId, - ); - } - case AstType.MemberExpression: { - const flags = buf[offset]; - offset += 1; - const objId = readU32(buf, offset); - offset += 4; - const propId = readU32(buf, offset); - return new MemberExpression(ctx, parentId, range, flags, objId, propId); - } - case AstType.MetaProperty: - throw new MetaProperty(ctx, parentId, range, 0, 0); // FIXME - case AstType.NewExpression: { - const calleeId = readU32(buf, offset); - const typeId = readU32(buf, offset + 4); // FIXME - const childIds = readChildIds(buf, offset + 8); - throw new NewExpression(ctx, parentId, range, calleeId, childIds); - } - case AstType.ObjectExpression: { - const elemIds = readChildIds(buf, offset); - return new ObjectExpression(ctx, parentId, range, elemIds); - } - case AstType.ParenthesisExpression: { - const exprId = readU32(buf, offset); - return new ParenthesisExpression(ctx, parentId, range, exprId); - } - case AstType.PrivateIdentifier: { - const strId = readU32(buf, offset); - return new PrivateIdentifier(ctx, parentId, range, strId); - } - case AstType.Property: { - const flags = buf[offset]; // FIXME - const keyId = readU32(buf, offset + 1); - const valueId = readU32(buf, offset + 5); - return new Property(ctx, parentId, range, keyId, valueId); - } - case AstType.RestElement: { - const typeId = readU32(buf, offset); - const argId = readU32(buf, offset + 4); - return new RestElement(ctx, parentId, range, argId, typeId); - } - case AstType.SequenceExpression: { - const childIds = readChildIds(buf, offset); - return new SequenceExpression(ctx, parentId, range, childIds); - } - case AstType.SpreadElement: { - const exprId = readU32(buf, offset); - return new SpreadElement(ctx, parentId, range, exprId); - } - case AstType.Super: - throw new Super(ctx, parentId, range); - case AstType.TaggedTemplateExpression: { - const tagId = readU32(buf, offset); - const typeParamId = readU32(buf, offset + 4); - const quasiId = readU32(buf, offset + 8); - return new TaggedTemplateExpression( - ctx, - parentId, - range, - tagId, - typeParamId, - quasiId, - ); - } - - case AstType.TemplateElement: { - const flags = buf[offset]; - const tail = (flags & Flags.TplTail) !== 0; - const rawId = readU32(buf, offset + 1); - const cookedId = readU32(buf, offset + 5); - return new TemplateElement(ctx, parentId, range, rawId, cookedId, tail); - } - case AstType.TemplateLiteral: { - const quasiIds = readChildIds(buf, offset); - offset += 4; - offset += quasiIds.length * 4; - const exprIds = readChildIds(buf, offset); - return new TemplateLiteral(ctx, parentId, range, quasiIds, exprIds); - } - case AstType.UnaryExpression: { - const flags = buf[offset]; - const exprId = readU32(buf, offset + 1); - return new UnaryExpression(ctx, parentId, range, flags, exprId); - } - case AstType.UpdateExpression: { - const flags = buf[offset]; - const exprId = readU32(buf, offset + 1); - return new UpdateExpression(ctx, parentId, range, flags, exprId); - } - case AstType.YieldExpression: { - const flags = buf[offset]; - const exprId = readU32(buf, offset + 1); - return new YieldExpression(ctx, parentId, range, flags, exprId); - } - - // Literals - case AstType.BooleanLiteral: { - const flags = buf[offset]; - return new BooleanLiteral(ctx, parentId, range, flags); - } - case AstType.BigIntLiteral: { - const strId = readU32(buf, offset); - return new BigIntLiteral(ctx, parentId, range, strId); - } - case AstType.NullLiteral: - return new NullLiteral(ctx, parentId, range); - case AstType.NumericLiteral: { - const strId = readU32(buf, offset); - return new NumericLiteral(ctx, parentId, range, strId); - } - case AstType.RegExpLiteral: { - const patternId = readU32(buf, offset); - const flagsId = readU32(buf, offset + 4); - return new RegExpLiteral(ctx, parentId, range, patternId, flagsId); - } - case AstType.StringLiteral: { - const strId = readU32(buf, offset); - return new StringLiteral(ctx, parentId, range, strId); - } - - // Patterns - case AstType.ArrayPattern: { - const flags = buf[offset]; - const typeId = readU32(buf, offset + 1); - const elemIds = readChildIds(buf, offset + 5); - - return new ArrayPattern(ctx, parentId, range, flags, elemIds, typeId); - } - case AstType.ObjectPattern: { - const flags = buf[offset]; - const typeId = readU32(buf, offset + 1); - const elemIds = readChildIds(buf, offset + 5); - - return new ObjectPattern(ctx, parentId, range, flags, elemIds, typeId); - } - case AstType.AssignmentPattern: { - const leftId = readU32(buf, offset); - const rightId = readU32(buf, offset + 4); - - return new AssignmentPattern(ctx, parentId, range, leftId, rightId); - } - - // JSX - case AstType.JSXAttribute: { - const nameId = readU32(buf, offset); - const valueId = readU32(buf, offset + 4); - return new JSXAttribute(ctx, parentId, range, nameId, valueId); - } - case AstType.JSXClosingElement: { - const nameId = readU32(buf, offset); - return new JSXClosingElement(ctx, parentId, range, nameId); - } - case AstType.JSXClosingFragment: - return new JSXClosingFragment(ctx, parentId, range); - case AstType.JSXElement: { - const openingId = readU32(buf, offset); - const closingId = readU32(buf, offset + 4); - const childIds = readChildIds(buf, offset + 8); - return new JSXElement( - ctx, - parentId, - range, - openingId, - closingId, - childIds, - ); - } - case AstType.JSXEmptyExpression: { - return new JSXEmptyExpression(ctx, parentId, range); - } - case AstType.JSXExpressionContainer: { - const exprId = readU32(buf, offset); - return new JSXExpressionContainer(ctx, parentId, range, exprId); - } - case AstType.JSXFragment: { - const openingId = readU32(buf, offset); - const closingId = readU32(buf, offset + 4); - const childIds = readChildIds(buf, offset + 8); - return new JSXFragment( - ctx, - parentId, - range, - openingId, - closingId, - childIds, - ); - } - case AstType.JSXIdentifier: { - const strId = readU32(buf, offset); - return new JSXIdentifier(ctx, parentId, range, strId); - } - case AstType.JSXMemberExpression: { - const objId = readU32(buf, offset); - const propId = readU32(buf, offset + 4); - return new JSXMemberExpression(ctx, parentId, range, objId, propId); - } - case AstType.JSXNamespacedName: - throw new JSXNamespacedName(ctx, range, 0, 0); // FIXME - case AstType.JSXOpeningElement: { - const flags = buf[offset]; - const nameId = readU32(buf, offset + 1); - const attrIds = readChildIds(buf, offset + 5); - - const isSelfClosing = (flags & Flags.JSXSelfClosing) !== 0; - - return new JSXOpeningElement( - ctx, - parentId, - range, - isSelfClosing, - nameId, - attrIds, - ); - } - case AstType.JSXOpeningFragment: - return new JSXOpeningFragment(ctx, parentId, range); - case AstType.JSXSpreadAttribute: { - const childId = readU32(buf, offset); - return new JSXSpreadAttribute(ctx, parentId, range, childId); - } - case AstType.JSXSpreadChild: - throw new Error(`JSXSpreadChild not supported`); - case AstType.JSXText: { - const rawId = readU32(buf, offset); - const valueId = readU32(buf, offset + 4); - return new JSXText(ctx, parentId, range, rawId, valueId); - } - - default: - throw new Error(`Unknown ast node ${kind}`); - } -} - /** * @param {Uint8Array} buf * @param {AstContext} buf */ function createAstContext(buf) { - // console.log(buf); - - // Extract string table /** @type {Map} */ const strTable = new Map(); @@ -3730,7 +1161,6 @@ function createAstContext(buf) { offset += 4; } - // console.log({ idCount, idTable }); if (idTable.length !== idCount) { throw new Error( `Could not deserialize id table. Expected ${idCount} items, but got ${idTable.length}`, @@ -3837,6 +1267,24 @@ function traverse(ctx, visitor) { traverseInner(ctx, visitTypes, visitor, ctx.rootId); } +const SKIP_CHILD_TRAVERSAL = new Set([ + AstType.BooleanLiteral, + AstType.BigIntLiteral, + AstType.DebuggerStatement, + AstType.Identifier, + AstType.JSXClosingFragment, + AstType.JSXEmptyExpression, + AstType.JSXOpeningFragment, + AstType.JSXText, + AstType.NullLiteral, + AstType.NumericLiteral, + AstType.PrivateIdentifier, + AstType.RegExpLiteral, + AstType.StringLiteral, + AstType.TemplateLiteral, + AstType.This, +]); + /** * @param {AstContext} ctx * @param {Map} visitTypes @@ -3857,352 +1305,48 @@ function traverseInner(ctx, visitTypes, visitor, id) { if (offset === undefined) throw new Error(`Unknown id: ${id}`); const type = buf[offset]; + // console.log({ id, type, offset }); const name = visitTypes.get(type); if (name !== undefined) { - const node = createAstNode(ctx, id); + // console.log("--> invoking visitor"); + const node = new Node(ctx, offset); visitor[name](node); } + if (SKIP_CHILD_TRAVERSAL.has(type)) return; + // type + parentId + SpanLo + SpanHi offset += 1 + 4 + 4 + 4; - // Children - switch (type) { - case AstType.Program: { - // skip flag reading during traversal + const propCount = buf[offset]; + offset += 1; + // console.log({ propCount }); + + for (let i = 0; i < propCount; i++) { + const searchProp = buf[offset]; + offset += 1; + + if (searchProp === AST_PROP_INTERNAL_FLAGS) { offset += 1; - const childIds = readChildIds(buf, offset); - traverseChildren(ctx, visitTypes, visitor, childIds); - return; - } - case AstType.FunctionDeclaration: { - // Skip flags - offset += 1; - - const identId = readU32(buf, offset); - const typeParamsId = readU32(buf, offset + 4); - const returnTypeId = readU32(buf, offset + 8); - const bodyId = readU32(buf, offset + 12); - const paramIds = readChildIds(buf, offset + 16); - - traverseInner(ctx, visitTypes, visitor, identId); - traverseInner(ctx, visitTypes, visitor, typeParamsId); - traverseChildren(ctx, visitTypes, visitor, paramIds); - - traverseInner(ctx, visitTypes, visitor, returnTypeId); - traverseInner(ctx, visitTypes, visitor, bodyId); - - return; - } - case AstType.VariableDeclaration: { - // Skip flags - offset += 1; - - const childIds = readChildIds(buf, offset); - traverseChildren(ctx, visitTypes, visitor, childIds); - return; - } - case AstType.ForStatement: { - const initId = readU32(buf, offset); - const testId = readU32(buf, offset + 4); - const updateId = readU32(buf, offset + 8); - const bodyId = readU32(buf, offset + 12); - - traverseInner(ctx, visitTypes, visitor, initId); - traverseInner(ctx, visitTypes, visitor, testId); - traverseInner(ctx, visitTypes, visitor, updateId); - traverseInner(ctx, visitTypes, visitor, bodyId); - return; + continue; } - case AstType.SwitchStatement: { - const exprId = readU32(buf, offset); - const caseIds = readChildIds(buf, offset + 4); - - traverseInner(ctx, visitTypes, visitor, exprId); - traverseChildren(ctx, visitTypes, visitor, caseIds); - return; - } - case AstType.SwitchCase: { - const testId = readU32(buf, offset); - const consIds = readChildIds(buf, offset + 4); - - traverseInner(ctx, visitTypes, visitor, testId); - traverseChildren(ctx, visitTypes, visitor, consIds); - return; - } - - // Multiple children only - case AstType.ArrayExpression: - case AstType.BlockStatement: - case AstType.ObjectExpression: - case AstType.SequenceExpression: { - const stmtsIds = readChildIds(buf, offset); - traverseChildren(ctx, visitTypes, visitor, stmtsIds); - return; - } - - // Expressions - case AstType.CallExpression: { - offset += 1; // skip flags - const calleeId = readU32(buf, offset); - const typeArgId = readU32(buf, offset + 4); - const childIds = readChildIds(buf, offset + 8); - - traverseInner(ctx, visitTypes, visitor, calleeId); - traverseInner(ctx, visitTypes, visitor, typeArgId); - traverseChildren(ctx, visitTypes, visitor, childIds); - - return; - } - case AstType.ArrowFunctionExpression: { - // Skip flags - offset += 1; - - const typeParamId = readU32(buf, offset); + if (isArrayProp(type, searchProp)) { + const len = readU32(buf, offset); offset += 4; - if (typeParamId > 0) { - traverseInner(ctx, visitTypes, visitor, typeParamId); + + for (let j = 0; j < len; j++) { + const childId = readU32(buf, offset); + offset += 4; + traverseInner(ctx, visitTypes, visitor, childId); } - - const childIds = readChildIds(buf, offset); - offset += 4; - offset += childIds.length * 4; - traverseChildren(ctx, visitTypes, visitor, childIds); - - const bodyId = readU32(buf, offset); - offset += 4; - traverseInner(ctx, visitTypes, visitor, bodyId); - - const returnTypeId = readU32(buf, offset); - traverseInner(ctx, visitTypes, visitor, returnTypeId); - - return; - } - case AstType.MemberExpression: { - // Skip flags - offset += 1; - - const objId = readU32(buf, offset); - const propId = readU32(buf, offset + 4); - - traverseInner(ctx, visitTypes, visitor, objId); - traverseInner(ctx, visitTypes, visitor, propId); - - return; - } - case AstType.AssignmentExpression: { - // Skip flags - offset += 1; - - const leftId = readU32(buf, offset); - const rightId = readU32(buf, offset + 4); - - traverseInner(ctx, visitTypes, visitor, leftId); - traverseInner(ctx, visitTypes, visitor, rightId); - - return; - } - case AstType.BinaryExpression: - case AstType.LogicalExpression: { - // Skip flags - offset += 1; - - const leftId = readU32(buf, offset); - const rightId = readU32(buf, offset + 4); - - traverseInner(ctx, visitTypes, visitor, leftId); - traverseInner(ctx, visitTypes, visitor, rightId); - - return; - } - case AstType.Property: { - // Skip flags - offset += 1; - - const keyId = readU32(buf, offset); - const valueId = readU32(buf, offset + 4); - - traverseInner(ctx, visitTypes, visitor, keyId); - traverseInner(ctx, visitTypes, visitor, valueId); - - return; + continue; } - case AstType.JSXElement: - case AstType.JSXFragment: { - const openingId = readU32(buf, offset); - const closingId = readU32(buf, offset + 4); - const childIds = readChildIds(buf, offset + 8); - - traverseInner(ctx, visitTypes, visitor, openingId); - traverseInner(ctx, visitTypes, visitor, closingId); - traverseChildren(ctx, visitTypes, visitor, childIds); - - return; - } - case AstType.JSXOpeningElement: { - // Skip flags - offset += 1; - - const nameId = readU32(buf, offset); - const childIds = readChildIds(buf, offset + 4); - - traverseInner(ctx, visitTypes, visitor, nameId); - traverseChildren(ctx, visitTypes, visitor, childIds); - - return; - } - case AstType.UnaryExpression: - case AstType.UpdateExpression: - case AstType.YieldExpression: { - // Skip flags - offset += 1; - - const exprId = readU32(buf, offset); - traverseInner(ctx, visitTypes, visitor, exprId); - return; - } - case AstType.ForOfStatement: { - // Skip flags - offset += 1; - - const firstId = readU32(buf, offset); - const secondId = readU32(buf, offset + 4); - const thirdId = readU32(buf, offset + 8); - - traverseInner(ctx, visitTypes, visitor, firstId); - traverseInner(ctx, visitTypes, visitor, secondId); - traverseInner(ctx, visitTypes, visitor, thirdId); - return; - } - case AstType.NewExpression: { - const calleeId = readU32(buf, offset); - const typeId = readU32(buf, offset + 4); - const childIds = readChildIds(buf, offset + 8); - - traverseInner(ctx, visitTypes, visitor, calleeId); - traverseInner(ctx, visitTypes, visitor, typeId); - traverseChildren(ctx, visitTypes, visitor, childIds); - - return; - } - case AstType.FunctionExpression: { - offset += 1; // Flag - - const identId = readU32(buf, offset); - const typeParamId = readU32(buf, offset + 4); - const returnTypeId = readU32(buf, offset + 8); - const bodyId = readU32(buf, offset + 12); - const paramIds = readChildIds(buf, offset + 16); - - traverseInner(ctx, visitTypes, visitor, identId); - traverseInner(ctx, visitTypes, visitor, typeParamId); - traverseChildren(ctx, visitTypes, visitor, paramIds); - traverseInner(ctx, visitTypes, visitor, returnTypeId); - traverseInner(ctx, visitTypes, visitor, bodyId); - - return; - } - - // Patterns - case AstType.ArrayPattern: - case AstType.ObjectPattern: { - // Skip flags - offset += 1; - - const typeId = readU32(buf, offset); - const elemIds = readChildIds(buf, offset + 4); - - traverseChildren(ctx, visitTypes, visitor, elemIds); - traverseInner(ctx, visitTypes, visitor, typeId); - - return; - } - - // Three children - case AstType.ConditionalExpression: - case AstType.ForInStatement: - case AstType.IfStatement: - case AstType.TaggedTemplateExpression: { - const firstId = readU32(buf, offset); - const secondId = readU32(buf, offset + 4); - const thirdId = readU32(buf, offset + 8); - - traverseInner(ctx, visitTypes, visitor, firstId); - traverseInner(ctx, visitTypes, visitor, secondId); - traverseInner(ctx, visitTypes, visitor, thirdId); - return; - } - - // Two children - case AstType.AssignmentPattern: - case AstType.DoWhileStatement: - case AstType.JSXAttribute: - case AstType.JSXMemberExpression: - case AstType.LabeledStatement: - case AstType.RestElement: - case AstType.VariableDeclarator: - case AstType.WhileStatement: { - const firstId = readU32(buf, offset); - const secondId = readU32(buf, offset + 4); - - traverseInner(ctx, visitTypes, visitor, firstId); - traverseInner(ctx, visitTypes, visitor, secondId); - return; - } - - // Single child - case AstType.AwaitExpression: - case AstType.BreakStatement: - case AstType.ContinueStatement: - case AstType.ChainExpression: - case AstType.ExpressionStatement: - case AstType.JSXClosingElement: - case AstType.JSXExpressionContainer: - case AstType.JSXIdentifier: - case AstType.JSXSpreadAttribute: - case AstType.ReturnStatement: - case AstType.SpreadElement: - case AstType.ThrowStatement: - case AstType.ParenthesisExpression: { - const childId = readU32(buf, offset); - return traverseInner(ctx, visitTypes, visitor, childId); - } - - // These have no children - case AstType.BooleanLiteral: - case AstType.BigIntLiteral: - case AstType.DebuggerStatement: - case AstType.Identifier: - case AstType.JSXClosingFragment: - case AstType.JSXEmptyExpression: - case AstType.JSXOpeningFragment: - case AstType.JSXText: - case AstType.NullLiteral: - case AstType.NumericLiteral: - case AstType.PrivateIdentifier: - case AstType.RegExpLiteral: - case AstType.StringLiteral: - case AstType.TemplateLiteral: - case AstType.This: - return; - default: - throw new Error(`Unknown ast type: ${type}`); - } -} - -/** - * @param {AstContext} ctx - * @param {Map} visitTypes - * @param {Record} visitor - * @param {number[]} ids - */ -function traverseChildren(ctx, visitTypes, visitor, ids) { - for (let i = 0; i < ids.length; i++) { - const id = ids[i]; - traverseInner(ctx, visitTypes, visitor, id); + const childId = readU32(buf, offset); + traverseInner(ctx, visitTypes, visitor, childId); + offset += 4; } } diff --git a/cli/tools/lint/ast_buf.rs b/cli/tools/lint/ast_buf.rs index 80a95e86b1..3ef778a3ea 100644 --- a/cli/tools/lint/ast_buf.rs +++ b/cli/tools/lint/ast_buf.rs @@ -266,7 +266,7 @@ pub enum AstNode { TSNonNullExpression, TSAsExpression, TsInstantiation, - TsSatisfies, + TSSatisfiesExpression, PrivateIdentifier, ChainExpression, @@ -374,14 +374,17 @@ pub enum AstProp { ClosingFragment, Computed, Consequent, + Cooked, Declarations, Declare, Definite, Delegate, - Discrimininant, + Discriminant, Elements, + ElementTypes, Expression, Expressions, + Exported, Finalizer, Flags, Generator, @@ -392,6 +395,7 @@ pub enum AstProp { Kind, Label, Left, + Local, Members, Meta, Method, @@ -402,6 +406,7 @@ pub enum AstProp { OpeningFragment, Operator, Optional, + Param, Params, Pattern, Prefix, @@ -422,6 +427,7 @@ pub enum AstProp { TypeAnnotation, TypeArguments, TypeParameters, + Types, Update, Value, } @@ -565,6 +571,7 @@ impl SerializeCtx { kind: AstNode, parent_id: usize, span: &Span, + prop_count: usize, ) { self.id_to_offset.insert(id, self.buf.len()); @@ -575,6 +582,9 @@ impl SerializeCtx { // Span append_u32(&mut self.buf, span.lo.0); append_u32(&mut self.buf, span.hi.0); + + // No node has more than <10 properties + self.buf.push(prop_count as u8); } pub fn write_ids(&mut self, prop: AstProp, ids: I) @@ -619,7 +629,7 @@ impl SerializeCtx { self.id_to_offset.insert(id, self.buf.len()); self.id += 1; - self.write_node(id, kind, parent_id, span); + self.write_node(id, kind, parent_id, span, 0); id } diff --git a/cli/tools/lint/swc.rs b/cli/tools/lint/swc.rs index ac4d93e096..e75db93d35 100644 --- a/cli/tools/lint/swc.rs +++ b/cli/tools/lint/swc.rs @@ -55,7 +55,7 @@ pub fn serialize_ast_bin(parsed_source: &ParsedSource) -> Vec { }) .collect::>(); - ctx.write_node(root_id, AstNode::Program, parent_id, &module.span); + ctx.write_node(root_id, AstNode::Program, parent_id, &module.span, 2); ctx.write_flags(&flags); ctx.write_ids(AstProp::Body, child_ids); } @@ -66,7 +66,7 @@ pub fn serialize_ast_bin(parsed_source: &ParsedSource) -> Vec { .map(|stmt| serialize_stmt(&mut ctx, stmt, root_id)) .collect::>(); - ctx.write_node(root_id, AstNode::Program, parent_id, &script.span); + ctx.write_node(root_id, AstNode::Program, parent_id, &script.span, 2); ctx.write_flags(&flags); ctx.write_ids(AstProp::Body, child_ids); } @@ -148,10 +148,11 @@ fn serialize_module_decl( AstNode::ExportSpecifier, id, &child.span, + 3, ); ctx.write_flags(&flags); - ctx.write_id(org_id); - ctx.write_id(exported_id); + ctx.write_prop(AstProp::Local, org_id); + ctx.write_prop(AstProp::Exported, exported_id); spec_id } @@ -168,6 +169,7 @@ fn serialize_module_decl( AstNode::ExportNamedDeclaration, parent_id, &node.span, + 3, ); ctx.write_flags(&flags); ctx.write_prop(AstProp::Source, src_id); @@ -211,7 +213,7 @@ fn serialize_stmt( .map(|stmt| serialize_stmt(ctx, stmt, parent_id)) .collect::>(); - ctx.write_node(id, AstNode::Block, parent_id, &node.span); + ctx.write_node(id, AstNode::Block, parent_id, &node.span, 1); ctx.write_ids(AstProp::Body, children); id @@ -229,8 +231,8 @@ fn serialize_stmt( .as_ref() .map_or(0, |arg| serialize_expr(ctx, arg, id)); - ctx.write_node(id, AstNode::Return, parent_id, &node.span); - ctx.write_id(arg_id); + ctx.write_node(id, AstNode::Return, parent_id, &node.span, 1); + ctx.write_prop(AstProp::Argument, arg_id); id } @@ -240,9 +242,9 @@ fn serialize_stmt( let ident_id = serialize_ident(ctx, &node.label, id); let stmt_id = serialize_stmt(ctx, &node.body, id); - ctx.write_node(id, AstNode::Labeled, parent_id, &node.span); - ctx.write_id(ident_id); - ctx.write_id(stmt_id); + ctx.write_node(id, AstNode::Labeled, parent_id, &node.span, 2); + ctx.write_prop(AstProp::Label, ident_id); + ctx.write_prop(AstProp::Body, stmt_id); id } @@ -254,8 +256,8 @@ fn serialize_stmt( .as_ref() .map_or(0, |label| serialize_ident(ctx, label, id)); - ctx.write_node(id, AstNode::Break, parent_id, &node.span); - ctx.write_id(arg_id); + ctx.write_node(id, AstNode::Break, parent_id, &node.span, 1); + ctx.write_prop(AstProp::Label, arg_id); id } @@ -267,8 +269,8 @@ fn serialize_stmt( .as_ref() .map_or(0, |label| serialize_ident(ctx, label, id)); - ctx.write_node(id, AstNode::Continue, parent_id, &node.span); - ctx.write_id(arg_id); + ctx.write_node(id, AstNode::Continue, parent_id, &node.span, 1); + ctx.write_prop(AstProp::Label, arg_id); id } @@ -283,10 +285,10 @@ fn serialize_stmt( .as_ref() .map_or(0, |alt| serialize_stmt(ctx, alt, id)); - ctx.write_node(id, AstNode::IfStatement, parent_id, &node.span); - ctx.write_id(test_id); - ctx.write_id(cons_id); - ctx.write_id(alt_id); + ctx.write_node(id, AstNode::IfStatement, parent_id, &node.span, 3); + ctx.write_prop(AstProp::Test, test_id); + ctx.write_prop(AstProp::Consequent, cons_id); + ctx.write_prop(AstProp::Alternate, alt_id); id } @@ -312,16 +314,16 @@ fn serialize_stmt( .map(|cons| serialize_stmt(ctx, cons, child_id)) .collect::>(); - ctx.write_node(child_id, AstNode::SwitchCase, id, &case.span); - ctx.write_id(test_id); + ctx.write_node(child_id, AstNode::SwitchCase, id, &case.span, 2); + ctx.write_prop(AstProp::Test, test_id); ctx.write_ids(AstProp::Consequent, cons); child_id }) .collect::>(); - ctx.write_node(id, AstNode::Switch, parent_id, &node.span); - ctx.write_id(expr_id); + ctx.write_node(id, AstNode::Switch, parent_id, &node.span, 2); + ctx.write_prop(AstProp::Discriminant, expr_id); ctx.write_ids(AstProp::Cases, case_ids); id @@ -331,8 +333,8 @@ fn serialize_stmt( let expr_id = serialize_expr(ctx, &node.arg, id); - ctx.write_node(id, AstNode::Throw, parent_id, &node.span); - ctx.write_id(expr_id); + ctx.write_node(id, AstNode::Throw, parent_id, &node.span, 1); + ctx.write_prop(AstProp::Argument, expr_id); id } @@ -351,9 +353,9 @@ fn serialize_stmt( let body_id = serialize_stmt(ctx, &Stmt::Block(catch.body.clone()), id); - ctx.write_node(clause_id, AstNode::CatchClause, id, &catch.span); - ctx.write_id(param_id); - ctx.write_id(body_id); + ctx.write_node(clause_id, AstNode::CatchClause, id, &catch.span, 2); + ctx.write_prop(AstProp::Param, param_id); + ctx.write_prop(AstProp::Body, body_id); clause_id }); @@ -362,10 +364,10 @@ fn serialize_stmt( serialize_stmt(ctx, &Stmt::Block(finalizer.clone()), id) }); - ctx.write_node(id, AstNode::TryStatement, parent_id, &node.span); - ctx.write_id(block_id); - ctx.write_id(catch_id); - ctx.write_id(final_id); + ctx.write_node(id, AstNode::TryStatement, parent_id, &node.span, 3); + ctx.write_prop(AstProp::Block, block_id); + ctx.write_prop(AstProp::Handler, catch_id); + ctx.write_prop(AstProp::Finalizer, final_id); id } @@ -375,9 +377,9 @@ fn serialize_stmt( let test_id = serialize_expr(ctx, node.test.as_ref(), id); let stmt_id = serialize_stmt(ctx, node.body.as_ref(), id); - ctx.write_node(id, AstNode::While, parent_id, &node.span); - ctx.write_id(test_id); - ctx.write_id(stmt_id); + ctx.write_node(id, AstNode::While, parent_id, &node.span, 2); + ctx.write_prop(AstProp::Test, test_id); + ctx.write_prop(AstProp::Body, stmt_id); id } @@ -387,9 +389,9 @@ fn serialize_stmt( let expr_id = serialize_expr(ctx, node.test.as_ref(), id); let stmt_id = serialize_stmt(ctx, node.body.as_ref(), id); - ctx.write_node(id, AstNode::DoWhileStatement, parent_id, &node.span); - ctx.write_id(expr_id); - ctx.write_id(stmt_id); + ctx.write_node(id, AstNode::DoWhileStatement, parent_id, &node.span, 2); + ctx.write_prop(AstProp::Test, expr_id); + ctx.write_prop(AstProp::Body, stmt_id); id } @@ -413,11 +415,11 @@ fn serialize_stmt( .map_or(0, |expr| serialize_expr(ctx, expr, id)); let body_id = serialize_stmt(ctx, node.body.as_ref(), id); - ctx.write_node(id, AstNode::ForStatement, parent_id, &node.span); - ctx.write_id(init_id); - ctx.write_id(test_id); - ctx.write_id(update_id); - ctx.write_id(body_id); + ctx.write_node(id, AstNode::ForStatement, parent_id, &node.span, 4); + ctx.write_prop(AstProp::Init, init_id); + ctx.write_prop(AstProp::Test, test_id); + ctx.write_prop(AstProp::Update, update_id); + ctx.write_prop(AstProp::Body, body_id); id } @@ -428,7 +430,7 @@ fn serialize_stmt( let right_id = serialize_expr(ctx, node.right.as_ref(), id); let body_id = serialize_stmt(ctx, node.body.as_ref(), id); - ctx.write_node(id, AstNode::ForInStatement, parent_id, &node.span); + ctx.write_node(id, AstNode::ForInStatement, parent_id, &node.span, 3); ctx.write_prop(AstProp::Left, left_id); ctx.write_prop(AstProp::Right, right_id); ctx.write_prop(AstProp::Block, body_id); @@ -445,7 +447,7 @@ fn serialize_stmt( let right_id = serialize_expr(ctx, node.right.as_ref(), id); let body_id = serialize_stmt(ctx, node.body.as_ref(), id); - ctx.write_node(id, AstNode::ForOfStatement, parent_id, &node.span); + ctx.write_node(id, AstNode::ForOfStatement, parent_id, &node.span, 4); ctx.write_flags(&flags); ctx.write_prop(AstProp::Left, left_id); ctx.write_prop(AstProp::Right, right_id); @@ -458,7 +460,13 @@ fn serialize_stmt( let id = ctx.next_id(); let child_id = serialize_expr(ctx, node.expr.as_ref(), id); - ctx.write_node(id, AstNode::ExpressionStatement, parent_id, &node.span); + ctx.write_node( + id, + AstNode::ExpressionStatement, + parent_id, + &node.span, + 1, + ); ctx.write_prop(AstProp::Expression, child_id); id @@ -486,7 +494,7 @@ fn serialize_expr( }) .collect::>(); - ctx.write_node(id, AstNode::Array, parent_id, &node.span); + ctx.write_node(id, AstNode::Array, parent_id, &node.span, 1); ctx.write_ids(AstProp::Elements, elem_ids); id @@ -541,6 +549,7 @@ fn serialize_expr( AstNode::AssignmentPattern, prop_id, &assign_prop.span, + 2, ); ctx.write_id(key_id); ctx.write_id(value_id); @@ -622,7 +631,7 @@ fn serialize_expr( } }; - ctx.write_node(prop_id, AstNode::Property, id, &prop.span()); + ctx.write_node(prop_id, AstNode::Property, id, &prop.span(), 3); ctx.write_flags(&flags); ctx.write_id(key_id); ctx.write_id(value_id); @@ -633,7 +642,7 @@ fn serialize_expr( }) .collect::>(); - ctx.write_node(id, AstNode::Object, parent_id, &node.span); + ctx.write_node(id, AstNode::Object, parent_id, &node.span, 1); ctx.write_ids(AstProp::Properties, prop_ids); id @@ -669,7 +678,13 @@ fn serialize_expr( serialize_stmt(ctx, &Stmt::Block(block.clone()), id) }); - ctx.write_node(id, AstNode::FunctionExpression, parent_id, &fn_obj.span); + ctx.write_node( + id, + AstNode::FunctionExpression, + parent_id, + &fn_obj.span, + 6, + ); ctx.write_flags(&flags); ctx.write_prop(AstProp::Id, ident_id); ctx.write_prop(AstProp::TypeParameters, type_param_id); @@ -695,7 +710,7 @@ fn serialize_expr( let child_id = serialize_expr(ctx, &node.arg, id); - ctx.write_node(id, AstNode::Unary, parent_id, &node.span); + ctx.write_node(id, AstNode::Unary, parent_id, &node.span, 2); ctx.write_flags(&flags); ctx.write_prop(AstProp::Argument, child_id); @@ -715,7 +730,7 @@ fn serialize_expr( let child_id = serialize_expr(ctx, node.arg.as_ref(), id); - ctx.write_node(id, AstNode::UpdateExpression, parent_id, &node.span); + ctx.write_node(id, AstNode::UpdateExpression, parent_id, &node.span, 2); ctx.write_flags(&flags); ctx.write_prop(AstProp::Argument, child_id); @@ -764,7 +779,7 @@ fn serialize_expr( let left_id = serialize_expr(ctx, node.left.as_ref(), id); let right_id = serialize_expr(ctx, node.right.as_ref(), id); - ctx.write_node(id, node_type, parent_id, &node.span); + ctx.write_node(id, node_type, parent_id, &node.span, 3); ctx.write_flags(&flags); ctx.write_prop(AstProp::Left, left_id); ctx.write_prop(AstProp::Right, right_id); @@ -809,7 +824,7 @@ fn serialize_expr( let right_id = serialize_expr(ctx, node.right.as_ref(), id); - ctx.write_node(id, AstNode::Assign, parent_id, &node.span); + ctx.write_node(id, AstNode::Assign, parent_id, &node.span, 3); ctx.write_u8(assign_op_to_flag(node.op)); ctx.write_prop(AstProp::Left, left_id); ctx.write_prop(AstProp::Right, right_id); @@ -834,7 +849,7 @@ fn serialize_expr( SuperProp::Computed(prop) => serialize_expr(ctx, &prop.expr, id), }; - ctx.write_node(id, AstNode::MemberExpression, parent_id, &node.span); + ctx.write_node(id, AstNode::MemberExpression, parent_id, &node.span, 3); ctx.write_flags(&flags); ctx.write_id(super_id); ctx.write_id(child_id); @@ -848,7 +863,7 @@ fn serialize_expr( let cons_id = serialize_expr(ctx, node.cons.as_ref(), id); let alt_id = serialize_expr(ctx, node.alt.as_ref(), id); - ctx.write_node(id, AstNode::Cond, parent_id, &node.span); + ctx.write_node(id, AstNode::Cond, parent_id, &node.span, 3); ctx.write_prop(AstProp::Test, test_id); ctx.write_prop(AstProp::Consequent, cons_id); ctx.write_prop(AstProp::Alternate, alt_id); @@ -876,7 +891,7 @@ fn serialize_expr( .map(|arg| serialize_expr_or_spread(ctx, arg, id)) .collect::>(); - ctx.write_node(id, AstNode::CallExpression, parent_id, &node.span); + ctx.write_node(id, AstNode::CallExpression, parent_id, &node.span, 4); ctx.write_flags(&FlagValue::new()); ctx.write_prop(AstProp::Callee, callee_id); ctx.write_prop(AstProp::TypeArguments, type_id); @@ -900,7 +915,7 @@ fn serialize_expr( // FIXME let type_arg_id = 0; - ctx.write_node(id, AstNode::New, parent_id, &node.span); + ctx.write_node(id, AstNode::New, parent_id, &node.span, 3); ctx.write_prop(AstProp::Callee, callee_id); ctx.write_prop(AstProp::TypeArguments, type_arg_id); ctx.write_ids(AstProp::Arguments, arg_ids); @@ -916,7 +931,7 @@ fn serialize_expr( .map(|expr| serialize_expr(ctx, expr, id)) .collect::>(); - ctx.write_node(id, AstNode::SequenceExpression, parent_id, &node.span); + ctx.write_node(id, AstNode::SequenceExpression, parent_id, &node.span, 1); ctx.write_ids(AstProp::Expressions, children); id @@ -942,10 +957,10 @@ fn serialize_expr( .as_ref() .map_or(0, |cooked| ctx.str_table.insert(cooked.as_str())); - ctx.write_node(tpl_id, AstNode::TemplateElement, id, &quasi.span); + ctx.write_node(tpl_id, AstNode::TemplateElement, id, &quasi.span, 3); ctx.write_flags(&flags); - append_usize(&mut ctx.buf, raw_str_id); - append_usize(&mut ctx.buf, cooked_str_id); + ctx.write_prop(AstProp::Raw, raw_str_id); + ctx.write_prop(AstProp::Cooked, cooked_str_id); tpl_id }) @@ -957,7 +972,7 @@ fn serialize_expr( .map(|expr| serialize_expr(ctx, expr, id)) .collect::>(); - ctx.write_node(id, AstNode::TemplateLiteral, parent_id, &node.span); + ctx.write_node(id, AstNode::TemplateLiteral, parent_id, &node.span, 2); ctx.write_ids(AstProp::Quasis, quasi_ids); ctx.write_ids(AstProp::Expressions, expr_ids); @@ -977,6 +992,7 @@ fn serialize_expr( AstNode::TaggedTemplateExpression, parent_id, &node.span, + 3, ); ctx.write_prop(AstProp::Tag, tag_id); ctx.write_prop(AstProp::TypeArguments, type_param_id); @@ -1019,6 +1035,7 @@ fn serialize_expr( AstNode::ArrowFunctionExpression, parent_id, &node.span, + 4, ); ctx.write_flags(&flags); ctx.write_prop(AstProp::TypeParameters, type_param_id); @@ -1048,7 +1065,7 @@ fn serialize_expr( .as_ref() .map_or(0, |arg| serialize_expr(ctx, arg.as_ref(), id)); - ctx.write_node(id, AstNode::YieldExpression, parent_id, &node.span); + ctx.write_node(id, AstNode::YieldExpression, parent_id, &node.span, 2); ctx.write_flags(&flags); ctx.write_prop(AstProp::Argument, arg_id); @@ -1061,8 +1078,8 @@ fn serialize_expr( let id = ctx.next_id(); let arg_id = serialize_expr(ctx, node.arg.as_ref(), id); - ctx.write_node(id, AstNode::AwaitExpression, parent_id, &node.span); - ctx.write_id(arg_id); + ctx.write_node(id, AstNode::AwaitExpression, parent_id, &node.span, 1); + ctx.write_prop(AstProp::Argument, arg_id); id } @@ -1084,9 +1101,9 @@ fn serialize_expr( let expr_id = serialize_expr(ctx, &node.expr, parent_id); let type_ann_id = serialize_ts_type(ctx, &node.type_ann, id); - ctx.write_node(id, AstNode::TSTypeAssertion, parent_id, &node.span); - ctx.write_id(expr_id); - ctx.write_id(type_ann_id); + ctx.write_node(id, AstNode::TSTypeAssertion, parent_id, &node.span, 2); + ctx.write_prop(AstProp::Expression, expr_id); + ctx.write_prop(AstProp::TypeAnnotation, type_ann_id); id } @@ -1094,8 +1111,9 @@ fn serialize_expr( let id = ctx.next_id(); let expr_id = serialize_expr(ctx, node.expr.as_ref(), id); - ctx.write_node(id, AstNode::TsConstAssertion, parent_id, &node.span); - ctx.write_id(expr_id); + ctx.write_node(id, AstNode::TsConstAssertion, parent_id, &node.span, 1); + // FIXME + ctx.write_prop(AstProp::Argument, expr_id); id } @@ -1103,8 +1121,14 @@ fn serialize_expr( let id = ctx.next_id(); let expr_id = serialize_expr(ctx, node.expr.as_ref(), id); - ctx.write_node(id, AstNode::TSNonNullExpression, parent_id, &node.span); - ctx.write_id(expr_id); + ctx.write_node( + id, + AstNode::TSNonNullExpression, + parent_id, + &node.span, + 1, + ); + ctx.write_prop(AstProp::Expression, expr_id); id } @@ -1114,9 +1138,9 @@ fn serialize_expr( let expr_id = serialize_expr(ctx, node.expr.as_ref(), id); let type_ann_id = serialize_ts_type(ctx, node.type_ann.as_ref(), id); - ctx.write_node(id, AstNode::TSAsExpression, parent_id, &node.span); - ctx.write_id(expr_id); - ctx.write_id(type_ann_id); + ctx.write_node(id, AstNode::TSAsExpression, parent_id, &node.span, 2); + ctx.write_prop(AstProp::Expression, expr_id); + ctx.write_prop(AstProp::TypeAnnotation, type_ann_id); id } @@ -1126,7 +1150,7 @@ fn serialize_expr( let expr_id = serialize_expr(ctx, node.expr.as_ref(), id); // FIXME // let expr_id = serialize_expr(ctx, ts_instantiation.type_args.as_ref(), id); - ctx.write_node(id, AstNode::TsInstantiation, parent_id, &node.span); + ctx.write_node(id, AstNode::TsInstantiation, parent_id, &node.span, 1); ctx.write_id(expr_id); id @@ -1137,9 +1161,15 @@ fn serialize_expr( let expr_id = serialize_expr(ctx, node.expr.as_ref(), id); let type_id = serialize_ts_type(ctx, node.type_ann.as_ref(), id); - ctx.write_node(id, AstNode::TsSatisfies, parent_id, &node.span); - ctx.write_id(expr_id); - ctx.write_id(type_id); + ctx.write_node( + id, + AstNode::TSSatisfiesExpression, + parent_id, + &node.span, + 2, + ); + ctx.write_prop(AstProp::Expression, expr_id); + ctx.write_prop(AstProp::TypeAnnotation, type_id); id } @@ -1168,7 +1198,13 @@ fn serialize_expr( .map(|arg| serialize_expr_or_spread(ctx, arg, id)) .collect::>(); - ctx.write_node(call_id, AstNode::CallExpression, id, &opt_call.span); + ctx.write_node( + call_id, + AstNode::CallExpression, + id, + &opt_call.span, + 4, + ); ctx.write_flags(&flags); ctx.write_prop(AstProp::Callee, callee_id); ctx.write_prop(AstProp::TypeArguments, type_id); @@ -1178,7 +1214,7 @@ fn serialize_expr( } }; - ctx.write_node(id, AstNode::ChainExpression, parent_id, &node.span); + ctx.write_node(id, AstNode::ChainExpression, parent_id, &node.span, 1); ctx.write_prop(AstProp::Expression, arg_id); id @@ -1215,7 +1251,7 @@ fn serialize_member_expr( } }; - ctx.write_node(id, AstNode::MemberExpression, parent_id, &node.span); + ctx.write_node(id, AstNode::MemberExpression, parent_id, &node.span, 3); ctx.write_flags(&flags); ctx.write_prop(AstProp::Object, obj_id); ctx.write_prop(AstProp::Property, prop_id); @@ -1343,6 +1379,7 @@ fn serialize_decl( AstNode::MethodDefinition, id, &constructor.span, + 4, ); ctx.write_flags(&flags); ctx.write_id(key_id); @@ -1381,6 +1418,7 @@ fn serialize_decl( AstNode::MethodDefinition, id, &method.span, + 4, ); ctx.write_flags(&flags); ctx.write_id(key_id); @@ -1405,11 +1443,16 @@ fn serialize_decl( AstNode::ClassDeclaration, parent_id, &node.class.span, + 7, ); ctx.write_flags(&flags); + // FIXME ctx.write_id(ident_id); + // FIXME ctx.write_id(type_param_id); + // FIXME ctx.write_id(super_class_id); + // FIXME ctx.write_id(super_type_params); // FIXME @@ -1449,7 +1492,7 @@ fn serialize_decl( .map(|param| serialize_pat(ctx, ¶m.pat, id)) .collect::>(); - ctx.write_node(id, AstNode::Fn, parent_id, &node.function.span); + ctx.write_node(id, AstNode::Fn, parent_id, &node.function.span, 6); ctx.write_flags(&flags); ctx.write_prop(AstProp::Id, ident_id); ctx.write_prop(AstProp::TypeParameters, type_param_id); @@ -1487,15 +1530,21 @@ fn serialize_decl( .as_ref() .map_or(0, |init| serialize_expr(ctx, init.as_ref(), child_id)); - ctx.write_node(child_id, AstNode::VariableDeclarator, id, &decl.span); - ctx.write_id(decl_id); - ctx.write_id(init_id); + ctx.write_node( + child_id, + AstNode::VariableDeclarator, + id, + &decl.span, + 2, + ); + ctx.write_prop(AstProp::Id, decl_id); + ctx.write_prop(AstProp::Init, init_id); child_id }) .collect::>(); - ctx.write_node(id, AstNode::Var, parent_id, &node.span); + ctx.write_node(id, AstNode::Var, parent_id, &node.span, 2); ctx.write_flags(&flags); ctx.write_ids(AstProp::Declarations, children); @@ -1534,7 +1583,9 @@ fn serialize_decl( AstNode::TSInterfaceHeritage, id, &item.span, + 1, ); + // FIXME ctx.write_id(expr_id); child_id @@ -1564,11 +1615,13 @@ fn serialize_decl( AstNode::TsCallSignatureDeclaration, id, &ts_call.span, + 3, ); - ctx.write_id(type_param_id); + // FIXME + ctx.write_prop(AstProp::TypeAnnotation, type_param_id); // FIXME ctx.write_ids(AstProp::Params, param_ids); - ctx.write_id(return_type_id); + ctx.write_prop(AstProp::ReturnType, return_type_id); item_id } @@ -1584,12 +1637,12 @@ fn serialize_decl( .collect::>(); let body_id = ctx.next_id(); - ctx.write_node(body_id, AstNode::TSInterfaceBody, id, &node.body.span); + ctx.write_node(body_id, AstNode::TSInterfaceBody, id, &node.body.span, 4); // FIXME // ctx.write_ids( body_elem_ids); - ctx.write_node(id, AstNode::TSInterface, parent_id, &node.span); + ctx.write_node(id, AstNode::TSInterface, parent_id, &node.span, 3); ctx.write_flags(&flags); ctx.write_id(ident_id); ctx.write_id(type_param); @@ -1608,15 +1661,15 @@ fn serialize_decl( } let ident_id = serialize_ident(ctx, &node.id, id); - let ts_type_id = serialize_ts_type(ctx, &node.type_ann, id); + let type_ann_id = serialize_ts_type(ctx, &node.type_ann, id); let type_param_id = maybe_serialize_ts_type_param(ctx, &node.type_params, id); - ctx.write_node(id, AstNode::TsTypeAlias, parent_id, &node.span); + ctx.write_node(id, AstNode::TsTypeAlias, parent_id, &node.span, 4); ctx.write_flags(&flags); - ctx.write_id(ident_id); - ctx.write_id(type_param_id); - ctx.write_id(ts_type_id); + ctx.write_prop(AstProp::Id, ident_id); + ctx.write_prop(AstProp::TypeParameters, type_param_id); + ctx.write_prop(AstProp::TypeAnnotation, type_ann_id); id } @@ -1653,7 +1706,7 @@ fn serialize_decl( .as_ref() .map_or(0, |init| serialize_expr(ctx, init, member_id)); - ctx.write_node(member_id, AstNode::TSEnumMember, id, &member.span); + ctx.write_node(member_id, AstNode::TSEnumMember, id, &member.span, 2); ctx.write_id(ident_id); ctx.write_id(init_id); @@ -1661,7 +1714,7 @@ fn serialize_decl( }) .collect::>(); - ctx.write_node(id, AstNode::TSEnumDeclaration, parent_id, &node.span); + ctx.write_node(id, AstNode::TSEnumDeclaration, parent_id, &node.span, 3); ctx.write_flags(&flags); ctx.write_id(ident_id); ctx.write_ids(AstProp::Members, member_ids); @@ -1694,10 +1747,11 @@ fn serialize_private_name( node: &PrivateName, parent_id: usize, ) -> usize { - let id = ctx.push_node(AstNode::PrivateIdentifier, parent_id, &node.span); - + let id = ctx.next_id(); let str_id = ctx.str_table.insert(node.name.as_str()); - append_usize(&mut ctx.buf, str_id); + + ctx.write_node(id, AstNode::PrivateIdentifier, parent_id, &node.span, 1); + ctx.write_prop(AstProp::Name, str_id); id } @@ -1715,15 +1769,21 @@ fn serialize_jsx_element( let closing_id = ctx.next_id(); let child_id = serialize_jsx_element_name(ctx, &closing.name, id); - ctx.write_node(closing_id, AstNode::JSXClosingElement, id, &closing.span); - ctx.write_id(child_id); + ctx.write_node( + closing_id, + AstNode::JSXClosingElement, + id, + &closing.span, + 1, + ); + ctx.write_prop(AstProp::Name, child_id); closing_id }); let children = serialize_jsx_children(ctx, &node.children, id); - ctx.write_node(id, AstNode::JSXElement, parent_id, &node.span); + ctx.write_node(id, AstNode::JSXElement, parent_id, &node.span, 3); ctx.write_prop(AstProp::OpeningElement, opening_id); ctx.write_prop(AstProp::ClosingElement, closing_id); ctx.write_ids(AstProp::Children, children); @@ -1745,7 +1805,7 @@ fn serialize_jsx_fragment( let children = serialize_jsx_children(ctx, &node.children, id); - ctx.write_node(id, AstNode::JSXFragment, parent_id, &node.span); + ctx.write_node(id, AstNode::JSXFragment, parent_id, &node.span, 4); ctx.write_prop(AstProp::OpeningFragment, opening_id); ctx.write_prop(AstProp::ClosingFragment, closing_id); ctx.write_ids(AstProp::Children, children); @@ -1763,13 +1823,14 @@ fn serialize_jsx_children( .map(|child| { match child { JSXElementChild::JSXText(text) => { - let id = ctx.push_node(AstNode::JSXText, parent_id, &text.span); + let id = ctx.next_id(); let raw_id = ctx.str_table.insert(text.raw.as_str()); let value_id = ctx.str_table.insert(text.value.as_str()); - append_usize(&mut ctx.buf, raw_id); - append_usize(&mut ctx.buf, value_id); + ctx.write_node(id, AstNode::JSXText, parent_id, &text.span, 2); + ctx.write_prop(AstProp::Raw, raw_id); + ctx.write_prop(AstProp::Value, value_id); id } @@ -1805,7 +1866,7 @@ fn serialize_jsx_member_expr( let prop_id = serialize_ident_name_as_jsx_identifier(ctx, &node.prop, id); - ctx.write_node(id, AstNode::JSXMemberExpression, parent_id, &node.span); + ctx.write_node(id, AstNode::JSXMemberExpression, parent_id, &node.span, 2); ctx.write_prop(AstProp::Object, obj_id); ctx.write_prop(AstProp::Property, prop_id); @@ -1875,9 +1936,9 @@ fn serialize_jsx_opening_element( } }); - ctx.write_node(attr_id, AstNode::JSXAttribute, id, &jsxattr.span); - ctx.write_id(name_id); - ctx.write_id(value_id); + ctx.write_node(attr_id, AstNode::JSXAttribute, id, &jsxattr.span, 2); + ctx.write_prop(AstProp::Name, name_id); + ctx.write_prop(AstProp::Value, value_id); attr_id } @@ -1885,15 +1946,15 @@ fn serialize_jsx_opening_element( let attr_id = ctx.next_id(); let child_id = serialize_expr(ctx, &spread.expr, attr_id); - ctx.write_node(attr_id, AstNode::JSXAttribute, id, &spread.span()); - ctx.write_id(child_id); + ctx.write_node(attr_id, AstNode::JSXAttribute, id, &spread.span(), 1); + ctx.write_prop(AstProp::Argument, child_id); attr_id } }) .collect::>(); - ctx.write_node(id, AstNode::JSXOpeningElement, parent_id, &node.span); + ctx.write_node(id, AstNode::JSXOpeningElement, parent_id, &node.span, 3); ctx.write_flags(&flags); ctx.write_prop(AstProp::Name, name_id); ctx.write_ids(AstProp::Attributes, attr_ids); @@ -1913,8 +1974,14 @@ fn serialize_jsx_container_expr( JSXExpr::Expr(expr) => serialize_expr(ctx, expr, id), }; - ctx.write_node(id, AstNode::JSXExpressionContainer, parent_id, &node.span); - ctx.write_id(child_id); + ctx.write_node( + id, + AstNode::JSXExpressionContainer, + parent_id, + &node.span, + 1, + ); + ctx.write_prop(AstProp::Expression, child_id); id } @@ -1937,9 +2004,9 @@ fn serialize_jsx_namespaced_name( let ns_id = serialize_ident_name_as_jsx_identifier(ctx, &node.ns, id); let name_id = serialize_ident_name_as_jsx_identifier(ctx, &node.name, id); - ctx.write_node(id, AstNode::JSXNamespacedName, parent_id, &node.span); - ctx.write_id(ns_id); - ctx.write_id(name_id); + ctx.write_node(id, AstNode::JSXNamespacedName, parent_id, &node.span, 2); + ctx.write_prop(AstProp::Namespace, ns_id); + ctx.write_prop(AstProp::Name, name_id); id } @@ -1949,10 +2016,11 @@ fn serialize_ident_name_as_jsx_identifier( node: &IdentName, parent_id: usize, ) -> usize { - let id = ctx.push_node(AstNode::JSXIdentifier, parent_id, &node.span); + let id = ctx.next_id(); let str_id = ctx.str_table.insert(node.sym.as_str()); - append_usize(&mut ctx.buf, str_id); + ctx.write_node(id, AstNode::JSXIdentifier, parent_id, &node.span, 1); + ctx.write_prop(AstProp::Name, str_id); id } @@ -1962,10 +2030,11 @@ fn serialize_jsx_identifier( node: &Ident, parent_id: usize, ) -> usize { - let id = ctx.push_node(AstNode::JSXIdentifier, parent_id, &node.span); + let id = ctx.next_id(); let str_id = ctx.str_table.insert(node.sym.as_str()); - append_usize(&mut ctx.buf, str_id); + ctx.write_node(id, AstNode::JSXIdentifier, parent_id, &node.span, 1); + ctx.write_prop(AstProp::Name, str_id); id } @@ -1989,7 +2058,7 @@ fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize { .map(|pat| pat.as_ref().map_or(0, |v| serialize_pat(ctx, &v, id))) .collect::>(); - ctx.write_node(id, AstNode::ArrayPattern, parent_id, &node.span); + ctx.write_node(id, AstNode::ArrayPattern, parent_id, &node.span, 3); ctx.write_flags(&flags); ctx.write_prop(AstProp::TypeAnnotation, type_ann_id); ctx.write_ids(AstProp::Elements, children); @@ -2002,7 +2071,7 @@ fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize { let type_ann_id = maybe_serialize_ts_type_ann(ctx, &node.type_ann, id); let arg_id = serialize_pat(ctx, &node.arg, parent_id); - ctx.write_node(id, AstNode::RestElement, parent_id, &node.span); + ctx.write_node(id, AstNode::RestElement, parent_id, &node.span, 2); ctx.write_prop(AstProp::TypeAnnotation, type_ann_id); ctx.write_prop(AstProp::Argument, arg_id); @@ -2040,10 +2109,11 @@ fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize { AstNode::Property, id, &key_value_prop.span(), + 3, ); ctx.write_flags(&flags); - ctx.write_id(key_id); - ctx.write_id(value_id); + ctx.write_prop(AstProp::Key, key_id); + ctx.write_prop(AstProp::Value, value_id); child_id } @@ -2063,10 +2133,11 @@ fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize { AstNode::Property, id, &assign_pat_prop.span, + 4, ); ctx.write_flags(&FlagValue::new()); - ctx.write_id(ident_id); - ctx.write_id(value_id); + ctx.write_prop(AstProp::Key, ident_id); + ctx.write_prop(AstProp::Value, value_id); child_id } @@ -2076,7 +2147,7 @@ fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize { }) .collect::>(); - ctx.write_node(id, AstNode::ObjectPattern, parent_id, &node.span); + ctx.write_node(id, AstNode::ObjectPattern, parent_id, &node.span, 2); ctx.write_flags(&flags); ctx.write_ids(AstProp::Properties, children); @@ -2088,9 +2159,9 @@ fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize { let left_id = serialize_pat(ctx, &node.left, id); let right_id = serialize_expr(ctx, &node.right, id); - ctx.write_node(id, AstNode::AssignmentPattern, parent_id, &node.span); - ctx.write_id(left_id); - ctx.write_id(right_id); + ctx.write_node(id, AstNode::AssignmentPattern, parent_id, &node.span, 2); + ctx.write_prop(AstProp::Left, left_id); + ctx.write_prop(AstProp::Right, right_id); id } @@ -2124,8 +2195,8 @@ fn serialize_spread( let id = ctx.next_id(); let expr_id = serialize_expr(ctx, expr, id); - ctx.write_node(id, AstNode::Spread, parent_id, span); - ctx.write_id(expr_id); + ctx.write_node(id, AstNode::Spread, parent_id, span, 1); + ctx.write_prop(AstProp::Argument, expr_id); id } @@ -2262,7 +2333,7 @@ fn serialize_ts_type( .map(|param| serialize_ts_fn_param(ctx, param, id)) .collect::>(); - ctx.write_node(id, AstNode::TSFunctionType, parent_id, &node.span); + ctx.write_node(id, AstNode::TSFunctionType, parent_id, &node.span, 1); // FIXME ctx.write_ids(AstProp::Params, param_ids); // @@ -2279,7 +2350,7 @@ fn serialize_ts_type( // FIXME params - ctx.write_node(id, AstNode::TSTypeReference, parent_id, &node.span); + ctx.write_node(id, AstNode::TSTypeReference, parent_id, &node.span, 1); ctx.write_id(name_id); id @@ -2296,7 +2367,7 @@ fn serialize_ts_type( // FIXME: params - ctx.write_node(id, AstNode::TSTypeQuery, parent_id, &node.span); + ctx.write_node(id, AstNode::TSTypeQuery, parent_id, &node.span, 1); ctx.write_id(name_id); id @@ -2311,10 +2382,8 @@ fn serialize_ts_type( .map(|elem| todo!()) .collect::>(); - ctx.write_node(id, AstNode::TSTupleType, parent_id, &node.span); - - // FIXME - // ctx.write_ids(children); + ctx.write_node(id, AstNode::TSTupleType, parent_id, &node.span, 1); + ctx.write_ids(AstProp::ElementTypes, children); id } @@ -2330,10 +2399,8 @@ fn serialize_ts_type( .map(|item| serialize_ts_type(ctx, item, id)) .collect::>(); - ctx.write_node(id, AstNode::TSUnionType, parent_id, &node.span); - - // FIXME - // ctx.write_ids(children); + ctx.write_node(id, AstNode::TSUnionType, parent_id, &node.span, 1); + ctx.write_ids(AstProp::Types, children); id } @@ -2346,10 +2413,14 @@ fn serialize_ts_type( .map(|item| serialize_ts_type(ctx, item, id)) .collect::>(); - ctx.write_node(id, AstNode::TSIntersectionType, parent_id, &node.span); - - // FIXME - // ctx.write_ids(children); + ctx.write_node( + id, + AstNode::TSIntersectionType, + parent_id, + &node.span, + 1, + ); + ctx.write_ids(AstProp::Types, children); id } @@ -2361,7 +2432,7 @@ fn serialize_ts_type( let true_id = serialize_ts_type(ctx, &node.true_type, id); let false_id = serialize_ts_type(ctx, &node.false_type, id); - ctx.write_node(id, AstNode::TSConditionalType, parent_id, &node.span); + ctx.write_node(id, AstNode::TSConditionalType, parent_id, &node.span, 4); ctx.write_id(check_id); ctx.write_id(extends_id); ctx.write_id(true_id); @@ -2373,7 +2444,7 @@ fn serialize_ts_type( let id = ctx.next_id(); let param_id = serialize_ts_type_param(ctx, &node.type_param, parent_id); - ctx.write_node(id, AstNode::TSInferType, parent_id, &node.span); + ctx.write_node(id, AstNode::TSInferType, parent_id, &node.span, 1); ctx.write_id(param_id); id @@ -2407,7 +2478,7 @@ fn serialize_ts_type( // FIXME - ctx.write_node(id, AstNode::TSMappedType, parent_id, &node.span); + ctx.write_node(id, AstNode::TSMappedType, parent_id, &node.span, 4); ctx.write_flags(&optional_flags); ctx.write_flags(&readonly_flags); ctx.write_id(name_id); @@ -2433,7 +2504,7 @@ fn serialize_ts_type( id, ), }; - ctx.write_node(id, AstNode::TSLiteralType, parent_id, &node.span); + ctx.write_node(id, AstNode::TSLiteralType, parent_id, &node.span, 1); ctx.write_id(child_id); id @@ -2473,8 +2544,8 @@ fn serialize_ts_type_ann( let type_ann_id = serialize_ts_type(ctx, &node.type_ann, id); - ctx.write_node(id, AstNode::TSTypeAnnotation, parent_id, &node.span); - ctx.write_id(type_ann_id); + ctx.write_node(id, AstNode::TSTypeAnnotation, parent_id, &node.span, 1); + ctx.write_prop(AstProp::TypeAnnotation, type_ann_id); id } @@ -2504,7 +2575,7 @@ fn serialize_ts_type_param( let constraint_id = maybe_serialize_ts_type(ctx, &node.constraint, id); let default_id = maybe_serialize_ts_type(ctx, &node.default, id); - ctx.write_node(id, AstNode::TSTypeParameter, parent_id, &node.span); + ctx.write_node(id, AstNode::TSTypeParameter, parent_id, &node.span, 4); ctx.write_flags(&flags); ctx.write_id(name_id); ctx.write_id(constraint_id); @@ -2532,10 +2603,9 @@ fn maybe_serialize_ts_type_param( AstNode::TSTypeParameterDeclaration, parent_id, &node.span, + 1, ); - - // FIXME - // ctx.write_ids(children); + ctx.write_ids(AstProp::Params, children); id })