mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
47 lines
1.3 KiB
JavaScript
47 lines
1.3 KiB
JavaScript
import { camelToSnake } from './utils.mjs';
|
|
|
|
/**
|
|
* @param {import('./parse.mjs').Types} types
|
|
*/
|
|
export default function generateScopesCollectorCode(types) {
|
|
let methods = '';
|
|
for (const type of Object.values(types)) {
|
|
if (type.kind === 'enum' || !type.scopeArgs) continue;
|
|
|
|
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);
|
|
}
|
|
`;
|
|
}
|
|
|
|
return `
|
|
use std::cell::Cell;
|
|
|
|
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>,
|
|
}
|
|
|
|
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());
|
|
}
|
|
}
|
|
|
|
impl<'a> Visit<'a> for ChildScopeCollector {
|
|
${methods}
|
|
}
|
|
`;
|
|
}
|