Skip to content

Commit

Permalink
refactor(ast): use = syntax for #[scope] attrs
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Feb 3, 2025
1 parent 00d3f39 commit de94780
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 36 deletions.
18 changes: 9 additions & 9 deletions crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use super::{macros::inherit_variants, *};
/// Represents the root of a JavaScript abstract syntax tree (AST), containing metadata about the source, directives, top-level statements, and scope information.
#[ast(visit)]
#[scope(
flags(ScopeFlags::Top),
strict_if(self.source_type.is_strict() || self.has_use_strict_directive()),
flags = ScopeFlags::Top,
strict_if = self.source_type.is_strict() || self.has_use_strict_directive(),
)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)]
Expand Down Expand Up @@ -1365,7 +1365,7 @@ pub struct TryStatement<'a> {
/// }
/// ```
#[ast(visit)]
#[scope(flags(ScopeFlags::CatchClause))]
#[scope(flags = ScopeFlags::CatchClause)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)]
pub struct CatchClause<'a> {
Expand Down Expand Up @@ -1546,8 +1546,8 @@ pub struct BindingRestElement<'a> {
#[ast(visit)]
#[scope(
// `flags` passed in to visitor via parameter defined by `#[visit(args(flags = ...))]` on parents
flags(flags),
strict_if(self.has_use_strict_directive()),
flags = flags,
strict_if = self.has_use_strict_directive(),
)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)]
Expand Down Expand Up @@ -1679,8 +1679,8 @@ pub struct FunctionBody<'a> {
/// Arrow Function Definitions
#[ast(visit)]
#[scope(
flags(ScopeFlags::Function | ScopeFlags::Arrow),
strict_if(self.has_use_strict_directive()),
flags = ScopeFlags::Function | ScopeFlags::Arrow,
strict_if = self.has_use_strict_directive(),
)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)]
Expand Down Expand Up @@ -1711,7 +1711,7 @@ pub struct YieldExpression<'a> {

/// Class Definitions
#[ast(visit)]
#[scope(flags(ScopeFlags::StrictMode))]
#[scope(flags = ScopeFlags::StrictMode)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)]
pub struct Class<'a> {
Expand Down Expand Up @@ -2025,7 +2025,7 @@ pub struct PrivateIdentifier<'a> {
/// }
/// ```
#[ast(visit)]
#[scope(flags(ScopeFlags::ClassStaticBlock))]
#[scope(flags = ScopeFlags::ClassStaticBlock)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)]
pub struct StaticBlock<'a> {
Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_ast/src/ast/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,8 +1119,8 @@ pub enum TSTypePredicateName<'a> {
/// * [TypeScript Handbook - Global Augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation)
#[ast(visit)]
#[scope(
flags(ScopeFlags::TsModuleBlock),
strict_if(self.body.as_ref().is_some_and(TSModuleDeclarationBody::has_use_strict_directive)),
flags = ScopeFlags::TsModuleBlock,
strict_if = self.body.as_ref().is_some_and(TSModuleDeclarationBody::has_use_strict_directive),
)]
#[derive(Debug)]
#[generate_derive(CloneIn, GetSpan, GetSpanMut, ContentEq, ESTree)]
Expand Down
13 changes: 8 additions & 5 deletions crates/oxc_traverse/scripts/lib/parse.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -325,32 +325,35 @@ function parseScopeArgsStr(argsStr, args, position) {

try {
while (true) {
const [keyRaw] = matchAndConsume(/^([a-z_]+)\(/);
const [keyRaw] = matchAndConsume(/^([a-z_]+) *= */);
const key = SCOPE_ARGS_KEYS[keyRaw];
position.assert(key, `Unexpected scope macro arg: ${key}`);

let bracketCount = 1,
let bracketCount = 0,
index = 0;
for (; index < argsStr.length; index++) {
const char = argsStr[index];
if (char === '(') {
bracketCount++;
} else if (char === ')') {
bracketCount--;
if (bracketCount === 0) break;
} else if (char === ',' && bracketCount === 0) {
break;
}
}
position.assert(bracketCount === 0);

args[key] = argsStr.slice(0, index).trim();
argsStr = argsStr.slice(index + 1);
argsStr = argsStr.slice(index);
if (argsStr === '') break;

matchAndConsume(/^ ?, ?/);
matchAndConsume(/^\s*,\s*/);
}
} catch (err) {
position.throw(`Cannot parse scope args: '${argsStr}': ${err?.message || 'Unknown error'}`);
}

console.log(args);

return args;
}
27 changes: 7 additions & 20 deletions tasks/ast_tools/src/generators/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use cow_utils::CowUtils;
use oxc_index::IndexVec;
use proc_macro2::TokenStream;
use quote::{format_ident, quote, ToTokens};
use syn::{parse_str, punctuated::Punctuated, token::Comma, Expr, Ident, Meta, MetaList};
use syn::{parse_str, punctuated::Punctuated, token::Comma, Expr, Ident, Meta};

use crate::{
output::{output_path, Output},
Expand Down Expand Up @@ -122,33 +122,20 @@ fn parse_scope_attr(location: AttrLocation, part: AttrPart) -> Result<()> {
}))
}

fn parse_list(meta_list: &MetaList) -> Result<String> {
let exprs = meta_list
.parse_args_with(Punctuated::<Expr, Comma>::parse_terminated)
.map_err(|_| ())?;
if exprs.len() == 1 {
Ok(exprs.first().unwrap().to_token_stream().to_string())
} else {
Err(())
}
}

match (part, location) {
// `#[scope]` on struct
(AttrPart::None, AttrLocation::Struct(struct_def)) => {
get_or_create_scope(struct_def)?;
}
// `#[scope(flags(...))` on struct
(AttrPart::List("flags", meta_list), AttrLocation::Struct(struct_def)) => {
// TODO: Make syntax `#[scope(flags = ...)]`, so can use `AttrPart::String` instead of parsing here
// `#[scope(flags = ...)` on struct
(AttrPart::String("flags", value), AttrLocation::Struct(struct_def)) => {
let scope = get_or_create_scope(struct_def)?;
scope.flags = parse_list(meta_list)?;
scope.flags = value;
}
// `#[scope(strict_if(...))` on struct
(AttrPart::List("strict_if", meta_list), AttrLocation::Struct(struct_def)) => {
// TODO: Make syntax `#[scope(strict_if = ...)]`, so can use `AttrPart::String` instead of parsing here
// `#[scope(strict_if = ...)` on struct
(AttrPart::String("strict_if", value), AttrLocation::Struct(struct_def)) => {
let scope = get_or_create_scope(struct_def)?;
scope.strict_if = Some(parse_list(meta_list)?);
scope.strict_if = Some(value);
}
// `#[scope(enter_before)]` on struct field
(AttrPart::Tag("enter_before"), AttrLocation::StructField(struct_def, field_index)) => {
Expand Down

0 comments on commit de94780

Please sign in to comment.