mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 20:28:58 +00:00
style(traverse): fix formatting of traverse codegen (#5651)
`dprint` rather mangled indentation of these files.
This commit is contained in:
parent
e38114b825
commit
e52d006fc8
4 changed files with 215 additions and 215 deletions
|
|
@ -32,16 +32,16 @@ export default function generateAncestorsCode(types) {
|
|||
if (otherField === field) continue;
|
||||
|
||||
methodsCode += `
|
||||
#[inline]
|
||||
pub fn ${otherField.rawName}(self) -> &'t ${otherField.rawTypeName} {
|
||||
unsafe {
|
||||
&*(
|
||||
(self.0 as *const u8).add(${otherField.offsetVarName})
|
||||
as *const ${otherField.rawTypeName}
|
||||
)
|
||||
}
|
||||
}
|
||||
`;
|
||||
#[inline]
|
||||
pub fn ${otherField.rawName}(self) -> &'t ${otherField.rawTypeName} {
|
||||
unsafe {
|
||||
&*(
|
||||
(self.0 as *const u8).add(${otherField.offsetVarName})
|
||||
as *const ${otherField.rawTypeName}
|
||||
)
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
const fieldNameCamel = snakeToCamel(field.name),
|
||||
|
|
@ -49,17 +49,17 @@ export default function generateAncestorsCode(types) {
|
|||
structName = `${type.name}Without${fieldNameCamel}${lifetimes}`;
|
||||
|
||||
thisAncestorTypes += `
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ${structName}(
|
||||
pub(crate) *const ${type.rawName},
|
||||
pub(crate) PhantomData<&'t ()>,
|
||||
);
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct ${structName}(
|
||||
pub(crate) *const ${type.rawName},
|
||||
pub(crate) PhantomData<&'t ()>,
|
||||
);
|
||||
|
||||
impl${lifetimes} ${structName} {
|
||||
${methodsCode}
|
||||
}
|
||||
`;
|
||||
impl${lifetimes} ${structName} {
|
||||
${methodsCode}
|
||||
}
|
||||
`;
|
||||
|
||||
const variantName = `${type.name}${fieldNameCamel}`;
|
||||
variantNames.push(variantName);
|
||||
|
|
@ -76,85 +76,85 @@ export default function generateAncestorsCode(types) {
|
|||
|
||||
if (variantNames.length > 0) {
|
||||
ancestorTypes += `
|
||||
${offsetCode}
|
||||
${thisAncestorTypes}
|
||||
`;
|
||||
${offsetCode}
|
||||
${thisAncestorTypes}
|
||||
`;
|
||||
|
||||
isFunctions += `
|
||||
#[inline]
|
||||
pub fn is_${typeSnakeName}(self) -> bool {
|
||||
matches!(self, ${variantNames.map(name => `Self::${name}(_)`).join(' | ')})
|
||||
}
|
||||
`;
|
||||
#[inline]
|
||||
pub fn is_${typeSnakeName}(self) -> bool {
|
||||
matches!(self, ${variantNames.map(name => `Self::${name}(_)`).join(' | ')})
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
for (const [typeName, variantNames] of Object.entries(variantNamesForEnums)) {
|
||||
isFunctions += `
|
||||
#[inline]
|
||||
pub fn is_via_${camelToSnake(typeName)}(self) -> bool {
|
||||
matches!(self, ${variantNames.map(name => `Self::${name}(_)`).join(' | ')})
|
||||
}
|
||||
`;
|
||||
#[inline]
|
||||
pub fn is_via_${camelToSnake(typeName)}(self) -> bool {
|
||||
matches!(self, ${variantNames.map(name => `Self::${name}(_)`).join(' | ')})
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
return `
|
||||
#![allow(
|
||||
unsafe_code,
|
||||
clippy::missing_safety_doc,
|
||||
clippy::ptr_as_ptr,
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
clippy::cast_ptr_alignment
|
||||
)]
|
||||
#![allow(
|
||||
unsafe_code,
|
||||
clippy::missing_safety_doc,
|
||||
clippy::ptr_as_ptr,
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
clippy::cast_ptr_alignment
|
||||
)]
|
||||
|
||||
use std::{cell::Cell, marker::PhantomData};
|
||||
use std::{cell::Cell, marker::PhantomData};
|
||||
|
||||
use memoffset::offset_of;
|
||||
use memoffset::offset_of;
|
||||
|
||||
use oxc_allocator::{Box, Vec};
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_syntax::scope::ScopeId;
|
||||
use oxc_allocator::{Box, Vec};
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_syntax::scope::ScopeId;
|
||||
|
||||
/// Type of [\`Ancestor\`].
|
||||
/// Used in [\`crate::TraverseCtx::retag_stack\`].
|
||||
#[repr(u16)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) enum AncestorType {
|
||||
None = 0,
|
||||
${ancestorTypeEnumVariants}
|
||||
}
|
||||
/// Type of [\`Ancestor\`].
|
||||
/// Used in [\`crate::TraverseCtx::retag_stack\`].
|
||||
#[repr(u16)]
|
||||
#[derive(Clone, Copy)]
|
||||
#[allow(dead_code)]
|
||||
pub(crate) enum AncestorType {
|
||||
None = 0,
|
||||
${ancestorTypeEnumVariants}
|
||||
}
|
||||
|
||||
/// Ancestor type used in AST traversal.
|
||||
///
|
||||
/// Encodes both the type of the parent, and child's location in the parent.
|
||||
/// i.e. variants for \`BinaryExpressionLeft\` and \`BinaryExpressionRight\`, not just \`BinaryExpression\`.
|
||||
///
|
||||
/// \`'a\` is lifetime of AST nodes.
|
||||
/// \`'t\` is lifetime of the \`Ancestor\` (which inherits lifetime from \`&'t TraverseCtx'\`).
|
||||
/// i.e. \`Ancestor\`s can only exist within the body of \`enter_*\` and \`exit_*\` methods
|
||||
/// and cannot "escape" from them.
|
||||
//
|
||||
// SAFETY:
|
||||
// * This type must be \`#[repr(u16)]\`.
|
||||
// * Variant discriminants must correspond to those in \`AncestorType\`.
|
||||
//
|
||||
// These invariants make it possible to set the discriminant of an \`Ancestor\` without altering
|
||||
// the "payload" pointer with:
|
||||
// \`*(ancestor as *mut _ as *mut AncestorType) = AncestorType::Program\`.
|
||||
// \`TraverseCtx::retag_stack\` uses this technique.
|
||||
#[repr(C, u16)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Ancestor<'a, 't> {
|
||||
None = AncestorType::None as u16,
|
||||
${ancestorEnumVariants}
|
||||
}
|
||||
/// Ancestor type used in AST traversal.
|
||||
///
|
||||
/// Encodes both the type of the parent, and child's location in the parent.
|
||||
/// i.e. variants for \`BinaryExpressionLeft\` and \`BinaryExpressionRight\`, not just \`BinaryExpression\`.
|
||||
///
|
||||
/// \`'a\` is lifetime of AST nodes.
|
||||
/// \`'t\` is lifetime of the \`Ancestor\` (which inherits lifetime from \`&'t TraverseCtx'\`).
|
||||
/// i.e. \`Ancestor\`s can only exist within the body of \`enter_*\` and \`exit_*\` methods
|
||||
/// and cannot "escape" from them.
|
||||
//
|
||||
// SAFETY:
|
||||
// * This type must be \`#[repr(u16)]\`.
|
||||
// * Variant discriminants must correspond to those in \`AncestorType\`.
|
||||
//
|
||||
// These invariants make it possible to set the discriminant of an \`Ancestor\` without altering
|
||||
// the "payload" pointer with:
|
||||
// \`*(ancestor as *mut _ as *mut AncestorType) = AncestorType::Program\`.
|
||||
// \`TraverseCtx::retag_stack\` uses this technique.
|
||||
#[repr(C, u16)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Ancestor<'a, 't> {
|
||||
None = AncestorType::None as u16,
|
||||
${ancestorEnumVariants}
|
||||
}
|
||||
|
||||
impl<'a, 't> Ancestor<'a, 't> {
|
||||
${isFunctions}
|
||||
}
|
||||
impl<'a, 't> Ancestor<'a, 't> {
|
||||
${isFunctions}
|
||||
}
|
||||
|
||||
${ancestorTypes}
|
||||
`;
|
||||
${ancestorTypes}
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,44 +7,44 @@ export default function generateScopesCollectorCode(types) {
|
|||
|
||||
const extraParams = type.scopeArgs.flags === 'flags' ? ', _flags: ScopeFlags' : '';
|
||||
methods += `
|
||||
#[inline]
|
||||
fn visit_${camelToSnake(type.name)}(&mut self, it: &${type.rawName}${extraParams}) {
|
||||
self.add_scope(&it.scope_id);
|
||||
}
|
||||
`;
|
||||
#[inline]
|
||||
fn visit_${camelToSnake(type.name)}(&mut self, it: &${type.rawName}${extraParams}) {
|
||||
self.add_scope(&it.scope_id);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
return `
|
||||
use std::cell::Cell;
|
||||
use std::cell::Cell;
|
||||
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::{ast::*, visit::Visit};
|
||||
use oxc_syntax::scope::{ScopeFlags, ScopeId};
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::{ast::*, visit::Visit};
|
||||
use oxc_syntax::scope::{ScopeFlags, ScopeId};
|
||||
|
||||
/// Visitor that locates all child scopes.
|
||||
/// NB: Child scopes only, not grandchild scopes.
|
||||
/// Does not do full traversal - stops each time it hits a node with a scope.
|
||||
pub(crate) struct ChildScopeCollector {
|
||||
pub(crate) scope_ids: Vec<ScopeId>,
|
||||
}
|
||||
/// Visitor that locates all child scopes.
|
||||
/// NB: Child scopes only, not grandchild scopes.
|
||||
/// Does not do full traversal - stops each time it hits a node with a scope.
|
||||
pub(crate) struct ChildScopeCollector {
|
||||
pub(crate) scope_ids: Vec<ScopeId>,
|
||||
}
|
||||
|
||||
impl ChildScopeCollector {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { scope_ids: vec![] }
|
||||
}
|
||||
impl ChildScopeCollector {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { scope_ids: vec![] }
|
||||
}
|
||||
|
||||
pub(crate) fn add_scope(&mut self, scope_id: &Cell<Option<ScopeId>>) {
|
||||
self.scope_ids.push(scope_id.get().unwrap());
|
||||
}
|
||||
}
|
||||
pub(crate) fn add_scope(&mut self, scope_id: &Cell<Option<ScopeId>>) {
|
||||
self.scope_ids.push(scope_id.get().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visit<'a> for ChildScopeCollector {
|
||||
${methods}
|
||||
impl<'a> Visit<'a> for ChildScopeCollector {
|
||||
${methods}
|
||||
|
||||
#[inline]
|
||||
fn visit_finally_clause(&mut self, it: &BlockStatement<'a>) {
|
||||
self.add_scope(&it.scope_id);
|
||||
}
|
||||
}
|
||||
`;
|
||||
#[inline]
|
||||
fn visit_finally_clause(&mut self, it: &BlockStatement<'a>) {
|
||||
self.add_scope(&it.scope_id);
|
||||
}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,23 +8,23 @@ export default function generateTraverseTraitCode(types) {
|
|||
for (const type of typesArr) {
|
||||
const snakeName = camelToSnake(type.name);
|
||||
traverseMethods += `
|
||||
#[inline]
|
||||
fn enter_${snakeName}(&mut self, node: &mut ${type.rawName}, ctx: &mut TraverseCtx<'a>) {}
|
||||
#[inline]
|
||||
fn exit_${snakeName}(&mut self, node: &mut ${type.rawName}, ctx: &mut TraverseCtx<'a>) {}
|
||||
`;
|
||||
#[inline]
|
||||
fn enter_${snakeName}(&mut self, node: &mut ${type.rawName}, ctx: &mut TraverseCtx<'a>) {}
|
||||
#[inline]
|
||||
fn exit_${snakeName}(&mut self, node: &mut ${type.rawName}, ctx: &mut TraverseCtx<'a>) {}
|
||||
`;
|
||||
}
|
||||
|
||||
return `
|
||||
use oxc_allocator::Vec;
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_allocator::Vec;
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::ast::*;
|
||||
|
||||
use crate::TraverseCtx;
|
||||
use crate::TraverseCtx;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub trait Traverse<'a> {
|
||||
${traverseMethods}
|
||||
}
|
||||
`;
|
||||
#[allow(unused_variables)]
|
||||
pub trait Traverse<'a> {
|
||||
${traverseMethods}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,38 +12,38 @@ export default function generateWalkFunctionsCode(types) {
|
|||
}
|
||||
|
||||
return `
|
||||
#![allow(
|
||||
unsafe_code,
|
||||
clippy::missing_safety_doc,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
clippy::semicolon_if_nothing_returned,
|
||||
clippy::cast_ptr_alignment
|
||||
)]
|
||||
#![allow(
|
||||
unsafe_code,
|
||||
clippy::missing_safety_doc,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
clippy::semicolon_if_nothing_returned,
|
||||
clippy::cast_ptr_alignment
|
||||
)]
|
||||
|
||||
use std::{cell::Cell, marker::PhantomData};
|
||||
use std::{cell::Cell, marker::PhantomData};
|
||||
|
||||
use oxc_allocator::Vec;
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_syntax::scope::ScopeId;
|
||||
use oxc_allocator::Vec;
|
||||
#[allow(clippy::wildcard_imports)]
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_syntax::scope::ScopeId;
|
||||
|
||||
use crate::{ancestor::{self, AncestorType}, Ancestor, Traverse, TraverseCtx};
|
||||
use crate::{ancestor::{self, AncestorType}, Ancestor, Traverse, TraverseCtx};
|
||||
|
||||
${walkMethods}
|
||||
${walkMethods}
|
||||
|
||||
pub(crate) unsafe fn walk_statements<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
stmts: *mut Vec<'a, Statement<'a>>,
|
||||
ctx: &mut TraverseCtx<'a>
|
||||
) {
|
||||
traverser.enter_statements(&mut *stmts, ctx);
|
||||
for stmt in (*stmts).iter_mut() {
|
||||
walk_statement(traverser, stmt, ctx);
|
||||
}
|
||||
traverser.exit_statements(&mut *stmts, ctx);
|
||||
}
|
||||
`;
|
||||
pub(crate) unsafe fn walk_statements<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
stmts: *mut Vec<'a, Statement<'a>>,
|
||||
ctx: &mut TraverseCtx<'a>
|
||||
) {
|
||||
traverser.enter_statements(&mut *stmts, ctx);
|
||||
for stmt in (*stmts).iter_mut() {
|
||||
walk_statement(traverser, stmt, ctx);
|
||||
}
|
||||
traverser.exit_statements(&mut *stmts, ctx);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
function generateWalkForStruct(type, types) {
|
||||
|
|
@ -77,9 +77,9 @@ function generateWalkForStruct(type, types) {
|
|||
// Visitor should not do that though, so maybe it's OK.
|
||||
// In final version, we should not make `scope_id` fields `Cell`s to prevent this.
|
||||
enterScopeCode = `
|
||||
let previous_scope_id = ctx.current_scope_id();
|
||||
ctx.set_current_scope_id((*(${makeFieldCode(scopeIdField)})).get().unwrap());
|
||||
`;
|
||||
let previous_scope_id = ctx.current_scope_id();
|
||||
ctx.set_current_scope_id((*(${makeFieldCode(scopeIdField)})).get().unwrap());
|
||||
`;
|
||||
exitScopeCode = `ctx.set_current_scope_id(previous_scope_id);`;
|
||||
}
|
||||
|
||||
|
|
@ -91,12 +91,12 @@ function generateWalkForStruct(type, types) {
|
|||
let tagCode = '', retagCode = '';
|
||||
if (index === 0) {
|
||||
tagCode = `
|
||||
let pop_token = ctx.push_stack(
|
||||
Ancestor::${type.name}${fieldCamelName}(
|
||||
ancestor::${type.name}Without${fieldCamelName}(node, PhantomData)
|
||||
)
|
||||
);
|
||||
`;
|
||||
let pop_token = ctx.push_stack(
|
||||
Ancestor::${type.name}${fieldCamelName}(
|
||||
ancestor::${type.name}Without${fieldCamelName}(node, PhantomData)
|
||||
)
|
||||
);
|
||||
`;
|
||||
} else {
|
||||
retagCode = `ctx.retag_stack(AncestorType::${type.name}${fieldCamelName});`;
|
||||
}
|
||||
|
|
@ -111,10 +111,10 @@ function generateWalkForStruct(type, types) {
|
|||
walkCode = `walk_statements(traverser, std::ptr::from_mut(field), ctx);`;
|
||||
} else {
|
||||
walkCode = `
|
||||
for item in field.iter_mut() {
|
||||
${fieldWalkName}(traverser, std::ptr::from_mut(item), ctx);
|
||||
}
|
||||
`.trim();
|
||||
for item in field.iter_mut() {
|
||||
${fieldWalkName}(traverser, std::ptr::from_mut(item), ctx);
|
||||
}
|
||||
`.trim();
|
||||
}
|
||||
} else if (field.wrappers.length === 2 && field.wrappers[1] === 'Box') {
|
||||
walkCode = `${fieldWalkName}(traverser, std::ptr::from_mut(&mut **field), ctx);`;
|
||||
|
|
@ -124,13 +124,13 @@ function generateWalkForStruct(type, types) {
|
|||
}
|
||||
|
||||
return `
|
||||
${scopeCode}
|
||||
${tagCode}
|
||||
if let Some(field) = &mut *(${fieldCode}) {
|
||||
${retagCode}
|
||||
${walkCode}
|
||||
}
|
||||
`;
|
||||
${scopeCode}
|
||||
${tagCode}
|
||||
if let Some(field) = &mut *(${fieldCode}) {
|
||||
${retagCode}
|
||||
${walkCode}
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
if (field.wrappers[0] === 'Vec') {
|
||||
|
|
@ -150,51 +150,51 @@ function generateWalkForStruct(type, types) {
|
|||
);
|
||||
}
|
||||
walkVecCode = `
|
||||
for item in (*(${fieldCode})).iter_mut()${iterModifier} {
|
||||
${walkCode}
|
||||
}
|
||||
`.trim();
|
||||
for item in (*(${fieldCode})).iter_mut()${iterModifier} {
|
||||
${walkCode}
|
||||
}
|
||||
`.trim();
|
||||
}
|
||||
|
||||
return `
|
||||
${scopeCode}
|
||||
${tagCode || retagCode}
|
||||
${walkVecCode}
|
||||
`;
|
||||
${scopeCode}
|
||||
${tagCode || retagCode}
|
||||
${walkVecCode}
|
||||
`;
|
||||
}
|
||||
|
||||
if (field.wrappers.length === 1 && field.wrappers[0] === 'Box') {
|
||||
return `
|
||||
${scopeCode}
|
||||
${tagCode || retagCode}
|
||||
${fieldWalkName}(traverser, std::ptr::from_mut(&mut **(${fieldCode})), ctx);
|
||||
`;
|
||||
${scopeCode}
|
||||
${tagCode || retagCode}
|
||||
${fieldWalkName}(traverser, std::ptr::from_mut(&mut **(${fieldCode})), ctx);
|
||||
`;
|
||||
}
|
||||
|
||||
assert(field.wrappers.length === 0, `Cannot handle struct field with type: ${field.type}`);
|
||||
|
||||
return `
|
||||
${scopeCode}
|
||||
${tagCode || retagCode}
|
||||
${fieldWalkName}(traverser, ${fieldCode}, ctx);
|
||||
`;
|
||||
${scopeCode}
|
||||
${tagCode || retagCode}
|
||||
${fieldWalkName}(traverser, ${fieldCode}, ctx);
|
||||
`;
|
||||
});
|
||||
|
||||
if (visitedFields.length > 0) fieldsCodes.push('ctx.pop_stack(pop_token);');
|
||||
|
||||
const typeSnakeName = camelToSnake(type.name);
|
||||
return `
|
||||
pub(crate) unsafe fn walk_${typeSnakeName}<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut ${type.rawName},
|
||||
ctx: &mut TraverseCtx<'a>
|
||||
) {
|
||||
traverser.enter_${typeSnakeName}(&mut *node, ctx);
|
||||
${fieldsCodes.join('\n')}
|
||||
${exitScopeCode}
|
||||
traverser.exit_${typeSnakeName}(&mut *node, ctx);
|
||||
}
|
||||
`.replace(/\n\s*\n+/g, '\n');
|
||||
pub(crate) unsafe fn walk_${typeSnakeName}<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut ${type.rawName},
|
||||
ctx: &mut TraverseCtx<'a>
|
||||
) {
|
||||
traverser.enter_${typeSnakeName}(&mut *node, ctx);
|
||||
${fieldsCodes.join('\n')}
|
||||
${exitScopeCode}
|
||||
traverser.exit_${typeSnakeName}(&mut *node, ctx);
|
||||
}
|
||||
`.replace(/\n\s*\n+/g, '\n');
|
||||
}
|
||||
|
||||
function makeFieldCode(field) {
|
||||
|
|
@ -245,16 +245,16 @@ function generateWalkForEnum(type, types) {
|
|||
|
||||
const typeSnakeName = camelToSnake(type.name);
|
||||
return `
|
||||
pub(crate) unsafe fn walk_${typeSnakeName}<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut ${type.rawName},
|
||||
ctx: &mut TraverseCtx<'a>
|
||||
) {
|
||||
traverser.enter_${typeSnakeName}(&mut *node, ctx);
|
||||
match &mut *node {
|
||||
${variantCodes.join('\n')}
|
||||
}
|
||||
traverser.exit_${typeSnakeName}(&mut *node, ctx);
|
||||
}
|
||||
`;
|
||||
pub(crate) unsafe fn walk_${typeSnakeName}<'a, Tr: Traverse<'a>>(
|
||||
traverser: &mut Tr,
|
||||
node: *mut ${type.rawName},
|
||||
ctx: &mut TraverseCtx<'a>
|
||||
) {
|
||||
traverser.enter_${typeSnakeName}(&mut *node, ctx);
|
||||
match &mut *node {
|
||||
${variantCodes.join('\n')}
|
||||
}
|
||||
traverser.exit_${typeSnakeName}(&mut *node, ctx);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue