1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-21 04:52:26 -05:00

more nodes

This commit is contained in:
Marvin Hagemeister 2024-12-12 01:35:57 +01:00
parent 17ad68bb53
commit a3421b9c0a
5 changed files with 643 additions and 67 deletions

View file

@ -149,6 +149,15 @@ const Flags = {
UpdateMinusMinus: 0b000000100,
YieldDelegate: 1,
ParamOptional: 1,
ClassDeclare: 0b000000001,
ClassAbstract: 0b000000010,
ClassConstructor: 0b000000100,
ClassMethod: 0b000001000,
ClassPublic: 0b001000000,
ClassProtected: 0b010000000,
ClassPrivate: 0b100000000,
};
// Keep in sync with Rust
@ -171,7 +180,7 @@ const AstType = {
TSNamespaceExport: 11,
// Decls
Class: 12,
ClassDeclaration: 12,
FunctionDeclaration: 13,
VariableDeclaration: 14,
Using: 15,
@ -252,28 +261,29 @@ const AstType = {
RestElement: 83,
ExportSpecifier: 84,
TemplateElement: 85,
MethodDefinition: 86,
// Patterns
ArrayPattern: 86,
AssignmentPattern: 87,
ObjectPattern: 88,
ArrayPattern: 87,
AssignmentPattern: 88,
ObjectPattern: 89,
// JSX
JSXAttribute: 89,
JSXClosingElement: 90,
JSXClosingFragment: 91,
JSXElement: 92,
JSXEmptyExpression: 93,
JSXExpressionContainer: 94,
JSXFragment: 95,
JSXIdentifier: 96,
JSXMemberExpression: 97,
JSXNamespacedName: 98,
JSXOpeningElement: 99,
JSXOpeningFragment: 100,
JSXSpreadAttribute: 101,
JSXSpreadChild: 102,
JSXText: 103,
JSXAttribute: 90,
JSXClosingElement: 91,
JSXClosingFragment: 92,
JSXElement: 93,
JSXEmptyExpression: 94,
JSXExpressionContainer: 95,
JSXFragment: 96,
JSXIdentifier: 97,
JSXMemberExpression: 98,
JSXNamespacedName: 99,
JSXOpeningElement: 100,
JSXOpeningFragment: 101,
JSXSpreadAttribute: 102,
JSXSpreadChild: 103,
JSXText: 104,
};
const AstNodeById = Object.keys(AstType);
@ -936,23 +946,61 @@ class SwitchStatement extends BaseNode {
));
}
get cases() {
return []; // FIXME
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) {
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 BaseNode {
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;
}
}
@ -1562,19 +1610,75 @@ class ConditionalExpression extends BaseNode {
}
/** @implements {Deno.FunctionExpression} */
class FunctionExpression {
class FunctionExpression extends BaseNode {
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, range) {
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;
}
}
@ -1882,6 +1986,39 @@ class Property extends BaseNode {
}
}
/** @implements {Deno.RestElement} */
class RestElement extends BaseNode {
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 BaseNode {
type = /** @type {const} */ ("SequenceExpression");
@ -2216,6 +2353,120 @@ class TemplateElement extends BaseNode {
}
}
// Patterns
/** @implements {Deno.AssignmentPattern} */
class AssignmentPattern extends BaseNode {
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 BaseNode {
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 BaseNode {
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} */
@ -2853,8 +3104,16 @@ function createAstNode(ctx, id) {
const argId = readU32(buf, offset);
return new ReturnStatement(ctx, parentId, range, argId);
}
case AstType.SwitchStatement:
throw new SwitchStatement(ctx, parentId, range, 0); // FIXME
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);
@ -2958,8 +3217,25 @@ function createAstNode(ctx, id) {
altId,
);
}
case AstType.FunctionExpression:
throw new FunctionExpression(ctx, range); // FIXME
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);
@ -3011,6 +3287,11 @@ function createAstNode(ctx, id) {
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);
@ -3079,6 +3360,28 @@ function createAstNode(ctx, id) {
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);
@ -3331,7 +3634,7 @@ function traverse(ctx, visitor) {
* @param {number} id
*/
function traverseInner(ctx, visitTypes, visitor, id) {
console.log("traversing id", id);
// console.log("traversing id", id);
// Empty id
if (id === 0) return;
@ -3344,7 +3647,7 @@ function traverseInner(ctx, visitTypes, visitor, id) {
if (offset === undefined) throw new Error(`Unknown id: ${id}`);
const type = buf[offset];
console.log({ id, type, offset });
// console.log({ id, type, offset });
const name = visitTypes.get(type);
if (name !== undefined) {
@ -3403,13 +3706,31 @@ function traverseInner(ctx, visitTypes, visitor, id) {
return;
}
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);
return traverseChildren(ctx, visitTypes, visitor, stmtsIds);
traverseChildren(ctx, visitTypes, visitor, stmtsIds);
return;
}
// Expressions
@ -3557,6 +3878,38 @@ function traverseInner(ctx, visitTypes, visitor, id) {
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:
@ -3574,9 +3927,11 @@ function traverseInner(ctx, visitTypes, visitor, id) {
// 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);
@ -3598,6 +3953,7 @@ function traverseInner(ctx, visitTypes, visitor, id) {
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);

View file

@ -1,18 +1,19 @@
use deno_ast::{
swc::{
ast::{
AssignTarget, AssignTargetPat, BlockStmtOrExpr, Callee, Decl,
ExportSpecifier, Expr, ExprOrSpread, FnExpr, ForHead, Function, Ident,
IdentName, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElement,
AssignTarget, AssignTargetPat, BlockStmtOrExpr, Callee, ClassMember,
Decl, ExportSpecifier, Expr, ExprOrSpread, FnExpr, ForHead, Function,
Ident, IdentName, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElement,
JSXElementChild, JSXElementName, JSXEmptyExpr, JSXExpr, JSXExprContainer,
JSXFragment, JSXMemberExpr, JSXNamespacedName, JSXObject,
JSXOpeningElement, Lit, MemberProp, ModuleDecl, ModuleExportName,
ModuleItem, ObjectPatProp, Param, Pat, Program, Prop, PropName,
PropOrSpread, SimpleAssignTarget, Stmt, SuperProp, TsType, VarDeclOrExpr,
ModuleItem, ObjectPatProp, Param, ParamOrTsParamProp, Pat, Program, Prop,
PropName, PropOrSpread, SimpleAssignTarget, Stmt, SuperProp, TsType,
VarDeclOrExpr,
},
common::{Span, Spanned, SyntaxContext, DUMMY_SP},
},
view::{AssignOp, BinaryOp, UnaryOp, UpdateOp, VarDeclKind},
view::{Accessibility, AssignOp, BinaryOp, UnaryOp, UpdateOp, VarDeclKind},
ParsedSource,
};
use indexmap::IndexMap;
@ -36,7 +37,7 @@ enum AstNode {
TsNamespaceExport,
// Decls
Class,
ClassDeclaration,
Fn,
Var,
Using,
@ -60,7 +61,7 @@ enum AstNode {
Throw,
TryStatement,
While,
DoWhile,
DoWhileStatement,
For,
ForInStatement,
ForOf,
@ -71,7 +72,7 @@ enum AstNode {
This,
Array,
Object,
FnExpr,
FunctionExpression,
Unary,
UpdateExpression,
BinaryExpression,
@ -118,6 +119,7 @@ enum AstNode {
RestElement,
ExportSpecifier,
TemplateElement,
MethodDefinition,
// Patterns
ArrayPattern,
@ -243,6 +245,15 @@ enum Flag {
UpdateMinusMinus,
YieldDelegate,
ParamOptional,
ClassDeclare,
ClassAbstract,
ClassConstructor,
ClassMethod,
ClassPublic,
ClassProtected,
ClassPrivate,
}
fn assign_op_to_flag(m: AssignOp) -> u8 {
@ -326,6 +337,15 @@ impl From<Flag> for u8 {
Flag::UpdateMinusMinus => 0b000000100,
Flag::YieldDelegate => 1,
Flag::ParamOptional => 1,
Flag::ClassDeclare => 0b000000001,
Flag::ClassAbstract => 0b000000010,
Flag::ClassConstructor => 0b000000100,
Flag::ClassMethod => 0b000001000,
Flag::ClassPublic => 0b001000000,
Flag::ClassProtected => 0b010000000,
Flag::ClassPrivate => 0b10000000,
}
}
}
@ -704,23 +724,32 @@ fn serialize_stmt(
id
}
Stmt::Switch(node) => {
let id = ctx.push_node(AstNode::Switch.into(), parent_id, &node.span);
let id = ctx.push_node(AstNode::Switch, parent_id, &node.span);
let offset = ctx.reserve_child_ids_with_count(node.cases.len());
let offset = ctx.reserve_child_ids(1);
let cases_offset = ctx.reserve_child_ids_with_count(node.cases.len());
let expr_id = serialize_expr(ctx, &node.discriminant, id);
ctx.set_child(offset, expr_id, 0);
for (i, case) in node.cases.iter().enumerate() {
let child_id =
ctx.push_node(AstNode::SwitchCase.into(), parent_id, &case.span);
let child_offset =
ctx.reserve_child_ids_with_count(case.cons.len() + 1);
let test_offset = ctx.reserve_child_ids(1);
let child_offset = ctx.reserve_child_ids_with_count(case.cons.len());
if let Some(test) = &case.test {
let test_id = serialize_expr(ctx, test, child_id);
ctx.set_child(test_offset, test_id, 0);
}
for (j, cons) in case.cons.iter().enumerate() {
let cons_id = serialize_stmt(ctx, cons, child_id);
ctx.set_child(child_offset, cons_id, j);
}
ctx.set_child(offset, child_id, i);
ctx.set_child(cases_offset, child_id, i);
}
id
@ -785,7 +814,7 @@ fn serialize_stmt(
id
}
Stmt::DoWhile(node) => {
let id = ctx.push_node(AstNode::DoWhile, parent_id, &node.span);
let id = ctx.push_node(AstNode::DoWhileStatement, parent_id, &node.span);
let offset = ctx.reserve_child_ids(2);
@ -879,9 +908,125 @@ fn serialize_decl(
) -> usize {
match decl {
Decl::Class(node) => {
let id = ctx.push_node(AstNode::Class, parent_id, &node.class.span);
let id =
ctx.push_node(AstNode::ClassDeclaration, parent_id, &node.class.span);
// FIXME
let mut flags = FlagValue::new();
if node.declare {
flags.set(Flag::ClassDeclare)
}
if node.class.is_abstract {
flags.set(Flag::ClassAbstract)
}
let offset = ctx.reserve_child_ids(4);
let impl_offset =
ctx.reserve_child_ids_with_count(node.class.implements.len());
let body_offset = ctx.reserve_child_ids_with_count(node.class.body.len());
let ident_id = serialize_ident(ctx, &node.ident, id);
ctx.set_child(offset, ident_id, 0);
if let Some(type_params) = &node.class.type_params {
// FIXME
}
if let Some(super_class) = &node.class.super_class {
let super_id = serialize_expr(ctx, &super_class, id);
ctx.set_child(offset, super_id, 2);
}
if let Some(type_params) = &node.class.super_type_params {
// FIXME
// let type_id = serialize_expr(ctx,&type_params, id);
// ctx.set_child(offset, type_id, 3);
}
for (i, imp) in node.class.implements.iter().enumerate() {
// FIXME
// ctx.set_child(impl_offset, child_id, i);
}
for (i, member) in node.class.body.iter().enumerate() {
let child_id = match member {
ClassMember::Constructor(constructor) => {
let member_id =
ctx.push_node(AstNode::MethodDefinition, id, &constructor.span);
let mut flags = FlagValue::new();
flags.set(Flag::ClassConstructor);
accessibility_to_flag(&mut flags, constructor.accessibility);
ctx.result.push(flags.0);
let offset = ctx.reserve_child_ids(2);
let param_offset = ctx.reserve_child_ids(constructor.params.len());
let key_id = serialize_prop_name(ctx, &constructor.key, member_id);
ctx.set_child(offset, key_id, 0);
if let Some(body) = &constructor.body {
let body_id =
serialize_stmt(ctx, &Stmt::Block(body.clone()), member_id);
ctx.set_child(offset, body_id, 1);
}
for (i, param) in constructor.params.iter().enumerate() {
let child_id = match param {
ParamOrTsParamProp::TsParamProp(ts_param_prop) => todo!(),
ParamOrTsParamProp::Param(param) => {
serialize_pat(ctx, &param.pat, member_id)
}
};
ctx.set_child(param_offset, child_id, i);
}
member_id
}
ClassMember::Method(method) => {
let member_id =
ctx.push_node(AstNode::MethodDefinition, id, &method.span);
let mut flags = FlagValue::new();
flags.set(Flag::ClassMethod);
if method.function.is_async {
//
}
accessibility_to_flag(&mut flags, method.accessibility);
ctx.result.push(flags.0);
let offset = ctx.reserve_child_ids(2);
let param_offset =
ctx.reserve_child_ids(method.function.params.len());
let key_id = serialize_prop_name(ctx, &method.key, member_id);
ctx.set_child(offset, key_id, 0);
if let Some(body) = &method.function.body {
let body_id =
serialize_stmt(ctx, &Stmt::Block(body.clone()), member_id);
ctx.set_child(offset, body_id, 1);
}
for (i, param) in method.function.params.iter().enumerate() {
let child_id = serialize_pat(ctx, &param.pat, member_id);
ctx.set_child(param_offset, child_id, i);
}
member_id
}
ClassMember::PrivateMethod(private_method) => todo!(),
ClassMember::ClassProp(class_prop) => todo!(),
ClassMember::PrivateProp(private_prop) => todo!(),
ClassMember::TsIndexSignature(ts_index_signature) => todo!(),
ClassMember::Empty(_) => unreachable!(),
ClassMember::StaticBlock(static_block) => todo!(),
ClassMember::AutoAccessor(auto_accessor) => todo!(),
};
ctx.set_child(body_offset, child_id, i);
}
id
}
@ -1195,9 +1340,9 @@ fn serialize_expr(
}
Expr::Fn(node) => {
let fn_obj = node.function.as_ref();
let id = ctx.push_node(AstNode::FnExpr, parent_id, &fn_obj.span);
let id =
ctx.push_node(AstNode::FunctionExpression, parent_id, &fn_obj.span);
let flag_offset = ctx.reserve_flag();
let mut flags = FlagValue::new();
if fn_obj.is_async {
flags.set(Flag::FnAsync)
@ -1205,9 +1350,11 @@ fn serialize_expr(
if fn_obj.is_generator {
flags.set(Flag::FnGenerator)
}
ctx.result[flag_offset] = flags.0;
ctx.result.push(flags.0);
let offset = ctx.reserve_child_ids(4);
let param_offset = ctx.reserve_child_ids_with_count(fn_obj.params.len());
let offset = ctx.reserve_child_ids(2);
if let Some(ident) = &node.ident {
let ident_id = serialize_ident(ctx, ident, id);
ctx.set_child(offset, ident_id, 0);
@ -1218,14 +1365,11 @@ fn serialize_expr(
ctx.set_child(offset, 0, 1);
}
let param_offset = ctx.reserve_child_ids_with_count(fn_obj.params.len());
for (i, param) in fn_obj.params.iter().enumerate() {
let child_id = serialize_pat(ctx, &param.pat, id);
ctx.set_child(param_offset, child_id, i);
}
let offset = ctx.reserve_child_ids(2);
if let Some(return_type) = &fn_obj.return_type {
// FIXME
ctx.set_child(offset, 0, 1);
@ -1710,6 +1854,21 @@ fn serialize_expr(
}
}
fn accessibility_to_flag(
flags: &mut FlagValue,
accessibility: Option<Accessibility>,
) {
if let Some(accessibility) = &accessibility {
let value = match accessibility {
Accessibility::Public => Flag::ClassPublic,
Accessibility::Protected => Flag::ClassProtected,
Accessibility::Private => Flag::ClassPrivate,
};
flags.set(value);
}
}
fn serialize_jsx_element(
ctx: &mut SerializeCtx,
node: &JSXElement,
@ -1987,14 +2146,24 @@ fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize {
Pat::Array(node) => {
let id = ctx.push_node(AstNode::ArrayPattern, parent_id, &node.span);
// FIXME: Optional
let mut flags = FlagValue::new();
if node.optional {
flags.set(Flag::ParamOptional);
}
ctx.result.push(flags.0);
let offset = ctx.reserve_child_ids(1);
let elem_offset = ctx.reserve_child_ids_with_count(node.elems.len());
// FIXME: Type Ann
let offset = ctx.reserve_child_ids_with_count(node.elems.len());
if let Some(type_ann) = &node.type_ann {
// ctx.set_child(offset, child_id, 0);
}
for (i, elem) in node.elems.iter().enumerate() {
if let Some(pat) = elem {
let child_id = serialize_pat(ctx, pat, id);
ctx.set_child(offset, child_id, i);
ctx.set_child(elem_offset, child_id, i);
}
}
@ -2017,9 +2186,19 @@ fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize {
Pat::Object(node) => {
let id = ctx.push_node(AstNode::ObjectPattern, parent_id, &node.span);
// FIXME: Optional
let mut flags = FlagValue::new();
if node.optional {
flags.set(Flag::ParamOptional);
}
ctx.result.push(flags.0);
let offset = ctx.reserve_child_ids(1);
let props_offset = ctx.reserve_child_ids_with_count(node.props.len());
// FIXME: Type Ann
let offset = ctx.reserve_child_ids_with_count(node.props.len());
if let Some(type_ann) = &node.type_ann {
// ctx.set_child(offset, child_id, 0);
}
for (i, prop) in node.props.iter().enumerate() {
let child_id = match prop {
@ -2067,7 +2246,7 @@ fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize {
}
};
ctx.set_child(offset, child_id, i);
ctx.set_child(props_offset, child_id, i);
}
id

View file

@ -6173,18 +6173,34 @@ declare namespace Deno {
export interface AssignmentPattern extends BaseNode {
type: "AssignmentPattern";
// FIXME
left: ArrayPattern | ObjectPattern | Identifier;
right: Expression;
// FIXME: I don't think these are possible
// optional: boolean;
// typeAnnotation: TSTypeAnnotation | null;
}
export interface ArrayPattern extends BaseNode {
type: "ArrayPattern";
elements: any[];
elements: Array<
| ArrayPattern
| AssignmentPattern
| Identifier
| MemberExpression
| ObjectPattern
| RestElement
| null
>;
optional: boolean;
typeAnnotation: TSTypeAnnotation | null;
}
export interface ObjectPattern extends BaseNode {
type: "ObjectPattern";
// FIXME
optional: boolean;
properties: Array<Property | RestElement>;
// FIXME: TSEstree uses undefined for type annotations
typeAnnotation: TSTypeAnnotation | null;
}
export interface PrivateIdentifier extends BaseNode {
@ -6195,6 +6211,7 @@ declare namespace Deno {
export interface RestElement extends BaseNode {
type: "RestElement";
argument: Expression;
typeAnnotation: TSTypeAnnotation | null;
}
// Expressions
@ -6306,11 +6323,22 @@ declare namespace Deno {
alternate: Expression;
}
// FIXME
export interface FunctionExpression extends BaseNode {
type: "FunctionExpression";
id: Identifier | null;
async: boolean;
generator: boolean;
params: Array<
| ArrayPattern
| AssignmentPattern
| Identifier
| ObjectPattern
| RestElement
| TSParameterProperty
>;
body: BlockStatement;
expression: boolean; // FIXME: TSEStree
typeParameters: null; // FIXME
returnType: TSTypeAnnotation | null;
}
export interface Identifier extends BaseNode {
@ -7003,6 +7031,11 @@ declare namespace Deno {
| SpreadElement
| VariableDeclarator
| TemplateElement
| ArrayPattern
| AssignmentPattern
| ObjectPattern
| SwitchCase
| RestElement
| JSXNode;
export interface LintRuleContext {

View file

@ -12,8 +12,8 @@ function foo5({ a = 2 }) {}
function foo6([a, b]) {}
function foo7<T, U>(a: T, b: U) {}
async function foo() {}
async function* foo() {
async function foo8() {}
async function* foo9() {
yield 2;
}
@ -28,3 +28,8 @@ import * as imp1 from "./foo.ts";
import imp2 from "./foo.ts";
import { imp3, imp4 as imp5 } from "./foo.ts";
import json from "./json.json" with { type: "json" };
// Patterns
function foo10([a, b]) {}
function foo11({ a }) {}
function foo11(a = 3) {}

View file

@ -16,6 +16,9 @@ outer: while (false) {
continue outer;
}
do {
} while (false);
// Debugger
debugger;