mirror of
https://github.com/denoland/deno.git
synced 2025-01-21 04:52:26 -05:00
wip
This commit is contained in:
parent
23ca8dff06
commit
963abe986a
5 changed files with 796 additions and 684 deletions
|
@ -10,252 +10,9 @@ const {
|
|||
} = core.ops;
|
||||
|
||||
// Keep in sync with Rust
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
const AstTypeName = [
|
||||
"Invalid",
|
||||
"Program",
|
||||
|
||||
"Import",
|
||||
"ImportDecl",
|
||||
"ExportDecl",
|
||||
"ExportNamed",
|
||||
"ExportDefaultDecl",
|
||||
"ExportDefaultExpr",
|
||||
"ExportAll",
|
||||
"TSImportEquals",
|
||||
"TSExportAssignment",
|
||||
"TSNamespaceExport",
|
||||
|
||||
// Decls
|
||||
"ClassDeclaration",
|
||||
"FunctionDeclaration",
|
||||
"VariableDeclaration",
|
||||
"Using",
|
||||
"TsInterface",
|
||||
"TsTypeAlias",
|
||||
"TsEnum",
|
||||
"TsModule",
|
||||
|
||||
// Statements
|
||||
"BlockStatement",
|
||||
"Empty",
|
||||
"DebuggerStatement",
|
||||
"WithStatement",
|
||||
"ReturnStatement",
|
||||
"LabeledStatement",
|
||||
"BreakStatement",
|
||||
"ContinueStatement",
|
||||
"IfStatement",
|
||||
"SwitchStatement",
|
||||
"SwitchCase",
|
||||
"ThrowStatement",
|
||||
"TryStatement",
|
||||
"WhileStatement",
|
||||
"DoWhileStatement",
|
||||
"ForStatement",
|
||||
"ForInStatement",
|
||||
"ForOfStatement",
|
||||
"Decl",
|
||||
"ExpressionStatement",
|
||||
|
||||
// Expressions
|
||||
"This",
|
||||
"ArrayExpression",
|
||||
"ObjectExpression",
|
||||
"FunctionExpression",
|
||||
"UnaryExpression",
|
||||
"UpdateExpression",
|
||||
"BinaryExpression",
|
||||
"AssignmentExpression",
|
||||
"MemberExpression",
|
||||
"Super",
|
||||
"ConditionalExpression",
|
||||
"CallExpression",
|
||||
"NewExpression",
|
||||
"ParenthesisExpression",
|
||||
"SequenceExpression",
|
||||
"Identifier",
|
||||
"TemplateLiteral",
|
||||
"TaggedTemplateExpression",
|
||||
"ArrowFunctionExpression",
|
||||
"ClassExpr",
|
||||
"YieldExpression",
|
||||
"MetaProperty",
|
||||
"AwaitExpression",
|
||||
"LogicalExpression",
|
||||
"TSTypeAssertion",
|
||||
"TSConstAssertion",
|
||||
"TSNonNull",
|
||||
"TSAs",
|
||||
"TSInstantiation",
|
||||
"TSSatisfies",
|
||||
"PrivateIdentifier",
|
||||
"ChainExpression",
|
||||
|
||||
"StringLiteral",
|
||||
"BooleanLiteral",
|
||||
"NullLiteral",
|
||||
"NumericLiteral",
|
||||
"BigIntLiteral",
|
||||
"RegExpLiteral",
|
||||
|
||||
// Custom
|
||||
"EmptyExpr",
|
||||
"SpreadElement",
|
||||
"Property",
|
||||
"VariableDeclarator",
|
||||
"CatchClause",
|
||||
"RestElement",
|
||||
"ExportSpecifier",
|
||||
"TemplateElement",
|
||||
"MethodDefinition",
|
||||
|
||||
// Patterns
|
||||
"ArrayPattern",
|
||||
"AssignmentPattern",
|
||||
"ObjectPattern",
|
||||
|
||||
// JSX
|
||||
"JSXAttribute",
|
||||
"JSXClosingElement",
|
||||
"JSXClosingFragment",
|
||||
"JSXElement",
|
||||
"JSXEmptyExpression",
|
||||
"JSXExpressionContainer",
|
||||
"JSXFragment",
|
||||
"JSXIdentifier",
|
||||
"JSXMemberExpression",
|
||||
"JSXNamespacedName",
|
||||
"JSXOpeningElement",
|
||||
"JSXOpeningFragment",
|
||||
"JSXSpreadAttribute",
|
||||
"JSXSpreadChild",
|
||||
"JSXText",
|
||||
];
|
||||
|
||||
/** @type {Map<string, number>} */
|
||||
const AstType = new Map();
|
||||
for (let i = 0; i < AstTypeName.length; i++) {
|
||||
AstType.set(AstTypeName[i], i);
|
||||
}
|
||||
|
||||
// Keep in sync with Rust
|
||||
const AstPropArr = [
|
||||
// Base
|
||||
"parent",
|
||||
"range",
|
||||
"type",
|
||||
"_InternalFlags",
|
||||
|
||||
// Node
|
||||
"abstract",
|
||||
"accessibility",
|
||||
"alternate",
|
||||
"argument",
|
||||
"arguments",
|
||||
"async",
|
||||
"attributes",
|
||||
"await",
|
||||
"block",
|
||||
"body",
|
||||
"callee",
|
||||
"cases",
|
||||
"children",
|
||||
"checkType",
|
||||
"closingElement",
|
||||
"closingFragment",
|
||||
"computed",
|
||||
"consequent",
|
||||
"const",
|
||||
"constraint",
|
||||
"cooked",
|
||||
"declarations",
|
||||
"declare",
|
||||
"default",
|
||||
"definite",
|
||||
"delegate",
|
||||
"discriminant",
|
||||
"elements",
|
||||
"elementTypes",
|
||||
"exprName",
|
||||
"expression",
|
||||
"expressions",
|
||||
"exported",
|
||||
"extendsType",
|
||||
"falseType",
|
||||
"finalizer",
|
||||
"flags",
|
||||
"generator",
|
||||
"handler",
|
||||
"id",
|
||||
"in",
|
||||
"init",
|
||||
"initializer",
|
||||
"implements",
|
||||
"key",
|
||||
"kind",
|
||||
"label",
|
||||
"left",
|
||||
"literal",
|
||||
"local",
|
||||
"members",
|
||||
"meta",
|
||||
"method",
|
||||
"name",
|
||||
"namespace",
|
||||
"nameType",
|
||||
"object",
|
||||
"openingElement",
|
||||
"openingFragment",
|
||||
"operator",
|
||||
"optional",
|
||||
"out",
|
||||
"param",
|
||||
"params",
|
||||
"pattern",
|
||||
"prefix",
|
||||
"properties",
|
||||
"property",
|
||||
"quasi",
|
||||
"quasis",
|
||||
"raw",
|
||||
"readonly",
|
||||
"returnType",
|
||||
"right",
|
||||
"selfClosing",
|
||||
"shorthand",
|
||||
"source",
|
||||
"sourceType",
|
||||
"specifiers",
|
||||
"superClass",
|
||||
"superTypeArguments",
|
||||
"tag",
|
||||
"tail",
|
||||
"test",
|
||||
"trueType",
|
||||
"typeAnnotation",
|
||||
"typeArguments",
|
||||
"typeName",
|
||||
"typeParameter",
|
||||
"typeParameters",
|
||||
"types",
|
||||
"update",
|
||||
"value",
|
||||
];
|
||||
|
||||
/** @type {Map<string, number>} */
|
||||
const AstProp = new Map();
|
||||
for (let i = 0; i < AstPropArr.length; i++) {
|
||||
AstProp.set(AstPropArr[i], i);
|
||||
}
|
||||
|
||||
const AST_PROP_TYPE = /** @type {number} */ (AstProp.get("type"));
|
||||
const AST_PROP_PARENT = /** @type {number} */ (AstProp.get("parent"));
|
||||
const AST_PROP_RANGE = /** @type {number} */ (AstProp.get("range"));
|
||||
|
||||
const AstPropName = Array.from(AstProp.keys());
|
||||
const AST_PROP_TYPE = 0;
|
||||
const AST_PROP_PARENT = 1;
|
||||
const AST_PROP_RANGE = 2;
|
||||
|
||||
// Keep in sync with Rust
|
||||
/** @enum {number} */
|
||||
|
@ -274,7 +31,10 @@ const PropFlags = {
|
|||
* strTable: Map<number, string>,
|
||||
* strTableOffset: number,
|
||||
* rootId: number,
|
||||
* nodes: Map<number, Node>
|
||||
* nodes: Map<number, Node>,
|
||||
* strByType: number[],
|
||||
* typeByStr: Map<string, number>,
|
||||
* strByProp: number[]
|
||||
* }} AstContext
|
||||
*/
|
||||
|
||||
|
@ -421,7 +181,7 @@ function readValue(ctx, offset, search) {
|
|||
const type = buf[offset];
|
||||
|
||||
if (search === AST_PROP_TYPE) {
|
||||
return AstTypeName[type];
|
||||
return getString(ctx, ctx.strByType[type]);
|
||||
} else if (search === AST_PROP_RANGE) {
|
||||
const start = readU32(buf, offset + 1 + 4);
|
||||
const end = readU32(buf, offset + 1 + 4 + 4);
|
||||
|
@ -484,7 +244,7 @@ function toJsValue(ctx, offset) {
|
|||
for (let i = 0; i < count; i++) {
|
||||
const prop = buf[offset++];
|
||||
const kind = buf[offset++];
|
||||
const name = AstPropName[prop];
|
||||
const name = getString(ctx, ctx.strByProp[prop]);
|
||||
|
||||
if (kind === PropFlags.Ref) {
|
||||
const v = readU32(buf, offset);
|
||||
|
@ -545,14 +305,29 @@ class Node {
|
|||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < AstPropName.length; i++) {
|
||||
const name = AstPropName[i];
|
||||
/** @type {Set<number>} */
|
||||
const appliedGetters = new Set();
|
||||
|
||||
/**
|
||||
* @param {AstContext} ctx
|
||||
*/
|
||||
function setNodeGetters(ctx) {
|
||||
if (appliedGetters.size === ctx.strByProp.length) return;
|
||||
|
||||
for (let i = 0; i < ctx.strByProp.length; i++) {
|
||||
const id = ctx.strByProp[i];
|
||||
if (id === 0 || appliedGetters.has(i)) continue;
|
||||
appliedGetters.add(i);
|
||||
|
||||
const name = getString(ctx, id);
|
||||
|
||||
Object.defineProperty(Node.prototype, name, {
|
||||
get() {
|
||||
return readValue(this[INTERNAL_CTX], this[INTERNAL_OFFSET], i);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const DECODER = new TextDecoder();
|
||||
|
||||
|
@ -590,6 +365,8 @@ function createAstContext(buf) {
|
|||
|
||||
// console.log(JSON.stringify(buf, null, 2));
|
||||
|
||||
const typeMapOffset = readU32(buf, buf.length - 16);
|
||||
const propMapOffset = readU32(buf, buf.length - 12);
|
||||
const strTableOffset = readU32(buf, buf.length - 8);
|
||||
const rootId = readU32(buf, buf.length - 4);
|
||||
// console.log({ strTableOffset, rootId });
|
||||
|
@ -618,10 +395,48 @@ function createAstContext(buf) {
|
|||
);
|
||||
}
|
||||
|
||||
/** @type {AstContext} */
|
||||
const ctx = { buf, strTable, rootId, nodes: new Map(), strTableOffset };
|
||||
offset = typeMapOffset;
|
||||
const typeCount = readU32(buf, offset);
|
||||
offset += 4;
|
||||
|
||||
// dump(ctx);
|
||||
const typeByStr = new Map();
|
||||
const strByType = new Array(typeCount).fill(0);
|
||||
for (let i = 0; i < typeCount; i++) {
|
||||
const v = readU32(buf, offset);
|
||||
offset += 4;
|
||||
|
||||
// console.log("type: ", i, v, strTable.get(v));
|
||||
strByType[i] = v;
|
||||
typeByStr.set(strTable.get(v), i);
|
||||
}
|
||||
|
||||
offset = propMapOffset;
|
||||
const propCount = readU32(buf, offset);
|
||||
offset += 4;
|
||||
|
||||
const strByProp = new Array(propCount).fill(0);
|
||||
for (let i = 0; i < propCount; i++) {
|
||||
const v = readU32(buf, offset);
|
||||
offset += 4;
|
||||
|
||||
strByProp[i] = v;
|
||||
}
|
||||
|
||||
/** @type {AstContext} */
|
||||
const ctx = {
|
||||
buf,
|
||||
strTable,
|
||||
rootId,
|
||||
nodes: new Map(),
|
||||
strTableOffset,
|
||||
strByProp,
|
||||
strByType,
|
||||
typeByStr,
|
||||
};
|
||||
|
||||
setNodeGetters(ctx);
|
||||
|
||||
// _dump(ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
@ -709,11 +524,11 @@ function traverse(ctx, visitor) {
|
|||
|
||||
// TODO: create visiting types
|
||||
for (const name in visitor) {
|
||||
const id = AstType.get(name);
|
||||
const id = ctx.typeByStr.get(name);
|
||||
if (id === undefined) continue;
|
||||
visitTypes.set(id, name);
|
||||
}
|
||||
|
||||
// console.log("buffer len", ctx.buf.length, ctx.buf.byteLength);
|
||||
console.log("merged visitor", visitor);
|
||||
console.log("visiting types", visitTypes);
|
||||
|
||||
|
@ -779,13 +594,31 @@ function traverseInner(ctx, visitTypes, visitor, offset) {
|
|||
* @param {AstContext} ctx
|
||||
*/
|
||||
function _dump(ctx) {
|
||||
const { buf, strTableOffset } = ctx;
|
||||
const { buf, strTableOffset, strTable, strByType, strByProp } = ctx;
|
||||
|
||||
// @ts-ignore dump fn
|
||||
console.log(strTable);
|
||||
|
||||
for (let i = 0; i < strByType.length; i++) {
|
||||
const v = strByType[i];
|
||||
// @ts-ignore dump fn
|
||||
if (v > 0) console.log(" > type:", i, getString(ctx, v), v);
|
||||
}
|
||||
// @ts-ignore dump fn
|
||||
console.log();
|
||||
for (let i = 0; i < strByProp.length; i++) {
|
||||
const v = strByProp[i];
|
||||
// @ts-ignore dump fn
|
||||
if (v > 0) console.log(" > prop:", i, getString(ctx, v), v);
|
||||
}
|
||||
// @ts-ignore dump fn
|
||||
console.log();
|
||||
|
||||
let offset = 0;
|
||||
|
||||
while (offset < strTableOffset) {
|
||||
const type = buf[offset];
|
||||
const name = AstTypeName[type];
|
||||
const name = getString(ctx, ctx.strByType[type]);
|
||||
// @ts-ignore dump fn
|
||||
console.log(`${name}, offset: ${offset}, type: ${type}`);
|
||||
offset += 1;
|
||||
|
@ -800,7 +633,7 @@ function _dump(ctx) {
|
|||
const end = readU32(buf, offset);
|
||||
offset += 4;
|
||||
// @ts-ignore dump fn
|
||||
console.log(` range: ${start} -> ${end}}`);
|
||||
console.log(` range: ${start} -> ${end}`);
|
||||
|
||||
const count = buf[offset++];
|
||||
// @ts-ignore dump fn
|
||||
|
@ -809,7 +642,7 @@ function _dump(ctx) {
|
|||
for (let i = 0; i < count; i++) {
|
||||
const prop = buf[offset++];
|
||||
const kind = buf[offset++];
|
||||
const name = AstPropName[prop];
|
||||
const name = getString(ctx, ctx.strByProp[prop]);
|
||||
|
||||
let kindName = "unknown";
|
||||
for (const k in PropFlags) {
|
||||
|
@ -823,35 +656,35 @@ function _dump(ctx) {
|
|||
const v = readU32(buf, offset);
|
||||
offset += 4;
|
||||
// @ts-ignore dump fn
|
||||
console.log(` ${name}: ${v} (${kindName})`);
|
||||
console.log(` ${name}: ${v} (${kindName}, ${prop})`);
|
||||
} else if (kind === PropFlags.RefArr) {
|
||||
const len = readU32(buf, offset);
|
||||
offset += 4;
|
||||
// @ts-ignore dump fn
|
||||
console.log(` ${name}: Array(${len}) (${kindName})`);
|
||||
console.log(` ${name}: Array(${len}) (${kindName}, ${prop})`);
|
||||
|
||||
for (let j = 0; j < len; j++) {
|
||||
const v = readU32(buf, offset);
|
||||
offset += 4;
|
||||
// @ts-ignore dump fn
|
||||
console.log(` - ${v}`);
|
||||
console.log(` - ${v} (${prop})`);
|
||||
}
|
||||
} else if (kind === PropFlags.Bool) {
|
||||
const v = buf[offset];
|
||||
offset += 1;
|
||||
// @ts-ignore dump fn
|
||||
console.log(` ${name}: ${v} (${kindName})`);
|
||||
console.log(` ${name}: ${v} (${kindName}, ${prop})`);
|
||||
} else if (kind === PropFlags.String) {
|
||||
const v = readU32(buf, offset);
|
||||
offset += 4;
|
||||
// @ts-ignore dump fn
|
||||
console.log(` ${name}: ${getString(ctx, v)} (${kindName})`);
|
||||
console.log(` ${name}: ${getString(ctx, v)} (${kindName}, ${prop})`);
|
||||
} else if (kind === PropFlags.Null) {
|
||||
// @ts-ignore dump fn
|
||||
console.log(` ${name}: null (${kindName})`);
|
||||
console.log(` ${name}: null (${kindName}, ${prop})`);
|
||||
} else if (kind === PropFlags.Undefined) {
|
||||
// @ts-ignore dump fn
|
||||
console.log(` ${name}: undefined (${kindName})`);
|
||||
console.log(` ${name}: undefined (${kindName}, ${prop})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,283 +1,8 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use deno_ast::swc::common::{Span, DUMMY_SP};
|
||||
use indexmap::IndexMap;
|
||||
|
||||
// Keep in sync with JS
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum AstNode {
|
||||
Invalid,
|
||||
//
|
||||
Program,
|
||||
|
||||
// Module declarations
|
||||
Import,
|
||||
ImportDecl,
|
||||
ExportDecl,
|
||||
ExportNamedDeclaration,
|
||||
ExportDefaultDecl,
|
||||
ExportDefaultExpr,
|
||||
ExportAll,
|
||||
TsImportEquals,
|
||||
TsExportAssignment,
|
||||
TsNamespaceExport,
|
||||
|
||||
// Decls
|
||||
ClassDeclaration,
|
||||
Fn,
|
||||
Var,
|
||||
Using,
|
||||
TSInterface,
|
||||
TsTypeAlias,
|
||||
TSEnumDeclaration,
|
||||
TsModule,
|
||||
|
||||
// Statements
|
||||
Block,
|
||||
Empty,
|
||||
Debugger,
|
||||
With,
|
||||
Return,
|
||||
Labeled,
|
||||
Break,
|
||||
Continue,
|
||||
IfStatement,
|
||||
Switch,
|
||||
SwitchCase,
|
||||
Throw,
|
||||
TryStatement,
|
||||
WhileStatement,
|
||||
DoWhileStatement,
|
||||
ForStatement,
|
||||
ForInStatement,
|
||||
ForOfStatement,
|
||||
Decl,
|
||||
ExpressionStatement,
|
||||
|
||||
// Expressions
|
||||
This,
|
||||
ArrayExpression,
|
||||
Object,
|
||||
FunctionExpression,
|
||||
UnaryExpression,
|
||||
UpdateExpression,
|
||||
BinaryExpression,
|
||||
Assign,
|
||||
MemberExpression,
|
||||
Super,
|
||||
ConditionalExpression,
|
||||
CallExpression,
|
||||
New,
|
||||
Paren,
|
||||
SequenceExpression,
|
||||
Identifier,
|
||||
TemplateLiteral,
|
||||
TaggedTemplateExpression,
|
||||
ArrowFunctionExpression,
|
||||
ClassExpr,
|
||||
YieldExpression,
|
||||
MetaProp,
|
||||
AwaitExpression,
|
||||
LogicalExpression,
|
||||
TSTypeAssertion,
|
||||
TsConstAssertion,
|
||||
TSNonNullExpression,
|
||||
TSAsExpression,
|
||||
TsInstantiation,
|
||||
TSSatisfiesExpression,
|
||||
PrivateIdentifier,
|
||||
ChainExpression,
|
||||
|
||||
// Literals
|
||||
StringLiteral,
|
||||
Bool,
|
||||
Null,
|
||||
NumericLiteral,
|
||||
BigIntLiteral,
|
||||
RegExpLiteral,
|
||||
|
||||
// Custom
|
||||
EmptyExpr,
|
||||
Spread,
|
||||
Property,
|
||||
VariableDeclarator,
|
||||
CatchClause,
|
||||
RestElement,
|
||||
ExportSpecifier,
|
||||
TemplateElement,
|
||||
MethodDefinition,
|
||||
|
||||
// Patterns
|
||||
ArrayPattern,
|
||||
AssignmentPattern,
|
||||
ObjectPattern,
|
||||
|
||||
// JSX
|
||||
JSXAttribute,
|
||||
JSXClosingElement,
|
||||
JSXClosingFragment,
|
||||
JSXElement,
|
||||
JSXEmptyExpression,
|
||||
JSXExpressionContainer,
|
||||
JSXFragment,
|
||||
JSXIdentifier,
|
||||
JSXMemberExpression,
|
||||
JSXNamespacedName,
|
||||
JSXOpeningElement,
|
||||
JSXOpeningFragment,
|
||||
JSXSpreadAttribute,
|
||||
JSXSpreadChild,
|
||||
JSXText,
|
||||
|
||||
TSTypeAnnotation,
|
||||
TSTypeParameterDeclaration,
|
||||
TSTypeParameter,
|
||||
TSEnumMember,
|
||||
TSInterfaceBody,
|
||||
TSInterfaceHeritage,
|
||||
TSTypeReference,
|
||||
TSThisType,
|
||||
TSLiteralType,
|
||||
TSInferType,
|
||||
TSConditionalType,
|
||||
TSUnionType,
|
||||
TSIntersectionType,
|
||||
TSMappedType,
|
||||
TSTypeQuery,
|
||||
TSTupleType,
|
||||
TSFunctionType,
|
||||
TsCallSignatureDeclaration,
|
||||
|
||||
TSAnyKeyword,
|
||||
TSBigIntKeyword,
|
||||
TSBooleanKeyword,
|
||||
TSIntrinsicKeyword,
|
||||
TSNeverKeyword,
|
||||
TSNullKeyword,
|
||||
TSNumberKeyword,
|
||||
TSObjectKeyword,
|
||||
TSStringKeyword,
|
||||
TSSymbolKeyword,
|
||||
TSUndefinedKeyword,
|
||||
TSUnknownKeyword,
|
||||
TSVoidKeyword,
|
||||
TSEnumBody,
|
||||
}
|
||||
|
||||
impl From<AstNode> for u8 {
|
||||
fn from(m: AstNode) -> u8 {
|
||||
m as u8
|
||||
}
|
||||
}
|
||||
|
||||
// Keep in sync with JS
|
||||
pub enum AstProp {
|
||||
// Base
|
||||
Parent,
|
||||
Range,
|
||||
Type,
|
||||
_InternalFlags, // Private
|
||||
|
||||
// Node
|
||||
Abstract,
|
||||
Accessibility,
|
||||
Alternate,
|
||||
Argument,
|
||||
Arguments,
|
||||
Async,
|
||||
Attributes,
|
||||
Await,
|
||||
Block,
|
||||
Body,
|
||||
Callee,
|
||||
Cases,
|
||||
Children,
|
||||
CheckType,
|
||||
ClosingElement,
|
||||
ClosingFragment,
|
||||
Computed,
|
||||
Consequent,
|
||||
Const,
|
||||
Constraint,
|
||||
Cooked,
|
||||
Declarations,
|
||||
Declare,
|
||||
Default,
|
||||
Definite,
|
||||
Delegate,
|
||||
Discriminant,
|
||||
Elements,
|
||||
ElementTypes,
|
||||
ExprName,
|
||||
Expression,
|
||||
Expressions,
|
||||
Exported,
|
||||
ExtendsType,
|
||||
FalseType,
|
||||
Finalizer,
|
||||
Flags,
|
||||
Generator,
|
||||
Handler,
|
||||
Id,
|
||||
In,
|
||||
Init,
|
||||
Initializer,
|
||||
Implements,
|
||||
Key,
|
||||
Kind,
|
||||
Label,
|
||||
Left,
|
||||
Literal,
|
||||
Local,
|
||||
Members,
|
||||
Meta,
|
||||
Method,
|
||||
Name,
|
||||
Namespace,
|
||||
NameType,
|
||||
Object,
|
||||
OpeningElement,
|
||||
OpeningFragment,
|
||||
Operator,
|
||||
Optional,
|
||||
Out,
|
||||
Param,
|
||||
Params,
|
||||
Pattern,
|
||||
Prefix,
|
||||
Properties,
|
||||
Property,
|
||||
Quasi,
|
||||
Quasis,
|
||||
Raw,
|
||||
Readonly,
|
||||
ReturnType,
|
||||
Right,
|
||||
SelfClosing,
|
||||
Shorthand,
|
||||
Source,
|
||||
SourceType,
|
||||
Specifiers,
|
||||
SuperClass,
|
||||
SuperTypeArguments,
|
||||
Tag,
|
||||
Tail,
|
||||
Test,
|
||||
TrueType,
|
||||
TypeAnnotation,
|
||||
TypeArguments,
|
||||
TypeName,
|
||||
TypeParameter,
|
||||
TypeParameters,
|
||||
Types,
|
||||
Update,
|
||||
Value,
|
||||
}
|
||||
|
||||
impl From<AstProp> for u8 {
|
||||
fn from(m: AstProp) -> u8 {
|
||||
m as u8
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum PropFlags {
|
||||
Ref,
|
||||
|
@ -346,26 +71,6 @@ pub fn write_usize(result: &mut [u8], value: usize, idx: usize) {
|
|||
result[idx + 3] = v4;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FlagValue(pub u8);
|
||||
|
||||
impl FlagValue {
|
||||
pub fn new() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
||||
pub fn set(&mut self, flag: impl Into<u8>) {
|
||||
let value: u8 = flag.into();
|
||||
self.0 |= value;
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FlagValue> for u8 {
|
||||
fn from(item: FlagValue) -> Self {
|
||||
item.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StringTable {
|
||||
id: usize,
|
||||
|
@ -411,42 +116,118 @@ impl StringTable {
|
|||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct NodeRef(pub usize);
|
||||
|
||||
pub trait AstBufSerializer<K, P>
|
||||
where
|
||||
K: Into<u8> + Display,
|
||||
P: Into<u8> + Display,
|
||||
{
|
||||
fn header(
|
||||
&mut self,
|
||||
kind: K,
|
||||
parent: NodeRef,
|
||||
span: &Span,
|
||||
prop_count: usize,
|
||||
) -> NodeRef;
|
||||
fn ref_field(&mut self, prop: P) -> usize;
|
||||
fn ref_vec_field(&mut self, prop: P, len: usize) -> usize;
|
||||
fn str_field(&mut self, prop: P) -> usize;
|
||||
fn bool_field(&mut self, prop: P) -> usize;
|
||||
fn undefined_field(&mut self, prop: P) -> usize;
|
||||
#[allow(dead_code)]
|
||||
fn null_field(&mut self, prop: P) -> usize;
|
||||
|
||||
fn write_ref(&mut self, pos: usize, value: NodeRef);
|
||||
fn write_maybe_ref(&mut self, pos: usize, value: Option<NodeRef>);
|
||||
fn write_refs(&mut self, pos: usize, value: Vec<NodeRef>);
|
||||
fn write_str(&mut self, pos: usize, value: &str);
|
||||
fn write_bool(&mut self, pos: usize, value: bool);
|
||||
|
||||
fn serialize(&mut self) -> Vec<u8>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SerializeCtx {
|
||||
pub buf: Vec<u8>,
|
||||
pub start_buf: NodeRef,
|
||||
pub str_table: StringTable,
|
||||
buf: Vec<u8>,
|
||||
start_buf: NodeRef,
|
||||
str_table: StringTable,
|
||||
kind_map: Vec<usize>,
|
||||
prop_map: Vec<usize>,
|
||||
}
|
||||
|
||||
impl SerializeCtx {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(kind_len: u8, prop_len: u8) -> Self {
|
||||
let kind_size = kind_len as usize;
|
||||
let prop_size = prop_len as usize;
|
||||
let mut ctx = Self {
|
||||
start_buf: NodeRef(0),
|
||||
buf: vec![],
|
||||
str_table: StringTable::new(),
|
||||
kind_map: vec![0; kind_size + 1],
|
||||
prop_map: vec![0; prop_size + 1],
|
||||
};
|
||||
|
||||
ctx.str_table.insert("");
|
||||
|
||||
// Placeholder node
|
||||
ctx.push_node(AstNode::Invalid, NodeRef(0), &DUMMY_SP);
|
||||
// Placeholder node is always 0
|
||||
ctx.append_node(0, NodeRef(0), &DUMMY_SP, 0);
|
||||
ctx.kind_map[0] = 0;
|
||||
ctx.start_buf = NodeRef(ctx.buf.len());
|
||||
|
||||
// Insert default props that are always present
|
||||
let type_str = ctx.str_table.insert("type");
|
||||
let parent_str = ctx.str_table.insert("parent");
|
||||
let range_str = ctx.str_table.insert("range");
|
||||
|
||||
ctx.prop_map[0] = type_str;
|
||||
ctx.prop_map[1] = parent_str;
|
||||
ctx.prop_map[2] = range_str;
|
||||
|
||||
ctx
|
||||
}
|
||||
|
||||
/// Begin writing a node
|
||||
pub fn header(
|
||||
fn field_header<P>(&mut self, prop: P, prop_flags: PropFlags) -> usize
|
||||
where
|
||||
P: Into<u8> + Display + Clone,
|
||||
{
|
||||
let offset = self.buf.len();
|
||||
|
||||
let n: u8 = prop.clone().into();
|
||||
self.buf.push(n);
|
||||
|
||||
if let Some(v) = self.prop_map.get::<usize>(n.into()) {
|
||||
if *v == 0 {
|
||||
let id = self.str_table.insert(&format!("{prop}"));
|
||||
self.prop_map[n as usize] = id;
|
||||
}
|
||||
}
|
||||
|
||||
let flags: u8 = prop_flags.into();
|
||||
self.buf.push(flags);
|
||||
|
||||
offset
|
||||
}
|
||||
|
||||
fn field<P>(&mut self, prop: P, prop_flags: PropFlags) -> usize
|
||||
where
|
||||
P: Into<u8> + Display + Clone,
|
||||
{
|
||||
let offset = self.field_header(prop, prop_flags);
|
||||
|
||||
append_usize(&mut self.buf, 0);
|
||||
|
||||
offset
|
||||
}
|
||||
|
||||
fn append_node(
|
||||
&mut self,
|
||||
kind: AstNode,
|
||||
kind: u8,
|
||||
parent: NodeRef,
|
||||
span: &Span,
|
||||
prop_count: usize,
|
||||
) -> NodeRef {
|
||||
let offset = self.buf.len();
|
||||
|
||||
let kind_value: u8 = kind.into();
|
||||
self.buf.push(kind_value);
|
||||
self.buf.push(kind);
|
||||
|
||||
append_usize(&mut self.buf, parent.0);
|
||||
|
||||
|
@ -460,11 +241,42 @@ impl SerializeCtx {
|
|||
NodeRef(offset)
|
||||
}
|
||||
|
||||
pub fn ref_field(&mut self, prop: AstProp) -> usize {
|
||||
/// Begin writing a node
|
||||
pub fn header<N>(
|
||||
&mut self,
|
||||
kind: N,
|
||||
parent: NodeRef,
|
||||
span: &Span,
|
||||
prop_count: usize,
|
||||
) -> NodeRef
|
||||
where
|
||||
N: Into<u8> + Display + Clone,
|
||||
{
|
||||
let n: u8 = kind.clone().into();
|
||||
|
||||
if let Some(v) = self.kind_map.get::<usize>(n.into()) {
|
||||
if *v == 0 {
|
||||
let id = self.str_table.insert(&format!("{kind}"));
|
||||
self.kind_map[n as usize] = id;
|
||||
}
|
||||
}
|
||||
|
||||
let offset = self.append_node(n, parent, span, prop_count);
|
||||
|
||||
offset
|
||||
}
|
||||
|
||||
pub fn ref_field<P>(&mut self, prop: P) -> usize
|
||||
where
|
||||
P: Into<u8> + Display + Clone,
|
||||
{
|
||||
self.field(prop, PropFlags::Ref)
|
||||
}
|
||||
|
||||
pub fn ref_vec_field(&mut self, prop: AstProp, len: usize) -> usize {
|
||||
pub fn ref_vec_field<P>(&mut self, prop: P, len: usize) -> usize
|
||||
where
|
||||
P: Into<u8> + Display + Clone,
|
||||
{
|
||||
let offset = self.field(prop, PropFlags::RefArr);
|
||||
|
||||
for _ in 0..len {
|
||||
|
@ -474,45 +286,37 @@ impl SerializeCtx {
|
|||
offset
|
||||
}
|
||||
|
||||
pub fn str_field(&mut self, prop: AstProp) -> usize {
|
||||
pub fn str_field<P>(&mut self, prop: P) -> usize
|
||||
where
|
||||
P: Into<u8> + Display + Clone,
|
||||
{
|
||||
self.field(prop, PropFlags::String)
|
||||
}
|
||||
|
||||
fn field_header(&mut self, prop: AstProp, prop_flags: PropFlags) -> usize {
|
||||
let offset = self.buf.len();
|
||||
|
||||
let kind: u8 = prop.into();
|
||||
self.buf.push(kind);
|
||||
|
||||
let flags: u8 = prop_flags.into();
|
||||
self.buf.push(flags);
|
||||
|
||||
offset
|
||||
}
|
||||
|
||||
pub fn bool_field(&mut self, prop: AstProp) -> usize {
|
||||
pub fn bool_field<P>(&mut self, prop: P) -> usize
|
||||
where
|
||||
P: Into<u8> + Display + Clone,
|
||||
{
|
||||
let offset = self.field_header(prop, PropFlags::Bool);
|
||||
self.buf.push(0);
|
||||
offset
|
||||
}
|
||||
|
||||
pub fn undefined_field(&mut self, prop: AstProp) -> usize {
|
||||
pub fn undefined_field<P>(&mut self, prop: P) -> usize
|
||||
where
|
||||
P: Into<u8> + Display + Clone,
|
||||
{
|
||||
self.field_header(prop, PropFlags::Undefined)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn null_field(&mut self, prop: AstProp) -> usize {
|
||||
pub fn null_field<P>(&mut self, prop: P) -> usize
|
||||
where
|
||||
P: Into<u8> + Display + Clone,
|
||||
{
|
||||
self.field_header(prop, PropFlags::Null)
|
||||
}
|
||||
|
||||
fn field(&mut self, prop: AstProp, prop_flags: PropFlags) -> usize {
|
||||
let offset = self.field_header(prop, prop_flags);
|
||||
|
||||
append_usize(&mut self.buf, 0);
|
||||
|
||||
offset
|
||||
}
|
||||
|
||||
pub fn write_ref(&mut self, field_offset: usize, value: NodeRef) {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
|
@ -586,15 +390,6 @@ impl SerializeCtx {
|
|||
self.buf[field_offset + 2] = if value { 1 } else { 0 };
|
||||
}
|
||||
|
||||
pub fn push_node(
|
||||
&mut self,
|
||||
kind: AstNode,
|
||||
parent: NodeRef,
|
||||
span: &Span,
|
||||
) -> NodeRef {
|
||||
self.header(kind, parent, span, 0)
|
||||
}
|
||||
|
||||
pub fn serialize(&mut self) -> Vec<u8> {
|
||||
let mut buf: Vec<u8> = vec![];
|
||||
|
||||
|
@ -607,6 +402,20 @@ impl SerializeCtx {
|
|||
// eprintln!("STRING {:#?}", self.str_table);
|
||||
buf.append(&mut self.str_table.serialize());
|
||||
|
||||
let offset_kind_map = buf.len();
|
||||
append_usize(&mut buf, self.kind_map.len());
|
||||
for v in &self.kind_map {
|
||||
append_usize(&mut buf, *v);
|
||||
}
|
||||
|
||||
let offset_prop_map = buf.len();
|
||||
append_usize(&mut buf, self.prop_map.len());
|
||||
for v in &self.prop_map {
|
||||
append_usize(&mut buf, *v);
|
||||
}
|
||||
|
||||
append_usize(&mut buf, offset_kind_map);
|
||||
append_usize(&mut buf, offset_prop_map);
|
||||
append_usize(&mut buf, offset_str_table);
|
||||
append_usize(&mut buf, self.start_buf.0);
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ mod plugins;
|
|||
mod reporters;
|
||||
mod rules;
|
||||
mod swc;
|
||||
mod ts_estree;
|
||||
|
||||
pub use linter::CliLinter;
|
||||
pub use linter::CliLinterOptions;
|
||||
|
|
|
@ -23,10 +23,13 @@ use deno_ast::{
|
|||
ParsedSource,
|
||||
};
|
||||
|
||||
use super::ast_buf::{append_usize, AstNode, AstProp, NodeRef, SerializeCtx};
|
||||
use super::{
|
||||
ast_buf::{AstBufSerializer, NodeRef},
|
||||
ts_estree::{AstNode, AstProp, TsEsTreeBuilder},
|
||||
};
|
||||
|
||||
pub fn serialize_ast_bin(parsed_source: &ParsedSource) -> Vec<u8> {
|
||||
let mut ctx = SerializeCtx::new();
|
||||
let mut ctx = TsEsTreeBuilder::new();
|
||||
|
||||
let program = &parsed_source.program();
|
||||
|
||||
|
@ -70,16 +73,16 @@ pub fn serialize_ast_bin(parsed_source: &ParsedSource) -> Vec<u8> {
|
|||
}
|
||||
|
||||
fn serialize_module_decl(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
module_decl: &ModuleDecl,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
match module_decl {
|
||||
ModuleDecl::Import(node) => {
|
||||
ctx.push_node(AstNode::Import, parent, &node.span)
|
||||
ctx.header(AstNode::Import, parent, &node.span, 0)
|
||||
}
|
||||
ModuleDecl::ExportDecl(node) => {
|
||||
ctx.push_node(AstNode::ExportDecl, parent, &node.span)
|
||||
ctx.header(AstNode::ExportDecl, parent, &node.span, 0)
|
||||
}
|
||||
ModuleDecl::ExportNamed(node) => {
|
||||
let id =
|
||||
|
@ -139,28 +142,28 @@ fn serialize_module_decl(
|
|||
id
|
||||
}
|
||||
ModuleDecl::ExportDefaultDecl(node) => {
|
||||
ctx.push_node(AstNode::ExportDefaultDecl, parent, &node.span)
|
||||
ctx.header(AstNode::ExportDefaultDecl, parent, &node.span, 0)
|
||||
}
|
||||
ModuleDecl::ExportDefaultExpr(node) => {
|
||||
ctx.push_node(AstNode::ExportDefaultExpr, parent, &node.span)
|
||||
ctx.header(AstNode::ExportDefaultExpr, parent, &node.span, 0)
|
||||
}
|
||||
ModuleDecl::ExportAll(node) => {
|
||||
ctx.push_node(AstNode::ExportAll, parent, &node.span)
|
||||
ctx.header(AstNode::ExportAll, parent, &node.span, 0)
|
||||
}
|
||||
ModuleDecl::TsImportEquals(node) => {
|
||||
ctx.push_node(AstNode::TsImportEquals, parent, &node.span)
|
||||
ctx.header(AstNode::TsImportEquals, parent, &node.span, 0)
|
||||
}
|
||||
ModuleDecl::TsExportAssignment(node) => {
|
||||
ctx.push_node(AstNode::TsExportAssignment, parent, &node.span)
|
||||
ctx.header(AstNode::TsExportAssignment, parent, &node.span, 0)
|
||||
}
|
||||
ModuleDecl::TsNamespaceExport(node) => {
|
||||
ctx.push_node(AstNode::TsNamespaceExport, parent, &node.span)
|
||||
ctx.header(AstNode::TsNamespaceExport, parent, &node.span, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_stmt(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
stmt: &Stmt,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -181,7 +184,7 @@ fn serialize_stmt(
|
|||
}
|
||||
Stmt::Empty(_) => NodeRef(0),
|
||||
Stmt::Debugger(node) => {
|
||||
ctx.push_node(AstNode::Debugger, parent, &node.span)
|
||||
ctx.header(AstNode::Debugger, parent, &node.span, 0)
|
||||
}
|
||||
Stmt::With(_) => todo!(),
|
||||
Stmt::Return(node) => {
|
||||
|
@ -438,12 +441,12 @@ fn serialize_stmt(
|
|||
}
|
||||
|
||||
fn serialize_expr(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
expr: &Expr,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
match expr {
|
||||
Expr::This(node) => ctx.push_node(AstNode::This, parent, &node.span),
|
||||
Expr::This(node) => ctx.header(AstNode::This, parent, &node.span, 0),
|
||||
Expr::Array(node) => {
|
||||
let pos = ctx.header(AstNode::ArrayExpression, parent, &node.span, 1);
|
||||
let elems_pos = ctx.ref_vec_field(AstProp::Elements, node.elems.len());
|
||||
|
@ -681,7 +684,7 @@ fn serialize_expr(
|
|||
let obj_pos = ctx.ref_field(AstProp::Object);
|
||||
let prop_pos = ctx.ref_field(AstProp::Property);
|
||||
|
||||
let obj = ctx.push_node(AstNode::Super, pos, &node.obj.span);
|
||||
let obj = ctx.header(AstNode::Super, pos, &node.obj.span, 0);
|
||||
|
||||
let mut computed = false;
|
||||
let prop = match &node.prop {
|
||||
|
@ -726,7 +729,7 @@ fn serialize_expr(
|
|||
|
||||
let callee = match &node.callee {
|
||||
Callee::Super(super_node) => {
|
||||
ctx.push_node(AstNode::Super, pos, &super_node.span)
|
||||
ctx.header(AstNode::Super, pos, &super_node.span, 0)
|
||||
}
|
||||
Callee::Import(import) => todo!(),
|
||||
Callee::Expr(expr) => serialize_expr(ctx, expr, pos),
|
||||
|
@ -891,7 +894,7 @@ fn serialize_expr(
|
|||
pos
|
||||
}
|
||||
Expr::Class(node) => {
|
||||
let id = ctx.push_node(AstNode::ClassExpr, parent, &node.class.span);
|
||||
let id = ctx.header(AstNode::ClassExpr, parent, &node.class.span, 0);
|
||||
|
||||
// FIXME
|
||||
|
||||
|
@ -913,7 +916,7 @@ fn serialize_expr(
|
|||
pos
|
||||
}
|
||||
Expr::MetaProp(node) => {
|
||||
ctx.push_node(AstNode::MetaProp, parent, &node.span)
|
||||
ctx.header(AstNode::MetaProp, parent, &node.span, 0)
|
||||
}
|
||||
Expr::Await(node) => {
|
||||
let pos = ctx.header(AstNode::AwaitExpression, parent, &node.span, 1);
|
||||
|
@ -1061,7 +1064,7 @@ fn serialize_expr(
|
|||
}
|
||||
|
||||
fn serialize_prop_or_spread(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
prop: &PropOrSpread,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1204,7 +1207,7 @@ fn serialize_prop_or_spread(
|
|||
}
|
||||
|
||||
fn serialize_member_expr(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &MemberExpr,
|
||||
parent: NodeRef,
|
||||
optional: bool,
|
||||
|
@ -1239,7 +1242,7 @@ fn serialize_member_expr(
|
|||
}
|
||||
|
||||
fn serialize_class_member(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
member: &ClassMember,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1334,7 +1337,7 @@ fn serialize_class_member(
|
|||
}
|
||||
|
||||
fn serialize_expr_or_spread(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
arg: &ExprOrSpread,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1346,7 +1349,7 @@ fn serialize_expr_or_spread(
|
|||
}
|
||||
|
||||
fn serialize_ident(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
ident: &Ident,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1358,7 +1361,7 @@ fn serialize_ident(
|
|||
}
|
||||
|
||||
fn serialize_module_exported_name(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
name: &ModuleExportName,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1371,7 +1374,7 @@ fn serialize_module_exported_name(
|
|||
}
|
||||
|
||||
fn serialize_decl(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
decl: &Decl,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1521,7 +1524,7 @@ fn serialize_decl(
|
|||
id
|
||||
}
|
||||
Decl::Using(node) => {
|
||||
let id = ctx.push_node(AstNode::Using, parent, &node.span);
|
||||
let id = ctx.header(AstNode::Using, parent, &node.span, 0);
|
||||
|
||||
for (i, decl) in node.decls.iter().enumerate() {
|
||||
// FIXME
|
||||
|
@ -1687,7 +1690,7 @@ fn serialize_decl(
|
|||
pos
|
||||
}
|
||||
Decl::TsModule(ts_module_decl) => {
|
||||
ctx.push_node(AstNode::TsModule, parent, &ts_module_decl.span)
|
||||
ctx.header(AstNode::TsModule, parent, &ts_module_decl.span, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1701,7 +1704,7 @@ fn accessibility_to_str(accessibility: Accessibility) -> String {
|
|||
}
|
||||
|
||||
fn serialize_private_name(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &PrivateName,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1714,7 +1717,7 @@ fn serialize_private_name(
|
|||
}
|
||||
|
||||
fn serialize_jsx_element(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &JSXElement,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1746,7 +1749,7 @@ fn serialize_jsx_element(
|
|||
}
|
||||
|
||||
fn serialize_jsx_fragment(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &JSXFragment,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1757,9 +1760,9 @@ fn serialize_jsx_fragment(
|
|||
let children_pos = ctx.ref_vec_field(AstProp::Children, node.children.len());
|
||||
|
||||
let opening_id =
|
||||
ctx.push_node(AstNode::JSXOpeningFragment, pos, &node.opening.span);
|
||||
ctx.header(AstNode::JSXOpeningFragment, pos, &node.opening.span, 0);
|
||||
let closing_id =
|
||||
ctx.push_node(AstNode::JSXClosingFragment, pos, &node.closing.span);
|
||||
ctx.header(AstNode::JSXClosingFragment, pos, &node.closing.span, 0);
|
||||
|
||||
let children = serialize_jsx_children(ctx, &node.children, pos);
|
||||
|
||||
|
@ -1771,7 +1774,7 @@ fn serialize_jsx_fragment(
|
|||
}
|
||||
|
||||
fn serialize_jsx_children(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
children: &[JSXElementChild],
|
||||
parent: NodeRef,
|
||||
) -> Vec<NodeRef> {
|
||||
|
@ -1806,7 +1809,7 @@ fn serialize_jsx_children(
|
|||
}
|
||||
|
||||
fn serialize_jsx_member_expr(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &JSXMemberExpr,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1830,7 +1833,7 @@ fn serialize_jsx_member_expr(
|
|||
}
|
||||
|
||||
fn serialize_jsx_element_name(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &JSXElementName,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1848,7 +1851,7 @@ fn serialize_jsx_element_name(
|
|||
}
|
||||
|
||||
fn serialize_jsx_opening_element(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &JSXOpeningElement,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1919,7 +1922,7 @@ fn serialize_jsx_opening_element(
|
|||
}
|
||||
|
||||
fn serialize_jsx_container_expr(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &JSXExprContainer,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1937,15 +1940,15 @@ fn serialize_jsx_container_expr(
|
|||
}
|
||||
|
||||
fn serialize_jsx_empty_expr(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &JSXEmptyExpr,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
ctx.push_node(AstNode::JSXEmptyExpression, parent, &node.span)
|
||||
ctx.header(AstNode::JSXEmptyExpression, parent, &node.span, 0)
|
||||
}
|
||||
|
||||
fn serialize_jsx_namespaced_name(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &JSXNamespacedName,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1963,7 +1966,7 @@ fn serialize_jsx_namespaced_name(
|
|||
}
|
||||
|
||||
fn serialize_ident_name_as_jsx_identifier(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &IdentName,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1976,7 +1979,7 @@ fn serialize_ident_name_as_jsx_identifier(
|
|||
}
|
||||
|
||||
fn serialize_jsx_identifier(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &Ident,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -1989,7 +1992,7 @@ fn serialize_jsx_identifier(
|
|||
}
|
||||
|
||||
fn serialize_pat(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
pat: &Pat,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -2116,7 +2119,7 @@ fn serialize_pat(
|
|||
}
|
||||
|
||||
fn serialize_for_head(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
for_head: &ForHead,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -2132,7 +2135,7 @@ fn serialize_for_head(
|
|||
}
|
||||
|
||||
fn serialize_spread(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
expr: &Expr,
|
||||
span: &Span,
|
||||
parent: NodeRef,
|
||||
|
@ -2147,7 +2150,7 @@ fn serialize_spread(
|
|||
}
|
||||
|
||||
fn serialize_ident_name(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
ident_name: &IdentName,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -2159,7 +2162,7 @@ fn serialize_ident_name(
|
|||
}
|
||||
|
||||
fn serialize_prop_name(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
prop_name: &PropName,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -2168,13 +2171,12 @@ fn serialize_prop_name(
|
|||
serialize_ident_name(ctx, ident_name, parent)
|
||||
}
|
||||
PropName::Str(str_prop) => {
|
||||
let child_id =
|
||||
ctx.push_node(AstNode::StringLiteral, parent, &str_prop.span);
|
||||
let child_pos =
|
||||
ctx.header(AstNode::StringLiteral, parent, &str_prop.span, 1);
|
||||
let value_pos = ctx.str_field(AstProp::Value);
|
||||
ctx.write_str(value_pos, &str_prop.value);
|
||||
|
||||
let str_id = ctx.str_table.insert(str_prop.value.as_str());
|
||||
append_usize(&mut ctx.buf, str_id);
|
||||
|
||||
child_id
|
||||
child_pos
|
||||
}
|
||||
PropName::Num(number) => {
|
||||
serialize_lit(ctx, &Lit::Num(number.clone()), parent)
|
||||
|
@ -2187,7 +2189,7 @@ fn serialize_prop_name(
|
|||
}
|
||||
|
||||
fn serialize_lit(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
lit: &Lit,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -2208,7 +2210,7 @@ fn serialize_lit(
|
|||
|
||||
pos
|
||||
}
|
||||
Lit::Null(node) => ctx.push_node(AstNode::Null, parent, &node.span),
|
||||
Lit::Null(node) => ctx.header(AstNode::Null, parent, &node.span, 0),
|
||||
Lit::Num(node) => {
|
||||
let pos = ctx.header(AstNode::NumericLiteral, parent, &node.span, 1);
|
||||
let value_pos = ctx.str_field(AstProp::Value);
|
||||
|
@ -2237,13 +2239,13 @@ fn serialize_lit(
|
|||
pos
|
||||
}
|
||||
Lit::JSXText(jsxtext) => {
|
||||
ctx.push_node(AstNode::JSXText, parent, &jsxtext.span)
|
||||
ctx.header(AstNode::JSXText, parent, &jsxtext.span, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_ts_type(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &TsType,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -2265,10 +2267,10 @@ fn serialize_ts_type(
|
|||
TsKeywordTypeKind::TsIntrinsicKeyword => AstNode::TSIntrinsicKeyword,
|
||||
};
|
||||
|
||||
ctx.push_node(kind, parent, &node.span)
|
||||
ctx.header(kind, parent, &node.span, 0)
|
||||
}
|
||||
TsType::TsThisType(node) => {
|
||||
ctx.push_node(AstNode::TSThisType, parent, &node.span)
|
||||
ctx.header(AstNode::TSThisType, parent, &node.span, 0)
|
||||
}
|
||||
TsType::TsFnOrConstructorType(node) => match node {
|
||||
TsFnOrConstructorType::TsFnType(node) => {
|
||||
|
@ -2455,7 +2457,7 @@ fn serialize_ts_type(
|
|||
}
|
||||
|
||||
fn create_true_plus_minus_field(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
prop: AstProp,
|
||||
value: Option<TruePlusMinus>,
|
||||
) -> usize {
|
||||
|
@ -2470,7 +2472,7 @@ fn create_true_plus_minus_field(
|
|||
}
|
||||
|
||||
fn write_true_plus_minus(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
pos: usize,
|
||||
value: Option<TruePlusMinus>,
|
||||
) {
|
||||
|
@ -2486,7 +2488,7 @@ fn write_true_plus_minus(
|
|||
}
|
||||
|
||||
fn serialize_ts_entity_name(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &TsEntityName,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -2497,7 +2499,7 @@ fn serialize_ts_entity_name(
|
|||
}
|
||||
|
||||
fn maybe_serialize_ts_type_ann(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &Option<Box<TsTypeAnn>>,
|
||||
parent: NodeRef,
|
||||
) -> Option<NodeRef> {
|
||||
|
@ -2507,7 +2509,7 @@ fn maybe_serialize_ts_type_ann(
|
|||
}
|
||||
|
||||
fn serialize_ts_type_ann(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &TsTypeAnn,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -2522,7 +2524,7 @@ fn serialize_ts_type_ann(
|
|||
}
|
||||
|
||||
fn maybe_serialize_ts_type(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &Option<Box<TsType>>,
|
||||
parent: NodeRef,
|
||||
) -> Option<NodeRef> {
|
||||
|
@ -2532,7 +2534,7 @@ fn maybe_serialize_ts_type(
|
|||
}
|
||||
|
||||
fn serialize_ts_type_param(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &TsTypeParam,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
@ -2559,7 +2561,7 @@ fn serialize_ts_type_param(
|
|||
}
|
||||
|
||||
fn maybe_serialize_ts_type_param(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &Option<Box<TsTypeParamDecl>>,
|
||||
parent: NodeRef,
|
||||
) -> Option<NodeRef> {
|
||||
|
@ -2581,7 +2583,7 @@ fn maybe_serialize_ts_type_param(
|
|||
}
|
||||
|
||||
fn serialize_ts_fn_param(
|
||||
ctx: &mut SerializeCtx,
|
||||
ctx: &mut TsEsTreeBuilder,
|
||||
node: &TsFnParam,
|
||||
parent: NodeRef,
|
||||
) -> NodeRef {
|
||||
|
|
467
cli/tools/lint/ts_estree.rs
Normal file
467
cli/tools/lint/ts_estree.rs
Normal file
|
@ -0,0 +1,467 @@
|
|||
use std::fmt::{self, Debug, Display};
|
||||
|
||||
use deno_ast::swc::common::Span;
|
||||
|
||||
use super::ast_buf::{AstBufSerializer, NodeRef, SerializeCtx};
|
||||
|
||||
// Keep in sync with JS
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum AstNode {
|
||||
Invalid,
|
||||
//
|
||||
Program,
|
||||
|
||||
// Module declarations
|
||||
Import,
|
||||
ImportDecl,
|
||||
ExportDecl,
|
||||
ExportNamedDeclaration,
|
||||
ExportDefaultDecl,
|
||||
ExportDefaultExpr,
|
||||
ExportAll,
|
||||
TsImportEquals,
|
||||
TsExportAssignment,
|
||||
TsNamespaceExport,
|
||||
|
||||
// Decls
|
||||
ClassDeclaration,
|
||||
Fn,
|
||||
Var,
|
||||
Using,
|
||||
TSInterface,
|
||||
TsTypeAlias,
|
||||
TSEnumDeclaration,
|
||||
TsModule,
|
||||
|
||||
// Statements
|
||||
Block,
|
||||
Empty,
|
||||
Debugger,
|
||||
With,
|
||||
Return,
|
||||
Labeled,
|
||||
Break,
|
||||
Continue,
|
||||
IfStatement,
|
||||
Switch,
|
||||
SwitchCase,
|
||||
Throw,
|
||||
TryStatement,
|
||||
WhileStatement,
|
||||
DoWhileStatement,
|
||||
ForStatement,
|
||||
ForInStatement,
|
||||
ForOfStatement,
|
||||
Decl,
|
||||
ExpressionStatement,
|
||||
|
||||
// Expressions
|
||||
This,
|
||||
ArrayExpression,
|
||||
Object,
|
||||
FunctionExpression,
|
||||
UnaryExpression,
|
||||
UpdateExpression,
|
||||
BinaryExpression,
|
||||
Assign,
|
||||
MemberExpression,
|
||||
Super,
|
||||
ConditionalExpression,
|
||||
CallExpression,
|
||||
New,
|
||||
Paren,
|
||||
SequenceExpression,
|
||||
Identifier,
|
||||
TemplateLiteral,
|
||||
TaggedTemplateExpression,
|
||||
ArrowFunctionExpression,
|
||||
ClassExpr,
|
||||
YieldExpression,
|
||||
MetaProp,
|
||||
AwaitExpression,
|
||||
LogicalExpression,
|
||||
TSTypeAssertion,
|
||||
TsConstAssertion,
|
||||
TSNonNullExpression,
|
||||
TSAsExpression,
|
||||
TsInstantiation,
|
||||
TSSatisfiesExpression,
|
||||
PrivateIdentifier,
|
||||
ChainExpression,
|
||||
|
||||
// Literals
|
||||
StringLiteral,
|
||||
Bool,
|
||||
Null,
|
||||
NumericLiteral,
|
||||
BigIntLiteral,
|
||||
RegExpLiteral,
|
||||
|
||||
// Custom
|
||||
EmptyExpr,
|
||||
Spread,
|
||||
Property,
|
||||
VariableDeclarator,
|
||||
CatchClause,
|
||||
RestElement,
|
||||
ExportSpecifier,
|
||||
TemplateElement,
|
||||
MethodDefinition,
|
||||
|
||||
// Patterns
|
||||
ArrayPattern,
|
||||
AssignmentPattern,
|
||||
ObjectPattern,
|
||||
|
||||
// JSX
|
||||
JSXAttribute,
|
||||
JSXClosingElement,
|
||||
JSXClosingFragment,
|
||||
JSXElement,
|
||||
JSXEmptyExpression,
|
||||
JSXExpressionContainer,
|
||||
JSXFragment,
|
||||
JSXIdentifier,
|
||||
JSXMemberExpression,
|
||||
JSXNamespacedName,
|
||||
JSXOpeningElement,
|
||||
JSXOpeningFragment,
|
||||
JSXSpreadAttribute,
|
||||
JSXSpreadChild,
|
||||
JSXText,
|
||||
|
||||
TSTypeAnnotation,
|
||||
TSTypeParameterDeclaration,
|
||||
TSTypeParameter,
|
||||
TSEnumMember,
|
||||
TSInterfaceBody,
|
||||
TSInterfaceHeritage,
|
||||
TSTypeReference,
|
||||
TSThisType,
|
||||
TSLiteralType,
|
||||
TSInferType,
|
||||
TSConditionalType,
|
||||
TSUnionType,
|
||||
TSIntersectionType,
|
||||
TSMappedType,
|
||||
TSTypeQuery,
|
||||
TSTupleType,
|
||||
TSFunctionType,
|
||||
TsCallSignatureDeclaration,
|
||||
|
||||
TSAnyKeyword,
|
||||
TSBigIntKeyword,
|
||||
TSBooleanKeyword,
|
||||
TSIntrinsicKeyword,
|
||||
TSNeverKeyword,
|
||||
TSNullKeyword,
|
||||
TSNumberKeyword,
|
||||
TSObjectKeyword,
|
||||
TSStringKeyword,
|
||||
TSSymbolKeyword,
|
||||
TSUndefinedKeyword,
|
||||
TSUnknownKeyword,
|
||||
TSVoidKeyword,
|
||||
TSEnumBody, // Last value is used for max value
|
||||
}
|
||||
|
||||
impl Display for AstNode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstNode> for u8 {
|
||||
fn from(m: AstNode) -> u8 {
|
||||
m as u8
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AstProp {
|
||||
// Base, these three must be in sync with JS
|
||||
Type,
|
||||
Parent,
|
||||
Range,
|
||||
|
||||
// Node
|
||||
Abstract,
|
||||
Accessibility,
|
||||
Alternate,
|
||||
Argument,
|
||||
Arguments,
|
||||
Async,
|
||||
Attributes,
|
||||
Await,
|
||||
Block,
|
||||
Body,
|
||||
Callee,
|
||||
Cases,
|
||||
Children,
|
||||
CheckType,
|
||||
ClosingElement,
|
||||
ClosingFragment,
|
||||
Computed,
|
||||
Consequent,
|
||||
Const,
|
||||
Constraint,
|
||||
Cooked,
|
||||
Declarations,
|
||||
Declare,
|
||||
Default,
|
||||
Definite,
|
||||
Delegate,
|
||||
Discriminant,
|
||||
Elements,
|
||||
ElementTypes,
|
||||
ExprName,
|
||||
Expression,
|
||||
Expressions,
|
||||
Exported,
|
||||
ExtendsType,
|
||||
FalseType,
|
||||
Finalizer,
|
||||
Flags,
|
||||
Generator,
|
||||
Handler,
|
||||
Id,
|
||||
In,
|
||||
Init,
|
||||
Initializer,
|
||||
Implements,
|
||||
Key,
|
||||
Kind,
|
||||
Label,
|
||||
Left,
|
||||
Literal,
|
||||
Local,
|
||||
Members,
|
||||
Meta,
|
||||
Method,
|
||||
Name,
|
||||
Namespace,
|
||||
NameType,
|
||||
Object,
|
||||
OpeningElement,
|
||||
OpeningFragment,
|
||||
Operator,
|
||||
Optional,
|
||||
Out,
|
||||
Param,
|
||||
Params,
|
||||
Pattern,
|
||||
Prefix,
|
||||
Properties,
|
||||
Property,
|
||||
Quasi,
|
||||
Quasis,
|
||||
Raw,
|
||||
Readonly,
|
||||
ReturnType,
|
||||
Right,
|
||||
SelfClosing,
|
||||
Shorthand,
|
||||
Source,
|
||||
SourceType,
|
||||
Specifiers,
|
||||
SuperClass,
|
||||
SuperTypeArguments,
|
||||
Tag,
|
||||
Tail,
|
||||
Test,
|
||||
TrueType,
|
||||
TypeAnnotation,
|
||||
TypeArguments,
|
||||
TypeName,
|
||||
TypeParameter,
|
||||
TypeParameters,
|
||||
Types,
|
||||
Update,
|
||||
Value, // Last value is used for max value
|
||||
}
|
||||
|
||||
impl Display for AstProp {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let s = match self {
|
||||
AstProp::Parent => "parent",
|
||||
AstProp::Range => "range",
|
||||
AstProp::Type => "type",
|
||||
AstProp::Abstract => "abstract",
|
||||
AstProp::Accessibility => "accessibility",
|
||||
AstProp::Alternate => "alternate",
|
||||
AstProp::Argument => "argument",
|
||||
AstProp::Arguments => "arguments",
|
||||
AstProp::Async => "async",
|
||||
AstProp::Attributes => "attributes",
|
||||
AstProp::Await => "await",
|
||||
AstProp::Block => "block",
|
||||
AstProp::Body => "body",
|
||||
AstProp::Callee => "callee",
|
||||
AstProp::Cases => "cases",
|
||||
AstProp::Children => "children",
|
||||
AstProp::CheckType => "checkType",
|
||||
AstProp::ClosingElement => "closingElement",
|
||||
AstProp::ClosingFragment => "closingFragment",
|
||||
AstProp::Computed => "computed",
|
||||
AstProp::Consequent => "consequent",
|
||||
AstProp::Const => "const",
|
||||
AstProp::Constraint => "constraint",
|
||||
AstProp::Cooked => "cooked",
|
||||
AstProp::Declarations => "declarations",
|
||||
AstProp::Declare => "declare",
|
||||
AstProp::Default => "default",
|
||||
AstProp::Definite => "definite",
|
||||
AstProp::Delegate => "delegate",
|
||||
AstProp::Discriminant => "discriminant",
|
||||
AstProp::Elements => "elements",
|
||||
AstProp::ElementTypes => "elementTypes",
|
||||
AstProp::ExprName => "exprName",
|
||||
AstProp::Expression => "expression",
|
||||
AstProp::Expressions => "expressions",
|
||||
AstProp::Exported => "exported",
|
||||
AstProp::ExtendsType => "extendsType",
|
||||
AstProp::FalseType => "falseType",
|
||||
AstProp::Finalizer => "finalizer",
|
||||
AstProp::Flags => "flags",
|
||||
AstProp::Generator => "generator",
|
||||
AstProp::Handler => "handler",
|
||||
AstProp::Id => "id",
|
||||
AstProp::In => "in",
|
||||
AstProp::Init => "init",
|
||||
AstProp::Initializer => "initializer",
|
||||
AstProp::Implements => "implements",
|
||||
AstProp::Key => "key",
|
||||
AstProp::Kind => "kind",
|
||||
AstProp::Label => "label",
|
||||
AstProp::Left => "left",
|
||||
AstProp::Literal => "literal",
|
||||
AstProp::Local => "local",
|
||||
AstProp::Members => "members",
|
||||
AstProp::Meta => "meta",
|
||||
AstProp::Method => "method",
|
||||
AstProp::Name => "name",
|
||||
AstProp::Namespace => "namespace",
|
||||
AstProp::NameType => "nameType",
|
||||
AstProp::Object => "object",
|
||||
AstProp::OpeningElement => "openingElement",
|
||||
AstProp::OpeningFragment => "openingFragment",
|
||||
AstProp::Operator => "operator",
|
||||
AstProp::Optional => "optional",
|
||||
AstProp::Out => "out",
|
||||
AstProp::Param => "param",
|
||||
AstProp::Params => "params",
|
||||
AstProp::Pattern => "pattern",
|
||||
AstProp::Prefix => "prefix",
|
||||
AstProp::Properties => "properties",
|
||||
AstProp::Property => "property",
|
||||
AstProp::Quasi => "quasi",
|
||||
AstProp::Quasis => "quasis",
|
||||
AstProp::Raw => "raw",
|
||||
AstProp::Readonly => "readonly",
|
||||
AstProp::ReturnType => "returnType",
|
||||
AstProp::Right => "right",
|
||||
AstProp::SelfClosing => "selfClosing",
|
||||
AstProp::Shorthand => "shorthand",
|
||||
AstProp::Source => "source",
|
||||
AstProp::SourceType => "sourceType",
|
||||
AstProp::Specifiers => "specifiers",
|
||||
AstProp::SuperClass => "superClass",
|
||||
AstProp::SuperTypeArguments => "superTypeArguments",
|
||||
AstProp::Tag => "tag",
|
||||
AstProp::Tail => "tail",
|
||||
AstProp::Test => "test",
|
||||
AstProp::TrueType => "trueType",
|
||||
AstProp::TypeAnnotation => "typeAnnotation",
|
||||
AstProp::TypeArguments => "typeArguments",
|
||||
AstProp::TypeName => "typeName",
|
||||
AstProp::TypeParameter => "typeParameter",
|
||||
AstProp::TypeParameters => "typeParameters",
|
||||
AstProp::Types => "types",
|
||||
AstProp::Update => "update",
|
||||
AstProp::Value => "value",
|
||||
};
|
||||
|
||||
write!(f, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AstProp> for u8 {
|
||||
fn from(m: AstProp) -> u8 {
|
||||
m as u8
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TsEsTreeBuilder {
|
||||
ctx: SerializeCtx,
|
||||
}
|
||||
|
||||
impl TsEsTreeBuilder {
|
||||
pub fn new() -> Self {
|
||||
// Max values
|
||||
let kind_count: u8 = AstNode::TSEnumBody.into();
|
||||
let prop_count: u8 = AstProp::Value.into();
|
||||
Self {
|
||||
ctx: SerializeCtx::new(kind_count, prop_count),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AstBufSerializer<AstNode, AstProp> for TsEsTreeBuilder {
|
||||
fn header(
|
||||
&mut self,
|
||||
kind: AstNode,
|
||||
parent: NodeRef,
|
||||
span: &Span,
|
||||
prop_count: usize,
|
||||
) -> NodeRef {
|
||||
self.ctx.header(kind, parent, span, prop_count)
|
||||
}
|
||||
|
||||
fn ref_field(&mut self, prop: AstProp) -> usize {
|
||||
self.ctx.ref_field(prop)
|
||||
}
|
||||
|
||||
fn ref_vec_field(&mut self, prop: AstProp, len: usize) -> usize {
|
||||
self.ctx.ref_vec_field(prop, len)
|
||||
}
|
||||
|
||||
fn str_field(&mut self, prop: AstProp) -> usize {
|
||||
self.ctx.str_field(prop)
|
||||
}
|
||||
|
||||
fn bool_field(&mut self, prop: AstProp) -> usize {
|
||||
self.ctx.bool_field(prop)
|
||||
}
|
||||
|
||||
fn undefined_field(&mut self, prop: AstProp) -> usize {
|
||||
self.ctx.undefined_field(prop)
|
||||
}
|
||||
|
||||
fn null_field(&mut self, prop: AstProp) -> usize {
|
||||
self.ctx.null_field(prop)
|
||||
}
|
||||
|
||||
fn write_ref(&mut self, pos: usize, value: NodeRef) {
|
||||
self.ctx.write_ref(pos, value);
|
||||
}
|
||||
|
||||
fn write_maybe_ref(&mut self, pos: usize, value: Option<NodeRef>) {
|
||||
self.ctx.write_maybe_ref(pos, value);
|
||||
}
|
||||
|
||||
fn write_refs(&mut self, pos: usize, value: Vec<NodeRef>) {
|
||||
self.ctx.write_refs(pos, value);
|
||||
}
|
||||
|
||||
fn write_str(&mut self, pos: usize, value: &str) {
|
||||
self.ctx.write_str(pos, value);
|
||||
}
|
||||
|
||||
fn write_bool(&mut self, pos: usize, value: bool) {
|
||||
self.ctx.write_bool(pos, value);
|
||||
}
|
||||
|
||||
fn serialize(&mut self) -> Vec<u8> {
|
||||
self.ctx.serialize()
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue