1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-21 21:50:00 -05:00
This commit is contained in:
Marvin Hagemeister 2024-12-10 05:34:12 +01:00
parent 280d10e801
commit 99b9e726d4
4 changed files with 209 additions and 74 deletions

View file

@ -181,7 +181,7 @@ const AstType = {
// Custom // Custom
EmptyExpr: 84, EmptyExpr: 84,
Spread: 85, Spread: 85,
ObjProperty: 86, Property: 86,
VarDeclarator: 87, VarDeclarator: 87,
CatchClause: 88, CatchClause: 88,
@ -1000,7 +1000,7 @@ class ArrowFunctionExpression extends BaseNode {
} }
/** @implements {Deno.AssignmentExpression} */ /** @implements {Deno.AssignmentExpression} */
class AssignmentExpression { class AssignmentExpression extends BaseNode {
type = /** @type {const} */ ("AssignmentExpression"); type = /** @type {const} */ ("AssignmentExpression");
range; range;
get left() { get left() {
@ -1024,12 +1024,15 @@ class AssignmentExpression {
/** /**
* @param {AstContext} ctx * @param {AstContext} ctx
* @param {number} parentId
* @param {Deno.Range} range * @param {Deno.Range} range
* @param {number} flags * @param {number} flags
* @param {number} leftId * @param {number} leftId
* @param {number} rightId * @param {number} rightId
*/ */
constructor(ctx, range, flags, leftId, rightId) { constructor(ctx, parentId, range, flags, leftId, rightId) {
super(ctx, parentId);
this.#ctx = ctx; this.#ctx = ctx;
this.#leftId = leftId; this.#leftId = leftId;
this.#rightId = rightId; this.#rightId = rightId;
@ -1045,37 +1048,37 @@ class AssignmentExpression {
function getAssignOperator(n) { function getAssignOperator(n) {
switch (n) { switch (n) {
case 0: case 0:
return "&&="; return "=";
case 1: case 1:
return "&="; return "+=";
case 2: case 2:
return "**="; return "-=";
case 3: case 3:
return "*="; return "*=";
case 4: case 4:
return "||=";
case 5:
return "|=";
case 6:
return "^=";
case 7:
return "=";
case 8:
return ">>=";
case 9:
return ">>>=";
case 10:
return "<<=";
case 11:
return "-=";
case 12:
return "%=";
case 13:
return "+=";
case 14:
return "??=";
case 15:
return "/="; return "/=";
case 5:
return "%=";
case 6:
return "<<=";
case 7:
return ">>=";
case 8:
return ">>>=";
case 9:
return "|=";
case 10:
return "^=";
case 11:
return "&=";
case 12:
return "**=";
case 13:
return "&&=";
case 14:
return "||=";
case 15:
return "??=";
default: default:
throw new Error(`Unknown operator: ${n}`); throw new Error(`Unknown operator: ${n}`);
} }
@ -1505,6 +1508,32 @@ class NewExpression {
} }
} }
/** @implements {Deno.ObjectExpression} */
class ObjectExpression extends BaseNode {
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} */ /** @implements {Deno.ParenthesisExpression} */
class ParenthesisExpression extends BaseNode { class ParenthesisExpression extends BaseNode {
type = /** @type {const} */ ("ParenthesisExpression"); type = /** @type {const} */ ("ParenthesisExpression");
@ -1553,6 +1582,48 @@ class PrivateIdentifier extends BaseNode {
} }
} }
/** @implements {Deno.Property} */
class Property extends BaseNode {
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.SequenceExpression} */ /** @implements {Deno.SequenceExpression} */
class SequenceExpression extends BaseNode { class SequenceExpression extends BaseNode {
type = /** @type {const} */ ("SequenceExpression"); type = /** @type {const} */ ("SequenceExpression");
@ -2120,7 +2191,6 @@ const DECODER = new TextDecoder();
* buf: Uint8Array, * buf: Uint8Array,
* strTable: Map<number, string>, * strTable: Map<number, string>,
* idTable: number[], * idTable: number[],
* visited: Set<number>,
* }} AstContext * }} AstContext
*/ */
@ -2329,8 +2399,19 @@ function createAstNode(ctx, id) {
returnTypeId, returnTypeId,
); );
} }
case AstType.AssignmentExpression: case AstType.AssignmentExpression: {
throw new AssignmentExpression(ctx, range, flags, 0, 0); // FIXME 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: case AstType.AwaitExpression:
throw new AwaitExpression(ctx, range, 0); // FIXME throw new AwaitExpression(ctx, range, 0); // FIXME
case AstType.BinaryExpression: case AstType.BinaryExpression:
@ -2372,8 +2453,10 @@ function createAstNode(ctx, id) {
throw new MetaProperty(ctx, range, 0, 0); // FIXME throw new MetaProperty(ctx, range, 0, 0); // FIXME
case AstType.NewExpression: case AstType.NewExpression:
throw new NewExpression(ctx, range, 0); // FIXME throw new NewExpression(ctx, range, 0); // FIXME
case AstType.ObjectExpression: case AstType.ObjectExpression: {
throw new Error("TODO"); const elemIds = readChildIds(buf, offset);
return new ObjectExpression(ctx, parentId, range, elemIds);
}
case AstType.ParenthesisExpression: { case AstType.ParenthesisExpression: {
const exprId = readU32(buf, offset); const exprId = readU32(buf, offset);
return new ParenthesisExpression(ctx, parentId, range, exprId); return new ParenthesisExpression(ctx, parentId, range, exprId);
@ -2382,6 +2465,12 @@ function createAstNode(ctx, id) {
const strId = readU32(buf, offset); const strId = readU32(buf, offset);
return new PrivateIdentifier(ctx, parentId, range, strId); 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.StaticBlock: case AstType.StaticBlock:
throw new Error("TODO"); throw new Error("TODO");
case AstType.SequenceExpression: { case AstType.SequenceExpression: {
@ -2511,7 +2600,7 @@ function createAstContext(buf) {
} }
/** @type {AstContext} */ /** @type {AstContext} */
const ctx = { buf, idTable, strTable, visited: new Set() }; const ctx = { buf, idTable, strTable };
return ctx; return ctx;
} }
@ -2618,16 +2707,11 @@ function traverseInner(ctx, visitTypes, visitor, id) {
// Empty id // Empty id
if (id === 0) return; if (id === 0) return;
const { idTable, buf, visited } = ctx; const { idTable, buf } = ctx;
if (id >= idTable.length) { if (id >= idTable.length) {
throw new Error(`Invalid node id: ${id}`); throw new Error(`Invalid node id: ${id}`);
} }
if (visited.has(id)) {
throw new Error(`Already visited ${id}`);
}
visited.add(id);
let offset = idTable[id]; let offset = idTable[id];
if (offset === undefined) throw new Error(`Unknown id: ${id}`); if (offset === undefined) throw new Error(`Unknown id: ${id}`);
@ -2655,6 +2739,7 @@ function traverseInner(ctx, visitTypes, visitor, id) {
// Multiple children only // Multiple children only
case AstType.ArrayExpression: case AstType.ArrayExpression:
case AstType.BlockStatement: case AstType.BlockStatement:
case AstType.ObjectExpression:
case AstType.SequenceExpression: { case AstType.SequenceExpression: {
const stmtsIds = readChildIds(buf, offset); const stmtsIds = readChildIds(buf, offset);
return traverseChildren(ctx, visitTypes, visitor, stmtsIds); return traverseChildren(ctx, visitTypes, visitor, stmtsIds);
@ -2708,8 +2793,33 @@ function traverseInner(ctx, visitTypes, visitor, id) {
return; 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.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;
}
// Two children // Two children
case AstType.AssignmentPattern:
case AstType.LabeledStatement: case AstType.LabeledStatement:
case AstType.WhileStatement: { case AstType.WhileStatement: {
const firstId = readU32(buf, offset); const firstId = readU32(buf, offset);

View file

@ -1,13 +1,14 @@
use deno_ast::{ use deno_ast::{
swc::{ swc::{
ast::{ ast::{
AssignTarget, BlockStmtOrExpr, Callee, Decl, Expr, ForHead, Ident, Lit, AssignTarget, BlockStmtOrExpr, Callee, Decl, Expr, FnExpr, ForHead,
MemberProp, ModuleDecl, ModuleItem, Pat, Program, Prop, PropName, Ident, Lit, MemberProp, ModuleDecl, ModuleItem, Pat, Program, Prop,
PropOrSpread, SimpleAssignTarget, Stmt, SuperProp, TsType, VarDeclOrExpr, PropName, PropOrSpread, SimpleAssignTarget, Stmt, SuperProp, TsType,
VarDeclOrExpr,
}, },
common::{Span, Spanned, DUMMY_SP}, common::{Span, Spanned, DUMMY_SP},
}, },
view::BinaryOp, view::{AssignOp, BinaryOp},
ParsedSource, ParsedSource,
}; };
use indexmap::IndexMap; use indexmap::IndexMap;
@ -180,6 +181,27 @@ enum Flag {
PropSetter, PropSetter,
} }
fn assign_op_to_flag(m: AssignOp) -> u8 {
match m {
AssignOp::Assign => 0,
AssignOp::AddAssign => 1,
AssignOp::SubAssign => 2,
AssignOp::MulAssign => 3,
AssignOp::DivAssign => 4,
AssignOp::ModAssign => 5,
AssignOp::LShiftAssign => 6,
AssignOp::RShiftAssign => 7,
AssignOp::ZeroFillRShiftAssign => 8,
AssignOp::BitOrAssign => 9,
AssignOp::BitXorAssign => 10,
AssignOp::BitAndAssign => 11,
AssignOp::ExpAssign => 12,
AssignOp::AndAssign => 13,
AssignOp::OrAssign => 14,
AssignOp::NullishAssign => 15,
}
}
impl From<Flag> for u8 { impl From<Flag> for u8 {
fn from(m: Flag) -> u8 { fn from(m: Flag) -> u8 {
match m { match m {
@ -324,6 +346,8 @@ pub fn serialize_ast_bin(parsed_source: &ParsedSource) -> Vec<u8> {
let program = &parsed_source.program(); let program = &parsed_source.program();
let mut flags = FlagValue::new(); let mut flags = FlagValue::new();
eprintln!("SWC {:#?}", program);
match program.as_ref() { match program.as_ref() {
Program::Module(module) => { Program::Module(module) => {
let id = ctx.push_node(AstNode::Program, parent_id, &module.span); let id = ctx.push_node(AstNode::Program, parent_id, &module.span);
@ -697,17 +721,7 @@ fn serialize_decl(
let child_offset = ctx.reserve_child_ids(2); // Name + init let child_offset = ctx.reserve_child_ids(2); // Name + init
let decl_id = match &decl.name { let decl_id = serialize_pat(ctx, &decl.name, child_id);
Pat::Ident(binding_ident) => {
serialize_ident(ctx, &binding_ident.id, child_id)
}
Pat::Array(array_pat) => todo!(),
Pat::Rest(rest_pat) => todo!(),
Pat::Object(object_pat) => todo!(),
Pat::Assign(assign_pat) => todo!(),
Pat::Invalid(invalid) => todo!(),
Pat::Expr(expr) => serialize_expr(ctx, expr.as_ref(), child_id),
};
ctx.set_child(child_offset, decl_id, 0); ctx.set_child(child_offset, decl_id, 0);
if let Some(init) = &decl.init { if let Some(init) = &decl.init {
@ -800,7 +814,6 @@ fn serialize_expr(
} }
Expr::Object(node) => { Expr::Object(node) => {
let id = ctx.push_node(AstNode::Object, parent_id, &node.span); let id = ctx.push_node(AstNode::Object, parent_id, &node.span);
let offset = ctx.reserve_child_ids_with_count(node.props.len()); let offset = ctx.reserve_child_ids_with_count(node.props.len());
for (i, prop) in node.props.iter().enumerate() { for (i, prop) in node.props.iter().enumerate() {
@ -828,12 +841,6 @@ fn serialize_expr(
let child_offset = ctx.reserve_child_ids(2); let child_offset = ctx.reserve_child_ids(2);
// FIXME: optional // FIXME: optional
// computed: boolean;
// key: PropertyName;
// kind: 'get' | 'init' | 'set';
// method: boolean;
// optional: boolean;
// shorthand: boolean;
match prop.as_ref() { match prop.as_ref() {
Prop::Shorthand(ident) => { Prop::Shorthand(ident) => {
flags.set(Flag::PropShorthand); flags.set(Flag::PropShorthand);
@ -856,15 +863,23 @@ fn serialize_expr(
ctx.set_child(child_offset, value_id, 1); ctx.set_child(child_offset, value_id, 1);
} }
Prop::Assign(assign_prop) => { Prop::Assign(assign_prop) => {
let child_id = let child_id = ctx.push_node(
ctx.push_node(AstNode::Assign, prop_id, &assign_prop.span); AstNode::AssignmentPattern,
prop_id,
&assign_prop.span,
);
let key_id = serialize_ident(ctx, &assign_prop.key, child_id); let offset = ctx.reserve_child_ids(2);
let key_id = serialize_ident(ctx, &assign_prop.key, prop_id);
let value_id = let value_id =
serialize_expr(ctx, assign_prop.value.as_ref(), child_id); serialize_expr(ctx, assign_prop.value.as_ref(), prop_id);
ctx.set_child(child_id, key_id, 0); ctx.set_child(offset, key_id, 0);
ctx.set_child(child_id, value_id, 1); ctx.set_child(offset, value_id, 1);
ctx.set_child(child_offset, key_id, 0);
ctx.set_child(child_offset, child_id, 1);
} }
Prop::Getter(getter_prop) => { Prop::Getter(getter_prop) => {
flags.set(Flag::PropGetter); flags.set(Flag::PropGetter);
@ -885,9 +900,11 @@ fn serialize_expr(
let key_id = let key_id =
serialize_prop_name(ctx, &setter_prop.key, prop_id); serialize_prop_name(ctx, &setter_prop.key, prop_id);
ctx.set_child(child_offset, key_id, 0);
// let value_id =
// ctx.push_node(AstNode::FnExpr, prop_id, &setter_prop.span);
let child_id =
ctx.push_node(AstNode::FnExpr, prop_id, &setter_prop.span);
// TODO // TODO
// if let Some(body) = &setter_prop.body { // if let Some(body) = &setter_prop.body {
// serialize_stmt(ctx, &Stmt::Block(body.clone())); // serialize_stmt(ctx, &Stmt::Block(body.clone()));
@ -961,6 +978,8 @@ fn serialize_expr(
} }
Expr::Assign(node) => { Expr::Assign(node) => {
let id = ctx.push_node(AstNode::Assign, parent_id, &node.span); let id = ctx.push_node(AstNode::Assign, parent_id, &node.span);
ctx.result.push(assign_op_to_flag(node.op));
let offset = ctx.reserve_child_ids(2); let offset = ctx.reserve_child_ids(2);
let left_id = match &node.left { let left_id = match &node.left {

View file

@ -6283,7 +6283,7 @@ declare namespace Deno {
arguments: Array<Expression | SpreadElement>; arguments: Array<Expression | SpreadElement>;
optional: boolean; // FIXME only in TSEstree optional: boolean; // FIXME only in TSEstree
// FIXME // FIXME
typeArguments: null; // FIXME typeArguments: any; // FIXME
} }
export interface ChainExpression extends BaseNode { export interface ChainExpression extends BaseNode {
@ -6965,6 +6965,7 @@ declare namespace Deno {
| Statement | Statement
| CatchClause | CatchClause
| PrivateIdentifier | PrivateIdentifier
| Property
| JSXNode; | JSXNode;
export interface LintRuleContext { export interface LintRuleContext {

View file

@ -24,7 +24,12 @@ a = {
get foo() { get foo() {
return 1; return 1;
}, },
set foo(a) { // FIXME
2; // set foo(a) {
}, // 2;
// },
// bar() {},
// async barAsync() {},
// *barGen() {},
// async *barAsyncGen() {},
}; };