0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 17:34:47 -05:00

fix traversal

This commit is contained in:
Marvin Hagemeister 2024-12-12 20:53:08 +01:00
parent 8f104313ff
commit 76c1275200
3 changed files with 134 additions and 67 deletions

View file

@ -45,11 +45,11 @@ export class Context {
let start, end;
if (data.node) {
start = data.node.span.start - 1;
end = data.node.span.end - 1;
} else if (data.span) {
start = data.span.start - 1;
end = data.span.end - 1;
start = data.node.range[0] - 1;
end = data.node.range[1] - 1;
} else if (data.range) {
start = data.range[0] - 1;
end = data.range[1] - 1;
} else {
throw new Error(
"Either `node` or `span` must be provided when reporting an error",
@ -2101,6 +2101,48 @@ class Super extends BaseNode {
}
}
/** @implements {Deno.TaggedTemplateExpression} */
class TaggedTemplateExpression extends BaseNode {
type = /** @type {const} */ ("TaggedTemplateExpression");
range;
get tag() {
return /** @type {*} */ (createAstNode(this.#ctx, this.#tagId));
}
get quasi() {
return /** @type {*} */ (createAstNode(this.#ctx, this.#quasiId));
}
get typeArguments() {
if (this.#typeParamId === 0) return null;
return /** @type {*} */ (createAstNode(this.#ctx, this.#typeParamId));
}
#ctx;
#tagId;
#typeParamId;
#quasiId;
/**
* @param {AstContext} ctx
* @param {number} parentId
* @param {Deno.Range} range
* @param {number} tagId
* @param {number} typeParamId
* @param {number} quasiId
*/
constructor(ctx, parentId, range, tagId, typeParamId, quasiId) {
super(ctx, parentId);
this.#ctx = ctx;
this.range = range;
this.#tagId = tagId;
this.#typeParamId = typeParamId;
this.#quasiId = quasiId;
}
}
/** @implements {Deno.UnaryExpression} */
class UnaryExpression extends BaseNode {
type = /** @type {const} */ ("UnaryExpression");
@ -2762,7 +2804,7 @@ class JSXMemberExpression extends BaseNode {
}
/** @implements {Deno.JSXNamespacedName} */
class JSXNamespacedName {
class JSXNamespacedName extends BaseNode {
type = /** @type {const} */ ("JSXNamespacedName");
range;
get name() {
@ -2784,11 +2826,14 @@ class JSXNamespacedName {
/**
* @param {AstContext} ctx
* @param {number} parentId
* @param {Deno.Range} range
* @param {number} nameId
* @param {number} nsId
*/
constructor(ctx, range, nameId, nsId) {
constructor(ctx, parentId, range, nameId, nsId) {
super(ctx, parentId);
this.#ctx = ctx;
this.range = range;
this.#nameId = nameId;
@ -2912,6 +2957,7 @@ const DECODER = new TextDecoder();
* buf: Uint8Array,
* strTable: Map<number, string>,
* idTable: number[],
* rootId: number
* }} AstContext
*/
@ -3323,8 +3369,19 @@ function createAstNode(ctx, id) {
}
case AstType.Super:
throw new Super(ctx, parentId, range);
case AstType.TaggedTemplateExpression:
throw new Error("FIXME");
case AstType.TaggedTemplateExpression: {
const tagId = readU32(buf, offset);
const typeParamId = readU32(buf, offset + 4);
const quasiId = readU32(buf, offset + 8);
return new TaggedTemplateExpression(
ctx,
parentId,
range,
tagId,
typeParamId,
quasiId,
);
}
case AstType.TemplateElement: {
const flags = buf[offset];
@ -3505,8 +3562,15 @@ function createAstContext(buf) {
/** @type {Map<number, string>} */
const strTable = new Map();
let offset = 0;
const stringCount = readU32(buf, 0);
// console.log(JSON.stringify(buf, null, 2));
const strTableOffset = readU32(buf, buf.length - 12);
const idTableOffset = readU32(buf, buf.length - 8);
const rootId = readU32(buf, buf.length - 4);
// console.log({ strTableOffset, idTableOffset, rootId });
let offset = strTableOffset;
const stringCount = readU32(buf, offset);
offset += 4;
let id = 0;
@ -3530,7 +3594,7 @@ function createAstContext(buf) {
}
// Build id table
const idCount = readU32(buf, offset);
const idCount = readU32(buf, idTableOffset);
offset += 4;
const idTable = new Array(idCount);
@ -3549,7 +3613,9 @@ function createAstContext(buf) {
}
/** @type {AstContext} */
const ctx = { buf, idTable, strTable };
const ctx = { buf, idTable, strTable, rootId };
// console.log({ strTable, idTable });
return ctx;
}
@ -3643,9 +3709,7 @@ function traverse(ctx, visitor) {
console.log("merged visitor", visitor);
console.log("visiting types", visitTypes);
// Program is always id 1
const id = 1;
traverseInner(ctx, visitTypes, visitor, id);
traverseInner(ctx, visitTypes, visitor, ctx.rootId);
}
/**
@ -3685,7 +3749,8 @@ function traverseInner(ctx, visitTypes, visitor, id) {
// skip flag reading during traversal
offset += 1;
const childIds = readChildIds(buf, offset);
return traverseChildren(ctx, visitTypes, visitor, childIds);
traverseChildren(ctx, visitTypes, visitor, childIds);
return;
}
case AstType.FunctionDeclaration: {
// Skip flags
@ -3757,9 +3822,9 @@ function traverseInner(ctx, visitTypes, visitor, id) {
// Expressions
case AstType.CallExpression: {
offset += 1; // skip flags
const calleeId = readU32(buf, offset + 1);
const typeArgId = readU32(buf, offset + 5);
const childIds = readChildIds(buf, offset + 9);
const calleeId = readU32(buf, offset);
const typeArgId = readU32(buf, offset + 4);
const childIds = readChildIds(buf, offset + 8);
traverseInner(ctx, visitTypes, visitor, calleeId);
traverseInner(ctx, visitTypes, visitor, typeArgId);
@ -3935,7 +4000,8 @@ function traverseInner(ctx, visitTypes, visitor, id) {
// Three children
case AstType.ConditionalExpression:
case AstType.ForInStatement:
case AstType.IfStatement: {
case AstType.IfStatement:
case AstType.TaggedTemplateExpression: {
const firstId = readU32(buf, offset);
const secondId = readU32(buf, offset + 4);
const thirdId = readU32(buf, offset + 8);

View file

@ -92,7 +92,7 @@ enum AstNode {
Seq,
Identifier,
TemplateLiteral,
TaggedTpl,
TaggedTemplateExpression,
ArrowFunctionExpression,
ClassExpr,
YieldExpression,
@ -481,26 +481,12 @@ impl SerializeCtx {
ctx.str_table.insert("");
ctx.push_node(AstNode::Empty, 0, &DUMMY_SP);
// Placeholder node
ctx.push_node(AstNode::Invalid, 0, &DUMMY_SP);
ctx
}
fn reserve_child_ids_with_count(&mut self, count: usize) -> usize {
append_usize(&mut self.result, count);
self.reserve_child_ids(count)
}
fn reserve_child_ids(&mut self, count: usize) -> usize {
let offset = self.result.len();
for _ in 0..count {
append_usize(&mut self.result, 0);
}
offset
}
fn next_id(&mut self) -> usize {
let id = self.id;
self.id += 1;
@ -563,13 +549,7 @@ impl SerializeCtx {
self.id_to_offset.insert(id, self.result.len());
self.id += 1;
let kind_value: u8 = kind.into();
self.result.push(kind_value);
append_usize(&mut self.result, parent_id);
// Span
append_u32(&mut self.result, span.lo.0);
append_u32(&mut self.result, span.hi.0);
self.write_node(id, kind, parent_id, span);
id
}
@ -585,10 +565,9 @@ pub fn serialize_ast_bin(parsed_source: &ParsedSource) -> Vec<u8> {
// eprintln!("SWC {:#?}", program);
let root_id = ctx.next_id();
match program.as_ref() {
Program::Module(module) => {
let id = ctx.next_id();
flags.set(Flag::ProgramModule);
let child_ids = module
@ -598,47 +577,55 @@ pub fn serialize_ast_bin(parsed_source: &ParsedSource) -> Vec<u8> {
ModuleItem::ModuleDecl(module_decl) => {
serialize_module_decl(&mut ctx, module_decl, parent_id)
}
ModuleItem::Stmt(stmt) => serialize_stmt(&mut ctx, stmt, id),
ModuleItem::Stmt(stmt) => serialize_stmt(&mut ctx, stmt, root_id),
})
.collect::<Vec<_>>();
ctx.write_node(id, AstNode::Program, parent_id, &module.span);
ctx.write_node(root_id, AstNode::Program, parent_id, &module.span);
ctx.write_flags(&flags);
ctx.write_ids(child_ids);
}
Program::Script(script) => {
let id = ctx.next_id();
let child_ids = script
.body
.iter()
.map(|stmt| serialize_stmt(&mut ctx, stmt, id))
.map(|stmt| serialize_stmt(&mut ctx, stmt, root_id))
.collect::<Vec<_>>();
ctx.write_node(id, AstNode::Program, parent_id, &script.span);
ctx.write_node(root_id, AstNode::Program, parent_id, &script.span);
ctx.write_flags(&flags);
ctx.write_ids(child_ids);
}
}
let mut result: Vec<u8> = vec![];
let mut buf: Vec<u8> = vec![];
// Append serialized AST
buf.append(&mut ctx.result);
let offset_str_table = buf.len();
// Serialize string table
// eprintln!("STRING {:#?}", ctx.str_table);
result.append(&mut ctx.str_table.serialize());
buf.append(&mut ctx.str_table.serialize());
let offset_id_table = buf.len();
// Serialize ids
append_usize(&mut result, ctx.id_to_offset.len());
append_usize(&mut buf, ctx.id_to_offset.len());
let offset = result.len() + (ctx.id_to_offset.len() * 4);
for (_i, value) in ctx.id_to_offset {
append_usize(&mut result, value + offset);
let mut ids = ctx.id_to_offset.keys().collect::<Vec<_>>();
ids.sort();
for id in ids {
let offset = ctx.id_to_offset.get(id).unwrap();
append_usize(&mut buf, *offset);
}
// Append serialized AST
result.append(&mut ctx.result);
result
append_usize(&mut buf, offset_str_table);
append_usize(&mut buf, offset_id_table);
append_usize(&mut buf, root_id);
buf
}
fn serialize_module_decl(
@ -1508,10 +1495,24 @@ fn serialize_expr(
id
}
Expr::TaggedTpl(tagged_tpl) => {
let id = ctx.push_node(AstNode::TaggedTpl, parent_id, &tagged_tpl.span);
Expr::TaggedTpl(node) => {
let id = ctx.next_id();
let tag_id = serialize_expr(ctx, &node.tag, id);
// FIXME
let type_param_id = 0;
let quasi_id = serialize_expr(ctx, &Expr::Tpl(*node.tpl.clone()), id);
ctx.write_node(
id,
AstNode::TaggedTemplateExpression,
parent_id,
&node.span,
);
ctx.write_id(tag_id);
ctx.write_id(type_param_id);
ctx.write_id(quasi_id);
id
}
@ -2030,7 +2031,6 @@ fn serialize_decl(
}
Decl::Using(node) => {
let id = ctx.push_node(AstNode::Using, parent_id, &node.span);
let offset = ctx.reserve_child_ids_with_count(node.decls.len());
for (i, decl) in node.decls.iter().enumerate() {
// FIXME

View file

@ -6169,6 +6169,7 @@ declare namespace Deno {
export interface BaseNode {
range: Range;
parent: AstNode;
}
export interface AssignmentPattern extends BaseNode {
@ -6434,7 +6435,7 @@ declare namespace Deno {
type: "TaggedTemplateExpression";
quasi: TemplateLiteral;
tag: Expression;
// typeArguments: TSTypeParameterInstantiation | undefined; // FIXME
typeArguments: null; // FIXME
}
export interface TemplateLiteral extends BaseNode {