diff --git a/full-moon-derive/src/node.rs b/full-moon-derive/src/node.rs index 151784df..5b8beafe 100644 --- a/full-moon-derive/src/node.rs +++ b/full-moon-derive/src/node.rs @@ -30,21 +30,6 @@ fn token_getter( } } -#[derive(PartialEq)] -enum NodeHint { - FullRange, -} - -impl Hint for NodeHint { - fn unit(name: String) -> Option<Self> { - if name == "full_range" { - Some(NodeHint::FullRange) - } else { - None - } - } -} - pub struct NodeGenerator; impl DeriveGenerator for NodeGenerator { @@ -122,41 +107,29 @@ impl StructGenerator for StructRangeGenerator { .map(|field| field.ident.as_ref().unwrap()) .collect::<Vec<_>>(); - let full_range = strukt - .fields - .iter() - .find(|field| search_hint("node", &field.attrs) == Some(NodeHint::FullRange)); - - if let Some(full_range) = full_range { - let ident = full_range.ident.as_ref().unwrap(); - quote! { - self.#ident.range() - } - } else { - let (mut start_position, mut end_position) = ( - Vec::with_capacity(fields.len()), - Vec::with_capacity(fields.len()), - ); + let (mut start_position, mut end_position) = ( + Vec::with_capacity(fields.len()), + Vec::with_capacity(fields.len()), + ); - for field in &fields { - start_position.push(quote! { - .or_else(|| { - self.#field.start_position() - }) - }); - } + for field in &fields { + start_position.push(quote! { + .or_else(|| { + self.#field.start_position() + }) + }); + } - for field in fields.iter().rev() { - end_position.push(quote! { - .or_else(|| { - self.#field.end_position() - }) - }); - } + for field in fields.iter().rev() { + end_position.push(quote! { + .or_else(|| { + self.#field.end_position() + }) + }); + } - quote! { - Some((None#(#start_position)*?, None#(#end_position)*?)) - } + quote! { + Some((None#(#start_position)*?, None#(#end_position)*?)) } } } @@ -238,17 +211,7 @@ impl MatchEnumGenerator for EnumRangeGenerator { .map(|field| field.ident.as_ref().unwrap()) .collect::<Vec<_>>(); - let full_range = named - .named - .iter() - .find(|field| search_hint("node", &field.attrs) == Some(NodeHint::FullRange)); - - let body = if let Some(full_range) = full_range { - let ident = full_range.ident.as_ref().unwrap(); - quote! { - #ident.range() - } - } else { + let body = { let (mut start_position, mut end_position) = ( Vec::with_capacity(fields.len()), Vec::with_capacity(fields.len()), diff --git a/full-moon-derive/src/visit.rs b/full-moon-derive/src/visit.rs index ab671737..bf7cc523 100644 --- a/full-moon-derive/src/visit.rs +++ b/full-moon-derive/src/visit.rs @@ -1,7 +1,6 @@ use crate::derive::*; use proc_macro2::TokenStream; use quote::{format_ident, quote}; -use std::collections::HashMap; // Not 100% accurate, but it is to full-moon's codebase fn snake_case(pascal_case: &str) -> String { @@ -22,7 +21,6 @@ fn snake_case(pascal_case: &str) -> String { #[derive(Debug, PartialEq)] enum VisitHint { - Contains(String), Skip, SkipVisitSelf, VisitAs(String), @@ -32,8 +30,6 @@ impl Hint for VisitHint { fn key_value(key: String, value: String) -> Option<Self> { if key == "visit_as" { Some(VisitHint::VisitAs(value)) - } else if key == "contains" { - Some(VisitHint::Contains(value)) } else { None } @@ -53,7 +49,6 @@ pub struct VisitGenerator; impl VisitGenerator { fn visit_fields(data_fields: &syn::Fields, prefix: TokenStream) -> TokenStream { let mut fields = Vec::new(); - let mut contains = HashMap::new(); for field in data_fields .iter() @@ -62,28 +57,7 @@ impl VisitGenerator { let ident = field.ident.as_ref().unwrap(); let token_stream = quote! { #prefix#ident }; - if let Some(VisitHint::Contains(contains_node)) = search_hint("visit", &field.attrs) { - contains.insert(contains_node, ident); - } else if let Some(contains_me) = contains.remove(&ident.to_string()) { - fields.push(quote! { - #prefix#contains_me.tokens.0 - }); - - fields.push(token_stream); - - fields.push(quote! { - #prefix#contains_me.tokens.1 - }); - } else { - fields.push(token_stream); - } - } - - if !contains.is_empty() { - panic!( - "#[visit(contains = \"...\")] used in wrong order: {:?}", - contains - ); + fields.push(token_stream); } quote! { diff --git a/full-moon/src/ast/mod.rs b/full-moon/src/ast/mod.rs index 2f33925b..001133ac 100644 --- a/full-moon/src/ast/mod.rs +++ b/full-moon/src/ast/mod.rs @@ -29,9 +29,6 @@ pub mod types; #[cfg(feature = "roblox")] use types::*; -#[cfg(feature = "roblox")] -mod type_visitors; - #[cfg(feature = "lua52")] pub mod lua52; #[cfg(feature = "lua52")] @@ -156,24 +153,15 @@ impl Default for Return { } /// Fields of a [`TableConstructor`] -#[derive(Clone, Debug, Display, PartialEq, Node)] +#[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] pub enum Field { /// A key in the format of `[expression] = value` - #[display( - fmt = "{}{}{}{}{}", - "brackets.tokens().0", - "key", - "brackets.tokens().1", - "equal", - "value" - )] + #[display(fmt = "{}{}{}", "key", "equal", "value")] ExpressionKey { - /// The `[...]` part of `[expression] = value` - brackets: ContainedSpan, - /// The `expression` part of `[expression] = value` - key: Expression, + /// The `[expression]` part of `[expression] = value` + key: ContainedSpan<Expression>, /// The `=` part of `[expression] = value` equal: TokenReference, /// The `value` part of `[expression] = value` @@ -199,12 +187,9 @@ pub enum Field { /// A table being constructed, such as `{ 1, 2, 3 }` or `{ a = 1 }` #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{}{}", "braces.tokens().0", "fields", "braces.tokens().1")] +#[display(fmt = "{}", "fields")] pub struct TableConstructor { - #[node(full_range)] - #[visit(contains = "fields")] - braces: ContainedSpan, - fields: Punctuated<Field>, + fields: ContainedSpan<Punctuated<Field>>, } impl TableConstructor { @@ -212,32 +197,36 @@ impl TableConstructor { /// Brace tokens are followed by spaces, such that { `fields` } pub fn new() -> Self { Self { - braces: ContainedSpan::new( + fields: ContainedSpan::new( TokenReference::symbol("{ ").unwrap(), + Punctuated::new(), TokenReference::symbol(" }").unwrap(), ), - fields: Punctuated::new(), } } /// The braces of the constructor - pub fn braces(&self) -> &ContainedSpan { - &self.braces + pub fn braces(&self) -> (&TokenReference, &TokenReference) { + self.fields.tokens() } /// Returns the [`Punctuated`] sequence of the fields used to create the table pub fn fields(&self) -> &Punctuated<Field> { - &self.fields + self.fields.inner() } /// Returns a new TableConstructor with the given braces - pub fn with_braces(self, braces: ContainedSpan) -> Self { - Self { braces, ..self } + pub fn with_braces(self, braces: (TokenReference, TokenReference)) -> Self { + Self { + fields: self.fields.with_tokens(braces), + } } /// Returns a new TableConstructor with the given fields pub fn with_fields(self, fields: Punctuated<Field>) -> Self { - Self { fields, ..self } + Self { + fields: self.fields.with_inner(fields), + } } } @@ -248,7 +237,7 @@ impl Default for TableConstructor { } /// An expression, mostly useful for getting values -#[derive(Clone, Debug, Display, PartialEq, Node)] +#[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[cfg_attr(feature = "serde", serde(untagged))] #[non_exhaustive] @@ -265,19 +254,8 @@ pub enum Expression { }, /// A statement in parentheses, such as `(#list)` - #[display( - fmt = "{}{}{}", - "contained.tokens().0", - "expression", - "contained.tokens().1" - )] - Parentheses { - /// The parentheses of the `ParenExpression` - #[node(full_range)] - contained: ContainedSpan, - /// The expression inside the parentheses - expression: Box<Expression>, - }, + #[display(fmt = "{}", "_0")] + Parentheses(ContainedSpan<Box<Expression>>), /// A unary operation, such as `#list` #[display(fmt = "{}{}", "unop", "expression")] @@ -415,23 +393,14 @@ pub enum Prefix { /// The indexing of something, such as `x.y` or `x["y"]` /// Values of variants are the keys, such as `"y"` -#[derive(Clone, Debug, Display, PartialEq, Node)] +#[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] pub enum Index { /// Indexing in the form of `x["y"]` - #[display( - fmt = "{}{}{}", - "brackets.tokens().0", - "expression", - "brackets.tokens().1" - )] - Brackets { - /// The `[...]` part of `["y"]` - brackets: ContainedSpan, - /// The `"y"` part of `["y"]` - expression: Expression, - }, + /// The `["y"]` part of the index. + #[display(fmt = "{}", "_0")] + Brackets(ContainedSpan<Expression>), /// Indexing in the form of `x.y` #[display(fmt = "{}{}", "dot", "name")] @@ -444,24 +413,13 @@ pub enum Index { } /// Arguments used for a function -#[derive(Clone, Debug, Display, PartialEq, Node)] +#[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] pub enum FunctionArgs { /// Used when a function is called in the form of `call(1, 2, 3)` - #[display( - fmt = "{}{}{}", - "parentheses.tokens().0", - "arguments", - "parentheses.tokens().1" - )] - Parentheses { - /// The `(...) part of (1, 2, 3)` - #[node(full_range)] - parentheses: ContainedSpan, - /// The `1, 2, 3` part of `1, 2, 3` - arguments: Punctuated<Expression>, - }, + #[display(fmt = "{}", "_0")] + Parentheses(ContainedSpan<Punctuated<Expression>>), /// Used when a function is called in the form of `call "foobar"` #[display(fmt = "{}", "_0")] String(TokenReference), @@ -1266,8 +1224,7 @@ pub enum Call { #[derive(Clone, Debug, PartialEq, Node)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub struct FunctionBody { - parameters_parentheses: ContainedSpan, - parameters: Punctuated<Parameter>, + parameters: ContainedSpan<Punctuated<Parameter>>, #[cfg(feature = "roblox")] type_specifiers: Vec<Option<TypeSpecifier>>, @@ -1284,11 +1241,11 @@ impl FunctionBody { /// Returns a new empty FunctionBody pub fn new() -> Self { Self { - parameters_parentheses: ContainedSpan::new( + parameters: ContainedSpan::new( TokenReference::symbol("(").unwrap(), + Punctuated::new(), TokenReference::symbol(")").unwrap(), ), - parameters: Punctuated::new(), #[cfg(feature = "roblox")] type_specifiers: Vec::new(), @@ -1302,13 +1259,13 @@ impl FunctionBody { } /// The parentheses of the parameters - pub fn parameters_parentheses(&self) -> &ContainedSpan { - &self.parameters_parentheses + pub fn parameters_parentheses(&self) -> (&TokenReference, &TokenReference) { + self.parameters.tokens() } /// Returns the [`Punctuated`] sequence of the parameters for the function declaration pub fn parameters(&self) -> &Punctuated<Parameter> { - &self.parameters + self.parameters.inner() } /// The code of a function body @@ -1337,16 +1294,8 @@ impl FunctionBody { self.return_type.as_ref() } - /// Returns a new FunctionBody with the given parentheses for the parameters - pub fn with_parameters_parentheses(self, parameters_parentheses: ContainedSpan) -> Self { - Self { - parameters_parentheses, - ..self - } - } - /// Returns a new FunctionBody with the given parameters - pub fn with_parameters(self, parameters: Punctuated<Parameter>) -> Self { + pub fn with_parameters(self, parameters: ContainedSpan<Punctuated<Parameter>>) -> Self { Self { parameters, ..self } } @@ -1391,9 +1340,9 @@ impl fmt::Display for FunctionBody { write!( formatter, "{}{}{}{}{}{}", - self.parameters_parentheses.tokens().0, - join_type_specifiers(&self.parameters, self.type_specifiers()), - self.parameters_parentheses.tokens().1, + self.parameters.start, + join_type_specifiers(self.parameters.inner(), self.type_specifiers()), + self.parameters.end, display_option(self.return_type.as_ref()), self.block, self.end_token @@ -1404,12 +1353,8 @@ impl fmt::Display for FunctionBody { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!( formatter, - "{}{}{}{}{}", - self.parameters_parentheses.tokens().0, - self.parameters, - self.parameters_parentheses.tokens().1, - self.block, - self.end_token + "{}{}{}", + self.parameters, self.block, self.end_token ) } } @@ -1838,13 +1783,11 @@ impl FunctionCall { FunctionCall { prefix, suffixes: vec![Suffix::Call(Call::AnonymousCall( - FunctionArgs::Parentheses { - arguments: Punctuated::new(), - parentheses: ContainedSpan::new( - TokenReference::symbol("(").unwrap(), - TokenReference::symbol(")").unwrap(), - ), - }, + FunctionArgs::Parentheses(ContainedSpan::new( + TokenReference::symbol("(").unwrap(), + Punctuated::new(), + TokenReference::symbol(")").unwrap(), + )), ))], } } @@ -2378,10 +2321,11 @@ mod tests { LocalFunction::new(token.clone()); MethodCall::new( token.clone(), - FunctionArgs::Parentheses { - arguments: Punctuated::new(), - parentheses: ContainedSpan::new(token.clone(), token.clone()), - }, + FunctionArgs::Parentheses(ContainedSpan::new( + token.clone(), + Punctuated::new(), + token.clone(), + )), ); NumericFor::new(token.clone(), expression.clone(), expression.clone()); Repeat::new(expression.clone()); diff --git a/full-moon/src/ast/parsers.rs b/full-moon/src/ast/parsers.rs index af426466..3e8914a3 100644 --- a/full-moon/src/ast/parsers.rs +++ b/full-moon/src/ast/parsers.rs @@ -154,8 +154,7 @@ define_parser!(ParseField, Field, |_, state| { return Ok(( state, Field::ExpressionKey { - brackets: ContainedSpan::new(start_bracket, end_bracket), - key, + key: ContainedSpan::new(start_bracket, key, end_bracket), equal, value, }, @@ -210,8 +209,7 @@ define_parser!(ParseTableConstructor, TableConstructor, |_, state| { Ok(( state, TableConstructor { - braces: ContainedSpan::new(start_brace, end_brace), - fields, + fields: ContainedSpan::new(start_brace, fields, end_brace), }, )) }); @@ -244,10 +242,11 @@ define_parser!(ParseParenExpression, Expression, |_, state| { Ok(( state, - Expression::Parentheses { - contained: ContainedSpan::new(left_paren, right_paren), - expression: Box::new(expression), - }, + Expression::Parentheses(ContainedSpan::new( + left_paren, + Box::new(expression), + right_paren, + )), )) }); @@ -410,10 +409,7 @@ define_parser!( ); Ok(( state, - Index::Brackets { - brackets: ContainedSpan::new(start_bracket, end_bracket), - expression, - }, + Index::Brackets(ContainedSpan::new(start_bracket, expression, end_bracket)), )) } else if let Ok((state, dot)) = ParseSymbol(Symbol::Dot).parse(state) { let (state, name) = expect!(state, ParseIdentifier.parse(state), "expected name"); @@ -443,10 +439,7 @@ define_parser!( ); Ok(( state, - FunctionArgs::Parentheses { - arguments, - parentheses: ContainedSpan::new(left_paren, right_paren), - }, + FunctionArgs::Parentheses(ContainedSpan::new(left_paren, arguments, right_paren)), )) } else if let Ok((state, table_constructor)) = keep_going!(ParseTableConstructor.parse(state)) { Ok((state, FunctionArgs::TableConstructor(table_constructor))) @@ -836,8 +829,7 @@ define_parser!(ParseFunctionBody, FunctionBody, |_, state| { Ok(( state, FunctionBody { - parameters_parentheses: ContainedSpan::new(start_parenthese, end_parenthese), - parameters, + parameters: ContainedSpan::new(start_parenthese, parameters, end_parenthese), block, end_token, #[cfg(feature = "roblox")] @@ -1173,8 +1165,7 @@ define_roblox_parser!( Ok(( state, GenericDeclaration { - arrows: ContainedSpan::new(start_arrow, end_arrow), - generics, + generics: ContainedSpan::new(start_arrow, generics, end_arrow), }, )) } @@ -1299,8 +1290,7 @@ cfg_if::cfg_if! { state, IndexedTypeInfo::Generic { base: identifier, - arrows: ContainedSpan::new(start_arrow, end_arrow), - generics, + generics: ContainedSpan::new(start_arrow, generics, end_arrow), }, ) } else { @@ -1326,10 +1316,7 @@ cfg_if::cfg_if! { let mut types = Punctuated::new(); types.push(Pair::new(type_info, None)); - Ok((state, TypeInfo::Tuple { - parentheses: ContainedSpan::new(this.0.clone(), end_parenthese), - types, - })) + Ok((state, TypeInfo::Tuple (ContainedSpan::new(this.0.clone(), types, end_parenthese)))) }); #[derive(Clone, Debug, PartialEq)] @@ -1388,8 +1375,7 @@ cfg_if::cfg_if! { Ok(( state, TypeInfo::Callback { - arguments: types, - parentheses: ContainedSpan::new(this.0.clone(), end_parenthese), + arguments: ContainedSpan::new(this.0.clone(), types, end_parenthese), arrow, return_type: Box::new(return_value), }, @@ -1428,8 +1414,7 @@ cfg_if::cfg_if! { state, TypeInfo::Typeof { typeof_token: identifier, - parentheses: ContainedSpan::new(start_parenthese, end_parenthese), - inner: Box::new(expression), + expression: ContainedSpan::new(start_parenthese, Box::new(expression), end_parenthese), }, ) } else if let Ok((state, punctuation)) = ParseSymbol(Symbol::Dot).parse(state) @@ -1466,8 +1451,7 @@ cfg_if::cfg_if! { state, TypeInfo::Generic { base: identifier, - arrows: ContainedSpan::new(start_arrow, end_arrow), - generics, + generics: ContainedSpan::new(start_arrow, generics, end_arrow), }, ) } else { @@ -1480,16 +1464,16 @@ cfg_if::cfg_if! { // Single token lookahead: see if we have a `->` ahead. If we do, we need to parse this // as a callback type, using what we already have from the parentheses type if let Ok((state, arrow)) = ParseSymbol(Symbol::ThinArrow).parse(state) { - // Unwrap the parsed parentheses type into its parentheses and its enclosed type - let (parentheses, arguments) = match parentheses_type { - TypeInfo::Tuple { parentheses, types } => { - // `types` is currently `Punctuated<TypeInfo>`, but we need to map it to `Punctuated<TypeArgument>` + let arguments = match parentheses_type { + TypeInfo::Tuple (types) => { + // `types.inner()` is currently `Punctuated<TypeInfo>`, but we need to map it to `Punctuated<TypeArgument>` // where each argument has no name. - let arguments = types.into_pairs().map(|pair| pair.map(|type_info| TypeArgument { + let arguments = types.inner.into_pairs().map(|pair| pair.map(|type_info| TypeArgument { name: None, type_info })).collect::<Punctuated<_>>(); - (parentheses, arguments) + + ContainedSpan::new(types.start, arguments, types.end) }, _ => unreachable!("parsed a non-tuple as a parentheses type"), }; @@ -1504,7 +1488,6 @@ cfg_if::cfg_if! { state, TypeInfo::Callback { arguments, - parentheses, arrow, return_type: Box::new(return_value), }, @@ -1527,10 +1510,7 @@ cfg_if::cfg_if! { ( state, - TypeInfo::Table { - braces: ContainedSpan::new(start_brace, end_brace), - fields, - }, + TypeInfo::Table (ContainedSpan::new(start_brace, fields, end_brace)) ) } else { let (state, type_info) = expect!( @@ -1547,10 +1527,7 @@ cfg_if::cfg_if! { ( state, - TypeInfo::Array { - braces: ContainedSpan::new(start_brace, end_brace), - type_info: Box::new(type_info) - }, + TypeInfo::Array (ContainedSpan::new(start_brace, Box::new(type_info), end_brace)) ) } } else if matches!(this.0, TypeInfoContext::ParenthesesType | TypeInfoContext::ReturnType) { @@ -1620,8 +1597,7 @@ cfg_if::cfg_if! { Ok(( state, TypeInfo::Callback { - arguments, - parentheses: ContainedSpan::new(start_parenthese, end_parenthese), + arguments: ContainedSpan::new(start_parenthese, arguments, end_parenthese), arrow, return_type: Box::new(return_value), }, @@ -1629,10 +1605,7 @@ cfg_if::cfg_if! { } else { Ok(( state, - TypeInfo::Tuple { - parentheses: ContainedSpan::new(start_parenthese, end_parenthese), - types, - }, + TypeInfo::Tuple (ContainedSpan::new(start_parenthese, types, end_parenthese)) )) } } else { @@ -1744,10 +1717,7 @@ cfg_if::cfg_if! { Ok(( state, - TypeFieldKey::IndexSignature { - brackets: ContainedSpan::new(start_bracket, end_bracket), - inner, - }, + TypeFieldKey::IndexSignature (ContainedSpan::new(start_bracket, inner, end_bracket)) )) } else { Err(InternalAstError::NoMatch) diff --git a/full-moon/src/ast/span.rs b/full-moon/src/ast/span.rs index 4b9fd05e..9443631d 100644 --- a/full-moon/src/ast/span.rs +++ b/full-moon/src/ast/span.rs @@ -7,53 +7,98 @@ //! //! Contained spans don't contain the inner data, just the start and end bounds. use crate::{ - node::{Node, Tokens}, + node::{Node, TokenItem, Tokens}, private::Sealed, tokenizer::{Position, TokenReference}, + visitors::{Visit, VisitMut, Visitor, VisitorMut}, }; -use full_moon_derive::Visit; +use derive_more::Display; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; /// A contained span with the beginning and ending bounds. /// Refer to the [module documentation](index.html) for more details. -#[derive(Clone, Debug, PartialEq, Visit)] +#[derive(Clone, Debug, Display, PartialEq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -pub struct ContainedSpan { - pub(crate) tokens: (TokenReference, TokenReference), +#[display(fmt = "{}{}{}", "start", "inner", "end")] +pub struct ContainedSpan<T> { + pub(crate) start: TokenReference, + pub(crate) inner: T, + pub(crate) end: TokenReference, } -impl ContainedSpan { +impl<T> ContainedSpan<T> { /// Creates a contained span from the start and end bounds - pub fn new(start: TokenReference, end: TokenReference) -> Self { - Self { - tokens: (start, end), - } + pub fn new(start: TokenReference, inner: T, end: TokenReference) -> Self { + Self { start, inner, end } } /// Returns the start and end bounds in a tuple as references pub fn tokens(&self) -> (&TokenReference, &TokenReference) { - (&self.tokens.0, &self.tokens.1) + (&self.start, &self.end) + } + + /// Returns the node contained within the ContainedSpan + pub fn inner(&self) -> &T { + &self.inner + } + + /// Creates a new ContainedSpan with the given containing tokens + pub fn with_tokens(self, tokens: (TokenReference, TokenReference)) -> Self { + Self { + start: tokens.0, + end: tokens.1, + ..self + } + } + + /// Creates a new ContainedSpan with the given node contained within it + pub fn with_inner(self, inner: T) -> Self { + Self { inner, ..self } } } -impl Node for ContainedSpan { +impl<T: Node> Node for ContainedSpan<T> { fn start_position(&self) -> Option<Position> { - self.tokens.0.start_position() + self.start.start_position() } fn end_position(&self) -> Option<Position> { - self.tokens.1.end_position() + self.end.end_position() } fn similar(&self, other: &Self) -> bool { - self.tokens.0.similar(&other.tokens.0) && self.tokens.1.similar(&other.tokens.1) + self.start.similar(&other.start) + && self.end.similar(&other.end) + && self.inner.similar(&other.inner) } fn tokens(&self) -> Tokens { - self.tokens.tokens() + let mut items = self.start.tokens().items; + items.append(&mut self.inner.tokens().items); + items.push(TokenItem::TokenReference(&self.end)); + + Tokens { items } } } -impl Sealed for ContainedSpan {} +impl<T> Sealed for ContainedSpan<T> {} + +impl<T: Visit> Visit for ContainedSpan<T> { + fn visit<V: Visitor>(&self, visitor: &mut V) { + self.start.visit(visitor); + self.inner.visit(visitor); + self.end.visit(visitor); + } +} + +impl<T: VisitMut> VisitMut for ContainedSpan<T> { + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self { + ContainedSpan { + start: self.start.visit_mut(visitor), + inner: self.inner.visit_mut(visitor), + end: self.end.visit_mut(visitor), + } + } +} diff --git a/full-moon/src/ast/type_visitors.rs b/full-moon/src/ast/type_visitors.rs deleted file mode 100644 index c3407c45..00000000 --- a/full-moon/src/ast/type_visitors.rs +++ /dev/null @@ -1,331 +0,0 @@ -// Implementations of Visit and VisitMut that are not able to be automatically derived yet. -// Ideally everything would be derived. -use super::*; -use crate::visitors::{Visit, VisitMut, Visitor, VisitorMut}; - -// The following have `ContainedSpan`, which when automatically derived will visit the tokens containing -// before they visit what they're actually containing. -// For example, if there is an AST node that represents `(foo)`... -// Then visitors will visit this as `()foo`. -// This is fixed for structs with `#[visit(contains = "...")], but this is not supported on enums. -impl Visit for TypeInfo { - fn visit<V: Visitor>(&self, visitor: &mut V) { - visitor.visit_type_info(self); - match self { - TypeInfo::Array { braces, type_info } => { - braces.tokens.0.visit(visitor); - type_info.visit(visitor); - braces.tokens.1.visit(visitor); - } - TypeInfo::Basic(__self_0) => { - __self_0.visit(visitor); - } - TypeInfo::Callback { - parentheses, - arguments, - arrow, - return_type, - } => { - parentheses.tokens.0.visit(visitor); - arguments.visit(visitor); - parentheses.tokens.1.visit(visitor); - arrow.visit(visitor); - return_type.visit(visitor); - } - TypeInfo::Generic { - base, - arrows, - generics, - } => { - base.visit(visitor); - arrows.tokens.0.visit(visitor); - generics.visit(visitor); - arrows.tokens.1.visit(visitor); - } - TypeInfo::Module { - module, - punctuation, - type_info, - } => { - module.visit(visitor); - punctuation.visit(visitor); - type_info.visit(visitor); - } - TypeInfo::Optional { - base, - question_mark, - } => { - base.visit(visitor); - question_mark.visit(visitor); - } - TypeInfo::Table { braces, fields } => { - braces.tokens.0.visit(visitor); - fields.visit(visitor); - braces.tokens.1.visit(visitor); - } - TypeInfo::Typeof { - typeof_token, - parentheses, - inner, - } => { - typeof_token.visit(visitor); - parentheses.tokens.0.visit(visitor); - inner.visit(visitor); - parentheses.tokens.1.visit(visitor); - } - TypeInfo::Tuple { parentheses, types } => { - parentheses.tokens.0.visit(visitor); - types.visit(visitor); - parentheses.tokens.1.visit(visitor); - } - TypeInfo::Union { left, pipe, right } => { - left.visit(visitor); - pipe.visit(visitor); - right.visit(visitor); - } - TypeInfo::Intersection { - left, - ampersand, - right, - } => { - left.visit(visitor); - ampersand.visit(visitor); - right.visit(visitor); - } - TypeInfo::Variadic { ellipse, type_info } => { - ellipse.visit(visitor); - type_info.visit(visitor); - } - }; - visitor.visit_type_info_end(self); - } -} - -impl VisitMut for TypeInfo { - fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { - self = visitor.visit_type_info(self); - self = match self { - TypeInfo::Array { - mut braces, - mut type_info, - } => { - braces.tokens.0 = braces.tokens.0.visit_mut(visitor); - type_info = type_info.visit_mut(visitor); - braces.tokens.1 = braces.tokens.1.visit_mut(visitor); - - TypeInfo::Array { braces, type_info } - } - TypeInfo::Basic(__self_0) => TypeInfo::Basic(__self_0.visit_mut(visitor)), - TypeInfo::Callback { - mut parentheses, - mut arguments, - mut arrow, - mut return_type, - } => { - parentheses.tokens.0 = parentheses.tokens.0.visit_mut(visitor); - arguments = arguments.visit_mut(visitor); - parentheses.tokens.1 = parentheses.tokens.1.visit_mut(visitor); - arrow = arrow.visit_mut(visitor); - return_type = return_type.visit_mut(visitor); - - TypeInfo::Callback { - parentheses, - arguments, - arrow, - return_type, - } - } - - TypeInfo::Generic { - mut base, - mut arrows, - mut generics, - } => { - base = base.visit_mut(visitor); - arrows.tokens.0 = arrows.tokens.0.visit_mut(visitor); - generics = generics.visit_mut(visitor); - arrows.tokens.1 = arrows.tokens.1.visit_mut(visitor); - - TypeInfo::Generic { - arrows, - base, - generics, - } - } - - TypeInfo::Module { - mut module, - mut punctuation, - mut type_info, - } => { - module = module.visit_mut(visitor); - punctuation = punctuation.visit_mut(visitor); - type_info = type_info.visit_mut(visitor); - - TypeInfo::Module { - module, - punctuation, - type_info, - } - } - - TypeInfo::Optional { - base, - question_mark, - } => TypeInfo::Optional { - base: base.visit_mut(visitor), - question_mark: question_mark.visit_mut(visitor), - }, - - TypeInfo::Table { - mut braces, - mut fields, - } => { - braces.tokens.0 = braces.tokens.0.visit_mut(visitor); - fields = fields.visit_mut(visitor); - braces.tokens.1 = braces.tokens.1.visit_mut(visitor); - - TypeInfo::Table { braces, fields } - } - - TypeInfo::Typeof { - mut typeof_token, - mut parentheses, - mut inner, - } => { - typeof_token = typeof_token.visit_mut(visitor); - parentheses.tokens.0 = parentheses.tokens.0.visit_mut(visitor); - inner = inner.visit_mut(visitor); - parentheses.tokens.1 = parentheses.tokens.1.visit_mut(visitor); - - TypeInfo::Typeof { - typeof_token, - parentheses, - inner, - } - } - - TypeInfo::Tuple { - mut parentheses, - mut types, - } => { - parentheses.tokens.0 = parentheses.tokens.0.visit_mut(visitor); - types = types.visit_mut(visitor); - parentheses.tokens.1 = parentheses.tokens.1.visit_mut(visitor); - - TypeInfo::Tuple { parentheses, types } - } - - TypeInfo::Union { left, pipe, right } => TypeInfo::Union { - left: left.visit_mut(visitor), - pipe: pipe.visit_mut(visitor), - right: right.visit_mut(visitor), - }, - - TypeInfo::Intersection { - left, - ampersand, - right, - } => TypeInfo::Intersection { - left: left.visit_mut(visitor), - ampersand: ampersand.visit_mut(visitor), - right: right.visit_mut(visitor), - }, - - TypeInfo::Variadic { ellipse, type_info } => TypeInfo::Variadic { - ellipse: ellipse.visit_mut(visitor), - type_info: type_info.visit_mut(visitor), - }, - }; - self = visitor.visit_type_info_end(self); - self - } -} - -impl Visit for IndexedTypeInfo { - fn visit<V: Visitor>(&self, visitor: &mut V) { - visitor.visit_indexed_type_info(self); - match self { - IndexedTypeInfo::Basic(__self_0) => { - __self_0.visit(visitor); - } - IndexedTypeInfo::Generic { - base, - arrows, - generics, - } => { - base.visit(visitor); - arrows.tokens.0.visit(visitor); - generics.visit(visitor); - arrows.tokens.1.visit(visitor); - } - }; - visitor.visit_indexed_type_info_end(self); - } -} - -impl VisitMut for IndexedTypeInfo { - fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { - self = visitor.visit_indexed_type_info(self); - self = match self { - IndexedTypeInfo::Basic(__self_0) => IndexedTypeInfo::Basic(__self_0.visit_mut(visitor)), - - IndexedTypeInfo::Generic { - mut base, - mut arrows, - mut generics, - } => { - base = base.visit_mut(visitor); - arrows.tokens.0 = arrows.tokens.0.visit_mut(visitor); - generics = generics.visit_mut(visitor); - arrows.tokens.1 = arrows.tokens.1.visit_mut(visitor); - - IndexedTypeInfo::Generic { - arrows, - base, - generics, - } - } - }; - self = visitor.visit_indexed_type_info_end(self); - self - } -} - -impl Visit for TypeFieldKey { - fn visit<V: Visitor>(&self, visitor: &mut V) { - visitor.visit_type_field_key(self); - match self { - TypeFieldKey::Name(__self_0) => { - __self_0.visit(visitor); - } - TypeFieldKey::IndexSignature { brackets, inner } => { - brackets.tokens.0.visit(visitor); - inner.visit(visitor); - brackets.tokens.1.visit(visitor); - } - }; - visitor.visit_type_field_key_end(self); - } -} - -impl VisitMut for TypeFieldKey { - fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { - self = visitor.visit_type_field_key(self); - self = match self { - TypeFieldKey::Name(__self_0) => TypeFieldKey::Name(__self_0.visit_mut(visitor)), - TypeFieldKey::IndexSignature { - mut brackets, - mut inner, - } => { - brackets.tokens.0 = brackets.tokens.0.visit_mut(visitor); - inner = inner.visit_mut(visitor); - brackets.tokens.1 = brackets.tokens.1.visit_mut(visitor); - - TypeFieldKey::IndexSignature { brackets, inner } - } - }; - self = visitor.visit_type_field_key_end(self); - self - } -} diff --git a/full-moon/src/ast/types.rs b/full-moon/src/ast/types.rs index 3328875e..11fc5ff6 100644 --- a/full-moon/src/ast/types.rs +++ b/full-moon/src/ast/types.rs @@ -5,37 +5,23 @@ use crate::{util::display_option, ShortString}; use derive_more::Display; /// Any type, such as `string`, `boolean?`, `number | boolean`, etc. -#[derive(Clone, Debug, Display, PartialEq, Node)] +#[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] pub enum TypeInfo { /// A shorthand type annotating the structure of an array: { number } - #[display(fmt = "{}{}{}", "braces.tokens().0", "type_info", "braces.tokens().1")] - Array { - /// The braces (`{}`) containing the type info. - braces: ContainedSpan, - /// The type info for the values in the Array - type_info: Box<TypeInfo>, - }, + #[display(fmt = "{}", "_0")] + Array(ContainedSpan<Box<TypeInfo>>), /// A standalone type, such as `string` or `Foo`. #[display(fmt = "{}", "_0")] Basic(TokenReference), /// A callback type, such as `(string, number) => boolean`. - #[display( - fmt = "{}{}{}{}{}", - "parentheses.tokens().0", - "arguments", - "parentheses.tokens().1", - "arrow", - "return_type" - )] + #[display(fmt = "{}{}{}", "arguments", "arrow", "return_type")] Callback { - /// The parentheses for the arguments. - parentheses: ContainedSpan, /// The argument types: `(string, number)`. - arguments: Punctuated<TypeArgument>, + arguments: ContainedSpan<Punctuated<TypeArgument>>, /// The "thin arrow" (`->`) in between the arguments and the return type. arrow: TokenReference, /// The return type: `boolean`. @@ -43,20 +29,12 @@ pub enum TypeInfo { }, /// A type using generics, such as `map<number, string>`. - #[display( - fmt = "{}{}{}{}", - "base", - "arrows.tokens().0", - "generics", - "arrows.tokens().1" - )] + #[display(fmt = "{}{}", "base", "generics")] Generic { /// The type that has generics: `map`. base: TokenReference, - /// The arrows (`<>`) containing the type parameters. - arrows: ContainedSpan, - /// The type parameters: `number, string`. - generics: Punctuated<TypeInfo>, + /// The type parameters: `<number, string>`. + generics: ContainedSpan<Punctuated<TypeInfo>>, }, /// An intersection type: `string & number`, denoting both types. @@ -91,44 +69,21 @@ pub enum TypeInfo { }, /// A type annotating the structure of a table: { foo: number, bar: string } - #[display(fmt = "{}{}{}", "braces.tokens().0", "fields", "braces.tokens().1")] - Table { - /// The braces (`{}`) containing the fields. - braces: ContainedSpan, - /// The fields: `foo: number, bar: string`. - fields: Punctuated<TypeField>, - }, + #[display(fmt = "{}", "_0")] + Table(ContainedSpan<Punctuated<TypeField>>), /// A type in the form of `typeof(foo)`. - #[display( - fmt = "{}{}{}{}", - "typeof_token", - "parentheses.tokens().0", - "inner", - "parentheses.tokens().1" - )] + #[display(fmt = "{}{}", "typeof_token", "expression")] Typeof { /// The token `typeof`. typeof_token: TokenReference, - /// The parentheses used to contain the expression. - parentheses: ContainedSpan, - /// The inner expression: `foo`. - inner: Box<Expression>, + /// The expression: `(foo)`. + expression: ContainedSpan<Box<Expression>>, }, /// A tuple expression: `(string, number)`. - #[display( - fmt = "{}{}{}", - "parentheses.tokens().0", - "types", - "parentheses.tokens().1" - )] - Tuple { - /// The parentheses used to contain the types - parentheses: ContainedSpan, - /// The types: `(string, number)`. - types: Punctuated<TypeInfo>, - }, + #[display(fmt = "{}", "_0")] + Tuple(ContainedSpan<Punctuated<TypeInfo>>), /// A union type: `string | number`, denoting one or the other. #[display(fmt = "{}{}{}", "left", "pipe", "right")] @@ -152,7 +107,7 @@ pub enum TypeInfo { } /// A subset of TypeInfo that consists of items which can only be used as an index, such as `Foo` and `Foo<Bar>`, -#[derive(Clone, Debug, Display, PartialEq, Node)] +#[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] pub enum IndexedTypeInfo { @@ -161,20 +116,12 @@ pub enum IndexedTypeInfo { Basic(TokenReference), /// A type using generics, such as `map<number, string>`. - #[display( - fmt = "{}{}{}{}", - "base", - "arrows.tokens().0", - "generics", - "arrows.tokens().1" - )] + #[display(fmt = "{}{}", "base", "generics")] Generic { /// The type that has generics: `map`. base: TokenReference, - /// The arrows (`<>`) containing the type parameters. - arrows: ContainedSpan, - /// The type parameters: `number, string`. - generics: Punctuated<TypeInfo>, + /// The type parameters: `<number, string>`. + generics: ContainedSpan<Punctuated<TypeInfo>>, }, } @@ -234,7 +181,7 @@ impl TypeField { } /// A key in a [`TypeField`]. Can either be a name or an index signature. -#[derive(Clone, Debug, Display, PartialEq, Node)] +#[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[non_exhaustive] pub enum TypeFieldKey { @@ -243,14 +190,8 @@ pub enum TypeFieldKey { Name(TokenReference), /// An index signature, such as `[number]`. - #[display(fmt = "{}{}{}", "brackets.tokens().0", "inner", "brackets.tokens().1")] - IndexSignature { - /// The brackets (`[]`) used to contain the type. - brackets: ContainedSpan, - - /// The type for the index signature, `number` in `[number]`. - inner: TypeInfo, - }, + #[display(fmt = "{}", "_0")] + IndexSignature(ContainedSpan<TypeInfo>), } /// A type assertion using `::`, such as `:: number`. @@ -389,43 +330,45 @@ impl TypeDeclaration { /// The generics used in a [`TypeDeclaration`]. #[derive(Clone, Debug, Display, PartialEq, Node, Visit)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] -#[display(fmt = "{}{}{}", "arrows.tokens().0", "generics", "arrows.tokens().1")] +#[display(fmt = "{}", "generics")] pub struct GenericDeclaration { - #[visit(contains = "generics")] - pub(crate) arrows: ContainedSpan, - pub(crate) generics: Punctuated<TokenReference>, + pub(crate) generics: ContainedSpan<Punctuated<TokenReference>>, } impl GenericDeclaration { /// Creates a new GenericDeclaration pub fn new() -> Self { Self { - arrows: ContainedSpan::new( + generics: ContainedSpan::new( TokenReference::symbol("<").unwrap(), + Punctuated::new(), TokenReference::symbol(">").unwrap(), ), - generics: Punctuated::new(), } } /// The arrows (`<>`) containing the types. - pub fn arrows(&self) -> &ContainedSpan { - &self.arrows + pub fn arrows(&self) -> (&TokenReference, &TokenReference) { + self.generics.tokens() } /// The names of the generics: `T, U` in `<T, U>`. pub fn generics(&self) -> &Punctuated<TokenReference> { - &self.generics + self.generics.inner() } /// Returns a new GenericDeclaration with the given arrows containing the types - pub fn with_arrows(self, arrows: ContainedSpan) -> Self { - Self { arrows, ..self } + pub fn with_arrows(self, arrows: (TokenReference, TokenReference)) -> Self { + Self { + generics: self.generics.with_tokens(arrows), + } } /// Returns a new TypeDeclaration with the given names of the generics pub fn with_generics(self, generics: Punctuated<TokenReference>) -> Self { - Self { generics, ..self } + Self { + generics: self.generics.with_inner(generics), + } } } diff --git a/full-moon/src/ast/visitors.rs b/full-moon/src/ast/visitors.rs index 9c3ce051..022fb731 100644 --- a/full-moon/src/ast/visitors.rs +++ b/full-moon/src/ast/visitors.rs @@ -3,270 +3,11 @@ use super::*; use crate::visitors::{Visit, VisitMut, Visitor, VisitorMut}; -// The following have `ContainedSpan`, which when automatically derived will visit the tokens containing -// before they visit what they're actually containing. -// For example, if there is an AST node that represents `(foo)`... -// Then visitors will visit this as `()foo`. -// This is fixed for structs with `#[visit(contains = "...")], but this is not supported on enums. - -impl Visit for Field { - fn visit<V: Visitor>(&self, visitor: &mut V) { - visitor.visit_field(self); - match self { - Field::ExpressionKey { - brackets, - key, - equal, - value, - } => { - brackets.tokens.0.visit(visitor); - key.visit(visitor); - brackets.tokens.1.visit(visitor); - equal.visit(visitor); - value.visit(visitor); - } - - Field::NameKey { key, equal, value } => { - key.visit(visitor); - equal.visit(visitor); - value.visit(visitor); - } - - Field::NoKey(__self_0) => { - __self_0.visit(visitor); - } - }; - - visitor.visit_field_end(self); - } -} - -impl VisitMut for Field { - fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { - self = visitor.visit_field(self); - self = match self { - Field::ExpressionKey { - mut brackets, - - mut key, - equal, - value, - } => { - brackets.tokens.0 = brackets.tokens.0.visit_mut(visitor); - key = key.visit_mut(visitor); - brackets.tokens.1 = brackets.tokens.1.visit_mut(visitor); - - Field::ExpressionKey { - brackets, - key, - equal: equal.visit_mut(visitor), - value: value.visit_mut(visitor), - } - } - - Field::NameKey { key, equal, value } => Field::NameKey { - key: key.visit_mut(visitor), - equal: equal.visit_mut(visitor), - value: value.visit_mut(visitor), - }, - - Field::NoKey(__self_0) => Field::NoKey(__self_0.visit_mut(visitor)), - }; - - self = visitor.visit_field_end(self); - self - } -} - -impl Visit for Expression { - fn visit<V: Visitor>(&self, visitor: &mut V) { - visitor.visit_expression(self); - match self { - Expression::BinaryOperator { lhs, binop, rhs } => { - lhs.visit(visitor); - binop.visit(visitor); - rhs.visit(visitor); - } - - Expression::Parentheses { - contained, - expression, - } => { - contained.tokens.0.visit(visitor); - expression.visit(visitor); - contained.tokens.1.visit(visitor); - } - Expression::UnaryOperator { unop, expression } => { - unop.visit(visitor); - expression.visit(visitor); - } - Expression::Value { - value, - #[cfg(feature = "roblox")] - type_assertion, - } => { - value.visit(visitor); - #[cfg(feature = "roblox")] - type_assertion.visit(visitor); - } - }; - - visitor.visit_expression_end(self); - } -} - -impl VisitMut for Expression { - fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { - self = visitor.visit_expression(self); - self = match self { - Expression::BinaryOperator { lhs, binop, rhs } => Expression::BinaryOperator { - lhs: lhs.visit_mut(visitor), - binop: binop.visit_mut(visitor), - rhs: rhs.visit_mut(visitor), - }, - - Expression::Parentheses { - mut contained, - mut expression, - } => { - contained.tokens.0 = contained.tokens.0.visit_mut(visitor); - expression = expression.visit_mut(visitor); - contained.tokens.1 = contained.tokens.1.visit_mut(visitor); - - Expression::Parentheses { - contained, - expression, - } - } - - Expression::UnaryOperator { unop, expression } => Expression::UnaryOperator { - unop: unop.visit_mut(visitor), - expression: expression.visit_mut(visitor), - }, - - Expression::Value { - value, - #[cfg(feature = "roblox")] - type_assertion, - } => Expression::Value { - value: value.visit_mut(visitor), - #[cfg(feature = "roblox")] - type_assertion: type_assertion.visit_mut(visitor), - }, - }; - - self = visitor.visit_expression_end(self); - self - } -} - -impl Visit for Index { - fn visit<V: Visitor>(&self, visitor: &mut V) { - visitor.visit_index(self); - match self { - Index::Brackets { - brackets, - expression, - } => { - brackets.tokens.0.visit(visitor); - expression.visit(visitor); - brackets.tokens.1.visit(visitor); - } - Index::Dot { dot, name } => { - dot.visit(visitor); - name.visit(visitor); - } - }; - - visitor.visit_index_end(self); - } -} - -impl VisitMut for Index { - fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { - self = visitor.visit_index(self); - self = match self { - Index::Brackets { - mut brackets, - mut expression, - } => { - brackets.tokens.0 = brackets.tokens.0.visit_mut(visitor); - expression = expression.visit_mut(visitor); - brackets.tokens.1 = brackets.tokens.1.visit_mut(visitor); - - Index::Brackets { - brackets, - expression, - } - } - - Index::Dot { dot, name } => Index::Dot { - dot: dot.visit_mut(visitor), - name: name.visit_mut(visitor), - }, - }; - - self = visitor.visit_index_end(self); - self - } -} - -impl Visit for FunctionArgs { - fn visit<V: Visitor>(&self, visitor: &mut V) { - visitor.visit_function_args(self); - match self { - FunctionArgs::Parentheses { - parentheses, - arguments, - } => { - parentheses.tokens.0.visit(visitor); - arguments.visit(visitor); - parentheses.tokens.1.visit(visitor); - } - FunctionArgs::String(__self_0) => { - __self_0.visit(visitor); - } - FunctionArgs::TableConstructor(__self_0) => { - __self_0.visit(visitor); - } - }; - - visitor.visit_function_args_end(self); - } -} - -impl VisitMut for FunctionArgs { - fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { - self = visitor.visit_function_args(self); - self = match self { - FunctionArgs::Parentheses { - mut parentheses, - mut arguments, - } => { - parentheses.tokens.0 = parentheses.tokens.0.visit_mut(visitor); - arguments = arguments.visit_mut(visitor); - parentheses.tokens.1 = parentheses.tokens.1.visit_mut(visitor); - FunctionArgs::Parentheses { - parentheses, - arguments, - } - } - FunctionArgs::String(__self_0) => FunctionArgs::String(__self_0.visit_mut(visitor)), - FunctionArgs::TableConstructor(__self_0) => { - FunctionArgs::TableConstructor(__self_0.visit_mut(visitor)) - } - }; - - self = visitor.visit_function_args_end(self); - self - } -} - // The following contain type signatures, which are addendums to previous identities impl Visit for FunctionBody { fn visit<V: Visitor>(&self, visitor: &mut V) { visitor.visit_function_body(self); - self.parameters_parentheses.tokens.0.visit(visitor); + self.parameters.start.visit(visitor); let mut type_specifiers; @@ -281,12 +22,12 @@ impl Visit for FunctionBody { type_specifiers = std::iter::repeat::<Option<Self>>(None); } - for parameter in &self.parameters { + for parameter in &self.parameters.inner { parameter.visit(visitor); type_specifiers.next().visit(visitor); } - self.parameters_parentheses.tokens.1.visit(visitor); + self.parameters.end.visit(visitor); #[cfg(feature = "roblox")] self.return_type.visit(visitor); @@ -300,8 +41,7 @@ impl Visit for FunctionBody { impl VisitMut for FunctionBody { fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { self = visitor.visit_function_body(self); - self.parameters_parentheses.tokens.0 = - self.parameters_parentheses.tokens.0.visit_mut(visitor); + self.parameters.start = self.parameters.start.visit_mut(visitor); let mut type_specifiers; @@ -319,7 +59,7 @@ impl VisitMut for FunctionBody { let mut new_type_specifiers = Vec::new(); let mut new_parameters = Punctuated::new(); - for parameter_pair in self.parameters.into_pairs() { + for parameter_pair in self.parameters.inner.into_pairs() { let parameter_tuple = parameter_pair.into_tuple(); let parameter = parameter_tuple.0.visit_mut(visitor); @@ -333,15 +73,14 @@ impl VisitMut for FunctionBody { new_parameters.push(Pair::new(parameter, punctuation)); } - self.parameters = new_parameters; + self.parameters.inner = new_parameters; #[cfg(feature = "roblox")] { self.type_specifiers = new_type_specifiers; } - self.parameters_parentheses.tokens.1 = - self.parameters_parentheses.tokens.1.visit_mut(visitor); + self.parameters.end = self.parameters.end.visit_mut(visitor); #[cfg(feature = "roblox")] { diff --git a/full-moon/src/visitors.rs b/full-moon/src/visitors.rs index 98431f1e..305b3cfe 100644 --- a/full-moon/src/visitors.rs +++ b/full-moon/src/visitors.rs @@ -1,5 +1,5 @@ use crate::{ - ast::{span::ContainedSpan, *}, + ast::*, private::Sealed, tokenizer::{Token, TokenReference}, }; @@ -219,7 +219,6 @@ create_visitor!(ast: { visit_assignment => Assignment, visit_block => Block, visit_call => Call, - visit_contained_span => ContainedSpan, visit_do => Do, visit_else_if => ElseIf, visit_eof => TokenReference,