mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
fix traversal
This commit is contained in:
parent
8f104313ff
commit
76c1275200
3 changed files with 134 additions and 67 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
3
cli/tsc/dts/lib.deno.ns.d.ts
vendored
3
cli/tsc/dts/lib.deno.ns.d.ts
vendored
|
@ -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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue