mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(ast): pass final ScopeFlags into visit_function (#4283)
We have a strange workaround for `visit_function` where we pass in `ScopeFlags`, to support creating the scope inside `Function`, but setting different flags for `MethodDefinition`s. Previously `visit_function` took `Option<ScopeFlags>` and then did `flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function` to it. Personally, I found this confusing. When I was looking at `MethodDefinition`, I was wondering "It's a function, why doesn't it set Function flag too?" This changes makes it more explicit and clear what `ScopeFlags` everything has.
This commit is contained in:
parent
bf3d8d3e8f
commit
2c7bb9f6c8
11 changed files with 44 additions and 48 deletions
|
|
@ -79,7 +79,7 @@ pub enum Expression<'a> {
|
|||
ChainExpression(Box<'a, ChainExpression<'a>>) = 16,
|
||||
ClassExpression(Box<'a, Class<'a>>) = 17,
|
||||
ConditionalExpression(Box<'a, ConditionalExpression<'a>>) = 18,
|
||||
#[visit_args(flags = None)]
|
||||
#[visit_args(flags = ScopeFlags::Function)]
|
||||
FunctionExpression(Box<'a, Function<'a>>) = 19,
|
||||
ImportExpression(Box<'a, ImportExpression<'a>>) = 20,
|
||||
LogicalExpression(Box<'a, LogicalExpression<'a>>) = 21,
|
||||
|
|
@ -970,7 +970,7 @@ pub struct BlockStatement<'a> {
|
|||
#[cfg_attr(feature = "serialize", serde(untagged))]
|
||||
pub enum Declaration<'a> {
|
||||
VariableDeclaration(Box<'a, VariableDeclaration<'a>>) = 32,
|
||||
#[visit_args(flags = None)]
|
||||
#[visit_args(flags = ScopeFlags::Function)]
|
||||
FunctionDeclaration(Box<'a, Function<'a>>) = 33,
|
||||
ClassDeclaration(Box<'a, Class<'a>>) = 34,
|
||||
UsingDeclaration(Box<'a, UsingDeclaration<'a>>) = 35,
|
||||
|
|
@ -1437,8 +1437,8 @@ pub struct BindingRestElement<'a> {
|
|||
/// Function Definitions
|
||||
#[visited_node]
|
||||
#[scope(
|
||||
// TODO: `ScopeFlags::Function` is not correct if this is a `MethodDefinition`
|
||||
flags(flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function),
|
||||
// `flags` passed in to visitor via parameter defined by `#[visit_args(flags = ...)]` on parents
|
||||
flags(flags),
|
||||
strict_if(self.is_strict()),
|
||||
)]
|
||||
#[derive(Debug)]
|
||||
|
|
@ -1642,12 +1642,12 @@ pub struct MethodDefinition<'a> {
|
|||
pub span: Span,
|
||||
pub decorators: Vec<'a, Decorator<'a>>,
|
||||
pub key: PropertyKey<'a>,
|
||||
#[visit_args(flags = Some(match self.kind {
|
||||
MethodDefinitionKind::Get => ScopeFlags::GetAccessor,
|
||||
MethodDefinitionKind::Set => ScopeFlags::SetAccessor,
|
||||
MethodDefinitionKind::Constructor => ScopeFlags::Constructor,
|
||||
MethodDefinitionKind::Method => ScopeFlags::empty(),
|
||||
}))]
|
||||
#[visit_args(flags = match self.kind {
|
||||
MethodDefinitionKind::Get => ScopeFlags::Function | ScopeFlags::GetAccessor,
|
||||
MethodDefinitionKind::Set => ScopeFlags::Function | ScopeFlags::SetAccessor,
|
||||
MethodDefinitionKind::Constructor => ScopeFlags::Function | ScopeFlags::Constructor,
|
||||
MethodDefinitionKind::Method => ScopeFlags::Function,
|
||||
})]
|
||||
pub value: Box<'a, Function<'a>>, // FunctionExpression
|
||||
pub kind: MethodDefinitionKind,
|
||||
pub computed: bool,
|
||||
|
|
@ -1959,7 +1959,7 @@ inherit_variants! {
|
|||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(untagged))]
|
||||
pub enum ExportDefaultDeclarationKind<'a> {
|
||||
#[visit_args(flags = None)]
|
||||
#[visit_args(flags = ScopeFlags::Function)]
|
||||
FunctionDeclaration(Box<'a, Function<'a>>) = 64,
|
||||
ClassDeclaration(Box<'a, Class<'a>>) = 65,
|
||||
|
||||
|
|
|
|||
|
|
@ -836,7 +836,7 @@ pub trait Visit<'a>: Sized {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_function(&mut self, it: &Function<'a>, flags: Option<ScopeFlags>) {
|
||||
fn visit_function(&mut self, it: &Function<'a>, flags: ScopeFlags) {
|
||||
walk_function(self, it, flags);
|
||||
}
|
||||
|
||||
|
|
@ -1509,7 +1509,7 @@ pub mod walk {
|
|||
Expression::ClassExpression(it) => visitor.visit_class(it),
|
||||
Expression::ConditionalExpression(it) => visitor.visit_conditional_expression(it),
|
||||
Expression::FunctionExpression(it) => {
|
||||
let flags = None;
|
||||
let flags = ScopeFlags::Function;
|
||||
visitor.visit_function(it, flags)
|
||||
}
|
||||
Expression::ImportExpression(it) => visitor.visit_import_expression(it),
|
||||
|
|
@ -3014,27 +3014,23 @@ pub mod walk {
|
|||
visitor.visit_decorators(&it.decorators);
|
||||
visitor.visit_property_key(&it.key);
|
||||
{
|
||||
let flags = Some(match it.kind {
|
||||
MethodDefinitionKind::Get => ScopeFlags::GetAccessor,
|
||||
MethodDefinitionKind::Set => ScopeFlags::SetAccessor,
|
||||
MethodDefinitionKind::Constructor => ScopeFlags::Constructor,
|
||||
MethodDefinitionKind::Method => ScopeFlags::empty(),
|
||||
});
|
||||
let flags = match it.kind {
|
||||
MethodDefinitionKind::Get => ScopeFlags::Function | ScopeFlags::GetAccessor,
|
||||
MethodDefinitionKind::Set => ScopeFlags::Function | ScopeFlags::SetAccessor,
|
||||
MethodDefinitionKind::Constructor => ScopeFlags::Function | ScopeFlags::Constructor,
|
||||
MethodDefinitionKind::Method => ScopeFlags::Function,
|
||||
};
|
||||
visitor.visit_function(&it.value, flags);
|
||||
}
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
pub fn walk_function<'a, V: Visit<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &Function<'a>,
|
||||
flags: Option<ScopeFlags>,
|
||||
) {
|
||||
pub fn walk_function<'a, V: Visit<'a>>(visitor: &mut V, it: &Function<'a>, flags: ScopeFlags) {
|
||||
let kind = AstKind::Function(visitor.alloc(it));
|
||||
visitor.enter_node(kind);
|
||||
visitor.enter_scope(
|
||||
{
|
||||
let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function;
|
||||
let mut flags = flags;
|
||||
if it.is_strict() {
|
||||
flags |= ScopeFlags::StrictMode;
|
||||
}
|
||||
|
|
@ -3738,7 +3734,7 @@ pub mod walk {
|
|||
match it {
|
||||
Declaration::VariableDeclaration(it) => visitor.visit_variable_declaration(it),
|
||||
Declaration::FunctionDeclaration(it) => {
|
||||
let flags = None;
|
||||
let flags = ScopeFlags::Function;
|
||||
visitor.visit_function(it, flags)
|
||||
}
|
||||
Declaration::ClassDeclaration(it) => visitor.visit_class(it),
|
||||
|
|
@ -4119,7 +4115,7 @@ pub mod walk {
|
|||
) {
|
||||
match it {
|
||||
ExportDefaultDeclarationKind::FunctionDeclaration(it) => {
|
||||
let flags = None;
|
||||
let flags = ScopeFlags::Function;
|
||||
visitor.visit_function(it, flags)
|
||||
}
|
||||
ExportDefaultDeclarationKind::ClassDeclaration(it) => visitor.visit_class(it),
|
||||
|
|
|
|||
|
|
@ -831,7 +831,7 @@ pub trait VisitMut<'a>: Sized {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_function(&mut self, it: &mut Function<'a>, flags: Option<ScopeFlags>) {
|
||||
fn visit_function(&mut self, it: &mut Function<'a>, flags: ScopeFlags) {
|
||||
walk_function(self, it, flags);
|
||||
}
|
||||
|
||||
|
|
@ -1516,7 +1516,7 @@ pub mod walk_mut {
|
|||
Expression::ClassExpression(it) => visitor.visit_class(it),
|
||||
Expression::ConditionalExpression(it) => visitor.visit_conditional_expression(it),
|
||||
Expression::FunctionExpression(it) => {
|
||||
let flags = None;
|
||||
let flags = ScopeFlags::Function;
|
||||
visitor.visit_function(it, flags)
|
||||
}
|
||||
Expression::ImportExpression(it) => visitor.visit_import_expression(it),
|
||||
|
|
@ -3150,12 +3150,12 @@ pub mod walk_mut {
|
|||
visitor.visit_decorators(&mut it.decorators);
|
||||
visitor.visit_property_key(&mut it.key);
|
||||
{
|
||||
let flags = Some(match it.kind {
|
||||
MethodDefinitionKind::Get => ScopeFlags::GetAccessor,
|
||||
MethodDefinitionKind::Set => ScopeFlags::SetAccessor,
|
||||
MethodDefinitionKind::Constructor => ScopeFlags::Constructor,
|
||||
MethodDefinitionKind::Method => ScopeFlags::empty(),
|
||||
});
|
||||
let flags = match it.kind {
|
||||
MethodDefinitionKind::Get => ScopeFlags::Function | ScopeFlags::GetAccessor,
|
||||
MethodDefinitionKind::Set => ScopeFlags::Function | ScopeFlags::SetAccessor,
|
||||
MethodDefinitionKind::Constructor => ScopeFlags::Function | ScopeFlags::Constructor,
|
||||
MethodDefinitionKind::Method => ScopeFlags::Function,
|
||||
};
|
||||
visitor.visit_function(&mut it.value, flags);
|
||||
}
|
||||
visitor.leave_node(kind);
|
||||
|
|
@ -3164,13 +3164,13 @@ pub mod walk_mut {
|
|||
pub fn walk_function<'a, V: VisitMut<'a>>(
|
||||
visitor: &mut V,
|
||||
it: &mut Function<'a>,
|
||||
flags: Option<ScopeFlags>,
|
||||
flags: ScopeFlags,
|
||||
) {
|
||||
let kind = AstType::Function;
|
||||
visitor.enter_node(kind);
|
||||
visitor.enter_scope(
|
||||
{
|
||||
let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function;
|
||||
let mut flags = flags;
|
||||
if it.is_strict() {
|
||||
flags |= ScopeFlags::StrictMode;
|
||||
}
|
||||
|
|
@ -3946,7 +3946,7 @@ pub mod walk_mut {
|
|||
match it {
|
||||
Declaration::VariableDeclaration(it) => visitor.visit_variable_declaration(it),
|
||||
Declaration::FunctionDeclaration(it) => {
|
||||
let flags = None;
|
||||
let flags = ScopeFlags::Function;
|
||||
visitor.visit_function(it, flags)
|
||||
}
|
||||
Declaration::ClassDeclaration(it) => visitor.visit_class(it),
|
||||
|
|
@ -4357,7 +4357,7 @@ pub mod walk_mut {
|
|||
) {
|
||||
match it {
|
||||
ExportDefaultDeclarationKind::FunctionDeclaration(it) => {
|
||||
let flags = None;
|
||||
let flags = ScopeFlags::Function;
|
||||
visitor.visit_function(it, flags)
|
||||
}
|
||||
ExportDefaultDeclarationKind::ClassDeclaration(it) => visitor.visit_class(it),
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ impl<'a> Visit<'a> for FunctionReturnType<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_function(&mut self, _func: &Function<'a>, _flags: Option<ScopeFlags>) {
|
||||
fn visit_function(&mut self, _func: &Function<'a>, _flags: ScopeFlags) {
|
||||
// We don't care about nested functions
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ impl<'a> Visit<'a> for ScopeTree<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_function(&mut self, func: &Function<'a>, flags: Option<ScopeFlags>) {
|
||||
fn visit_function(&mut self, func: &Function<'a>, flags: ScopeFlags) {
|
||||
walk_function(self, func, flags);
|
||||
if func.type_parameters.is_some() {
|
||||
self.leave_scope();
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ impl<'a> Visit<'a> for AwaitFinder {
|
|||
|
||||
fn visit_arrow_function_expression(&mut self, _expr: &ArrowFunctionExpression<'a>) {}
|
||||
|
||||
fn visit_function(&mut self, _func: &Function<'a>, _flags: Option<ScopeFlags>) {}
|
||||
fn visit_function(&mut self, _func: &Function<'a>, _flags: ScopeFlags) {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ impl<'a> Visit<'a> for KeepVar<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_function(&mut self, _it: &Function<'a>, _flags: Option<ScopeFlags>) {
|
||||
fn visit_function(&mut self, _it: &Function<'a>, _flags: ScopeFlags) {
|
||||
/* skip functions */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ struct CountASTNodes {
|
|||
}
|
||||
|
||||
impl<'a> Visit<'a> for CountASTNodes {
|
||||
fn visit_function(&mut self, func: &Function<'a>, flags: Option<ScopeFlags>) {
|
||||
fn visit_function(&mut self, func: &Function<'a>, flags: ScopeFlags) {
|
||||
self.functions += 1;
|
||||
walk::walk_function(self, func, flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1441,7 +1441,7 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
self.leave_node(kind);
|
||||
}
|
||||
|
||||
fn visit_function(&mut self, func: &Function<'a>, flags: Option<ScopeFlags>) {
|
||||
fn visit_function(&mut self, func: &Function<'a>, flags: ScopeFlags) {
|
||||
/* cfg */
|
||||
let (before_function_graph_ix, error_harness, function_graph_ix) =
|
||||
control_flow!(self, |cfg| {
|
||||
|
|
@ -1460,7 +1460,7 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
self.enter_node(kind);
|
||||
self.enter_scope(
|
||||
{
|
||||
let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function;
|
||||
let mut flags = flags;
|
||||
if func.is_strict() {
|
||||
flags |= ScopeFlags::StrictMode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -549,7 +549,7 @@ impl<'a> Visit<'a> for ChildScopeCollector {
|
|||
self.scope_ids.push(clause.scope_id.get().unwrap());
|
||||
}
|
||||
|
||||
fn visit_function(&mut self, func: &Function<'a>, _flags: Option<ScopeFlags>) {
|
||||
fn visit_function(&mut self, func: &Function<'a>, _flags: ScopeFlags) {
|
||||
self.scope_ids.push(func.scope_id.get().unwrap());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ impl<'a> VisitBuilder<'a> {
|
|||
|
||||
let as_param_type = self.with_ref_pat(&as_type);
|
||||
let (extra_params, extra_args) = if ident == "Function" {
|
||||
(quote!(, flags: Option<ScopeFlags>,), quote!(, flags))
|
||||
(quote!(, flags: ScopeFlags,), quote!(, flags))
|
||||
} else {
|
||||
(TokenStream::default(), TokenStream::default())
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue