ezno_parser/
visiting.rs

1//! Contains logic that makes viewing and transform parts of AST trivial through the visitor pattern
2
3use source_map::SourceId;
4
5use crate::{
6	ArrayDestructuringField, Expression, ObjectDestructuringField, PropertyKey,
7	StatementOrDeclaration, WithComment,
8};
9
10pub use temporary_annex::Annex;
11
12pub use ast::*;
13pub use structures::*;
14pub use visitors::*;
15pub use visitors_mut::*;
16
17mod ast {
18	use temporary_annex::Annex;
19
20	use crate::block::{BlockLike, BlockLikeMut};
21
22	use super::{
23		BlockItem, BlockItemMut, Chain, Expression, ImmutableVariableOrProperty,
24		MutableVariableOrProperty, VisitorMutReceiver, VisitorReceiver,
25	};
26
27	/// Options for behavior when visiting AST.
28	/// Customizable behavior is important for analysis
29	pub struct VisitOptions {
30		/// Visits statements in reverse,
31		/// e.g
32		/// ```ts
33		/// const x = 2;
34		/// const y = 3;
35		/// ```
36		/// If `reverse_statements` is true, `const y = 3` will be visited before `const x = 2`
37		pub reverse_statements: bool,
38		/// Will not visit anything under nested blocks, functions etc
39		pub visit_nested_blocks: bool,
40	}
41
42	impl Default for VisitOptions {
43		fn default() -> Self {
44			Self { reverse_statements: false, visit_nested_blocks: true }
45		}
46	}
47
48	/// Whether something has visit self
49	macro_rules! mark_items {
50        (impl $trait:ident for $($t:ty),*) => {
51            $(
52                impl $trait for $t {}
53            )*
54        }
55    }
56
57	/// Yielded during visiting AST. Might not be 1:1 with AST and include a wrapping type
58	pub trait SelfVisitable {}
59
60	/// Yielded during visiting AST. Might not be 1:1 with AST and include a wrapping type
61	pub trait SelfVisitableMut {}
62
63	mark_items! {
64		impl SelfVisitable for Expression, BlockItem<'_>, BlockLike<'_>, ImmutableVariableOrProperty<'_>
65	}
66
67	mark_items! {
68		impl SelfVisitableMut for Expression, BlockLikeMut<'_>, BlockItemMut<'_>, MutableVariableOrProperty<'_>
69	}
70
71	/// For something to visitable it can visit all nested fields.
72	pub trait Visitable {
73		fn visit<TData>(
74			&self,
75			visitors: &mut (impl VisitorReceiver<TData> + ?Sized),
76			data: &mut TData,
77			options: &VisitOptions,
78			chain: &mut Annex<Chain>,
79		);
80
81		fn visit_mut<TData>(
82			&mut self,
83			visitors: &mut (impl VisitorMutReceiver<TData> + ?Sized),
84			data: &mut TData,
85			options: &VisitOptions,
86			chain: &mut Annex<Chain>,
87		);
88	}
89
90	// Implementing Visitable to some structures that are commonly used in AST
91	impl<T: Visitable> Visitable for Box<T> {
92		fn visit<TData>(
93			&self,
94			v: &mut (impl VisitorReceiver<TData> + ?Sized),
95			d: &mut TData,
96			s: &VisitOptions,
97			c: &mut Annex<Chain>,
98		) {
99			Visitable::visit(&**self, v, d, s, c);
100		}
101
102		fn visit_mut<TData>(
103			&mut self,
104			v: &mut (impl VisitorMutReceiver<TData> + ?Sized),
105			d: &mut TData,
106			s: &VisitOptions,
107			c: &mut Annex<Chain>,
108		) {
109			Visitable::visit_mut(&mut **self, v, d, s, c);
110		}
111	}
112
113	impl<T: Visitable> Visitable for Vec<T> {
114		fn visit<TData>(
115			&self,
116			v: &mut (impl VisitorReceiver<TData> + ?Sized),
117			d: &mut TData,
118			s: &VisitOptions,
119			c: &mut Annex<Chain>,
120		) {
121			self.iter().for_each(|item| item.visit(v, d, s, c));
122		}
123
124		fn visit_mut<TData>(
125			&mut self,
126			v: &mut (impl VisitorMutReceiver<TData> + ?Sized),
127			d: &mut TData,
128			s: &VisitOptions,
129			c: &mut Annex<Chain>,
130		) {
131			self.iter_mut().for_each(|item| item.visit_mut(v, d, s, c));
132		}
133	}
134
135	impl<T: Visitable> Visitable for Option<T> {
136		fn visit<TData>(
137			&self,
138			v: &mut (impl VisitorReceiver<TData> + ?Sized),
139			d: &mut TData,
140			s: &VisitOptions,
141			c: &mut Annex<Chain>,
142		) {
143			if let Some(item) = self {
144				item.visit(v, d, s, c);
145			}
146		}
147
148		fn visit_mut<TData>(
149			&mut self,
150			v: &mut (impl VisitorMutReceiver<TData> + ?Sized),
151			d: &mut TData,
152			s: &VisitOptions,
153			c: &mut Annex<Chain>,
154		) {
155			if let Some(item) = self {
156				item.visit_mut(v, d, s, c);
157			}
158		}
159	}
160
161	impl<T: Visitable, U: Visitable> Visitable for (T, U) {
162		fn visit<TData>(
163			&self,
164			v: &mut (impl VisitorReceiver<TData> + ?Sized),
165			d: &mut TData,
166			s: &VisitOptions,
167			c: &mut Annex<Chain>,
168		) {
169			self.0.visit(v, d, s, c);
170			self.1.visit(v, d, s, c);
171		}
172
173		fn visit_mut<TData>(
174			&mut self,
175			v: &mut (impl VisitorMutReceiver<TData> + ?Sized),
176			d: &mut TData,
177			s: &VisitOptions,
178			c: &mut Annex<Chain>,
179		) {
180			self.0.visit_mut(v, d, s, c);
181			self.1.visit_mut(v, d, s, c);
182		}
183	}
184
185	macro_rules! create_blank_visiting_implementations {
186        ($($T:ty),*) => {
187            $(
188                impl Visitable for $T {
189                    fn visit<TData>(
190                        &self,
191                        _visitors: &mut (impl VisitorReceiver<TData> + ?Sized),
192                        _data: &mut TData,
193                        _options: &VisitOptions,
194                        _chain: &mut Annex<Chain>,
195                    ) {}
196
197                    fn visit_mut<TData>(
198                        &mut self,
199                        _visitors: &mut (impl VisitorMutReceiver<TData> + ?Sized),
200                        _data: &mut TData,
201                        _options: &VisitOptions,
202                        _chain: &mut Annex<Chain>,
203                    ) {}
204                }
205            )*
206        }
207    }
208
209	// A bunch of blank implementations for data types that do not have
210	// any AST nested / aren't important for visiting.
211	create_blank_visiting_implementations![
212		(),
213		bool,
214		isize,
215		usize,
216		i8,
217		u8,
218		i16,
219		u16,
220		i32,
221		u32,
222		i64,
223		u64,
224		i128,
225		u128,
226		f32,
227		f64,
228		char,
229		String,
230		Box<str>,
231		std::rc::Rc<str>,
232		std::path::Path,
233		std::path::PathBuf,
234		source_map::Span,
235		crate::TypeAnnotation,
236		crate::types::Visibility,
237		crate::number::NumberRepresentation,
238		crate::expressions::operators::BinaryOperator,
239		crate::expressions::operators::BinaryAssignmentOperator,
240		crate::expressions::operators::UnaryOperator,
241		crate::expressions::operators::UnaryPrefixAssignmentOperator,
242		crate::expressions::operators::UnaryPostfixAssignmentOperator,
243		crate::types::InterfaceDeclaration,
244		crate::types::type_alias::TypeAlias,
245		crate::types::type_annotations::IsItem,
246		crate::types::declare_variable::DeclareVariableDeclaration,
247		crate::VariableIdentifier,
248		crate::PropertyReference,
249		crate::Quoted,
250		crate::declarations::ImportExportName,
251		crate::declarations::ImportLocation,
252		crate::functions::FunctionHeader,
253		crate::functions::MethodHeader,
254		crate::VariableKeyword,
255		source_map::SourceId
256	];
257}
258
259/// Data used when visiting AST
260mod structures {
261	use crate::{
262		property_key::{AlwaysPublic, PublicOrPrivate},
263		Statement, VariableField, VariableIdentifier,
264	};
265
266	use super::{
267		ArrayDestructuringField, ObjectDestructuringField, PropertyKey, SourceId,
268		StatementOrDeclaration, WithComment,
269	};
270	use source_map::Span;
271	use temporary_annex::{Annex, Annexable};
272
273	#[derive(Debug, Clone)]
274	pub enum ChainVariable {
275		Module(SourceId),
276		Function(Span),
277		Block(Span),
278	}
279
280	/// Contains [`ChainVariable`]s which signal the position in the AST
281	#[derive(Debug, Clone)]
282	pub struct Chain(Vec<ChainVariable>);
283
284	impl Chain {
285		#[must_use]
286		pub fn new() -> Self {
287			Self(Vec::with_capacity(10))
288		}
289
290		#[must_use]
291		pub fn new_with_initial(initial: ChainVariable) -> Self {
292			let mut buf = Vec::with_capacity(10);
293			buf.push(initial);
294			Self(buf)
295		}
296
297		#[must_use]
298		pub fn len(&self) -> usize {
299			self.0.len()
300		}
301
302		#[must_use]
303		pub fn is_empty(&self) -> bool {
304			self.0.is_empty()
305		}
306
307		pub fn truncate(&mut self, to_size: usize) {
308			self.0.truncate(to_size);
309		}
310
311		#[must_use]
312		pub fn get_module(&self) -> SourceId {
313			if let ChainVariable::Module(source) = self.0.first().unwrap() {
314				source.to_owned()
315			} else {
316				source_map::Nullable::NULL
317			}
318		}
319
320		// TODO get function root. Aka last thing before in top level scope or
321	}
322
323	impl Annexable for Chain {
324		type NewItem = ChainVariable;
325
326		fn push_annex(&mut self, item: Self::NewItem) -> Annex<Self>
327		where
328			Self: Sized,
329		{
330			self.0.push(item);
331			Annex::new(self)
332		}
333
334		fn revert_annex(&mut self) {
335			self.0.pop();
336		}
337	}
338
339	#[derive(Debug)]
340	pub enum ImmutableVariableOrProperty<'a> {
341		// TODO maybe WithComment on some of these
342		VariableFieldName(&'a str, &'a Span),
343		// TODO these should maybe only be the spread variables
344		ArrayDestructuringMember(&'a ArrayDestructuringField<VariableField>),
345		ObjectDestructuringMember(&'a WithComment<ObjectDestructuringField<VariableField>>),
346		ClassName(Option<&'a VariableIdentifier>),
347		FunctionName(Option<&'a VariableIdentifier>),
348		ClassPropertyKey(&'a PropertyKey<PublicOrPrivate>),
349		ObjectPropertyKey(&'a PropertyKey<AlwaysPublic>),
350	}
351
352	#[derive(Debug)]
353	pub enum MutableVariableOrProperty<'a> {
354		VariableFieldName(&'a mut String),
355		// TODO these should maybe only be the spread variables
356		ArrayDestructuringMember(&'a mut ArrayDestructuringField<VariableField>),
357		ObjectDestructuringMember(&'a mut WithComment<ObjectDestructuringField<VariableField>>),
358		ClassName(Option<&'a mut VariableIdentifier>),
359		FunctionName(Option<&'a mut VariableIdentifier>),
360		ClassPropertyKey(&'a mut PropertyKey<PublicOrPrivate>),
361		ObjectPropertyKey(&'a mut PropertyKey<AlwaysPublic>),
362	}
363
364	impl<'a> ImmutableVariableOrProperty<'a> {
365		#[must_use]
366		pub fn get_variable_name(&self) -> Option<&'a str> {
367			match self {
368				ImmutableVariableOrProperty::VariableFieldName(name, _) => Some(name),
369				ImmutableVariableOrProperty::ArrayDestructuringMember(_) => None,
370				ImmutableVariableOrProperty::ObjectDestructuringMember(o) => {
371					match o.get_ast_ref() {
372						ObjectDestructuringField::Name(VariableIdentifier::Standard(a, ..), ..) => {
373							Some(a.as_str())
374						}
375						_ => None,
376					}
377				}
378				ImmutableVariableOrProperty::FunctionName(name)
379				| ImmutableVariableOrProperty::ClassName(name) => {
380					if let Some(VariableIdentifier::Standard(name, _)) = name {
381						Some(name)
382					} else {
383						None
384					}
385				}
386				ImmutableVariableOrProperty::ObjectPropertyKey(_property) => {
387					// Just want variable names
388					None
389					// match property.get_ast_ref() {
390					// 	PropertyKey::Identifier(ident, _, _)
391					// 	| PropertyKey::StringLiteral(ident, _, _) => Some(ident.as_str()),
392					// 	PropertyKey::NumberLiteral(_, _) | PropertyKey::Computed(_, _) => None,
393					// }
394				}
395				ImmutableVariableOrProperty::ClassPropertyKey(_property) => {
396					// Just want variable names
397					None
398					// match property.get_ast_ref() {
399					// 	PropertyKey::Identifier(ident, _, _)
400					// 	| PropertyKey::StringLiteral(ident, _, _) => Some(ident.as_str()),
401					// 	PropertyKey::NumberLiteral(_, _) | PropertyKey::Computed(_, _) => None,
402					// }
403				}
404			}
405		}
406
407		#[must_use]
408		pub fn get_position(&self) -> Span {
409			use crate::ASTNode;
410			match self {
411				ImmutableVariableOrProperty::FunctionName(pos)
412				| ImmutableVariableOrProperty::ClassName(pos) => match pos {
413					Some(p) => p.get_position(),
414					None => source_map::Nullable::NULL,
415				},
416				ImmutableVariableOrProperty::VariableFieldName(_, pos) => **pos,
417				ImmutableVariableOrProperty::ArrayDestructuringMember(m) => m.get_position(),
418				ImmutableVariableOrProperty::ObjectDestructuringMember(m) => m.get_position(),
419				ImmutableVariableOrProperty::ClassPropertyKey(k) => k.get_position(),
420				ImmutableVariableOrProperty::ObjectPropertyKey(k) => k.get_position(),
421			}
422		}
423	}
424
425	/// Wrapper type for [`StatementOrDeclaration`]. Needed because [`crate::Statement`] doesn't
426	/// come under [`StatementOrDeclaration`] in the case of [`crate::BlockOrSingleStatement`]
427	pub enum BlockItem<'a> {
428		StatementOrDeclaration(&'a crate::StatementOrDeclaration),
429		SingleStatement(&'a crate::Statement),
430	}
431
432	impl<'a> From<&'a StatementOrDeclaration> for BlockItem<'a> {
433		fn from(item: &'a StatementOrDeclaration) -> Self {
434			BlockItem::StatementOrDeclaration(item)
435		}
436	}
437
438	impl<'a> From<&'a Statement> for BlockItem<'a> {
439		fn from(item: &'a Statement) -> Self {
440			BlockItem::SingleStatement(item)
441		}
442	}
443
444	/// Wrapper type for [`StatementOrDeclaration`]. Needed because [`crate::Statement`] doesn't
445	/// come under [`StatementOrDeclaration`] in the case of [`crate::BlockOrSingleStatement`]
446	pub enum BlockItemMut<'a> {
447		StatementOrDeclaration(&'a mut crate::StatementOrDeclaration),
448		SingleStatement(&'a mut crate::Statement),
449	}
450
451	impl<'a> From<&'a mut StatementOrDeclaration> for BlockItemMut<'a> {
452		fn from(item: &'a mut StatementOrDeclaration) -> Self {
453			BlockItemMut::StatementOrDeclaration(item)
454		}
455	}
456
457	impl<'a> From<&'a mut Statement> for BlockItemMut<'a> {
458		fn from(item: &'a mut Statement) -> Self {
459			BlockItemMut::SingleStatement(item)
460		}
461	}
462}
463
464mod visitors {
465	use super::{BlockItem, Chain, Expression, ImmutableVariableOrProperty, SelfVisitable};
466	use crate::{block::BlockLike, TSXKeyword};
467	use source_map::Span;
468
469	/// A visitor over something which is hooked/is [`SelfVisitable`] with some generic `Data`
470	pub trait Visitor<Item: SelfVisitable, Data> {
471		fn visit(&mut self, item: &Item, data: &mut Data, chain: &Chain);
472	}
473
474	/// Something which has a bunch of callbacks for AST
475	#[allow(unused_variables)]
476	pub trait VisitorReceiver<T> {
477		fn visit_expression(&mut self, expression: &Expression, data: &mut T, chain: &Chain) {}
478
479		fn visit_statement(&mut self, statement: BlockItem, data: &mut T, chain: &Chain) {}
480
481		fn visit_variable(
482			&mut self,
483			variable: &ImmutableVariableOrProperty,
484			data: &mut T,
485			chain: &Chain,
486		) {
487		}
488
489		fn visit_block(&mut self, block: &BlockLike, data: &mut T, chain: &Chain) {}
490
491		fn visit_keyword(&mut self, keyword: &(TSXKeyword, &Span), data: &mut T, chain: &Chain) {}
492	}
493
494	impl<T> VisitorReceiver<T> for Visitors<T> {
495		fn visit_expression(&mut self, expression: &Expression, data: &mut T, chain: &Chain) {
496			self.expression_visitors.iter_mut().for_each(|vis| vis.visit(expression, data, chain));
497		}
498
499		fn visit_statement(&mut self, statement: BlockItem, data: &mut T, chain: &Chain) {
500			self.statement_visitors.iter_mut().for_each(|vis| vis.visit(&statement, data, chain));
501		}
502
503		fn visit_variable(
504			&mut self,
505			variable: &ImmutableVariableOrProperty,
506			data: &mut T,
507			chain: &Chain,
508		) {
509			self.variable_visitors.iter_mut().for_each(|vis| vis.visit(variable, data, chain));
510		}
511
512		fn visit_block(&mut self, block: &BlockLike, data: &mut T, chain: &Chain) {
513			self.block_visitors.iter_mut().for_each(|vis| vis.visit(block, data, chain));
514		}
515
516		fn visit_keyword(&mut self, _keyword: &(TSXKeyword, &Span), _data: &mut T, _chain: &Chain) {
517		}
518	}
519
520	type ExpressionVisitor<T> = Box<dyn Visitor<Expression, T>>;
521	type StatementVisitor<T> = Box<dyn for<'a> Visitor<BlockItem<'a>, T>>;
522	type VariableVisitor<T> = Box<dyn for<'a> Visitor<ImmutableVariableOrProperty<'a>, T>>;
523	type BlockVisitor<T> = Box<dyn for<'a> Visitor<BlockLike<'a>, T>>;
524
525	/// A utility type which implements [`VisitorReceiver`]. Use for running a bunch of different **immutable**
526	/// visitors over a **immutable** AST. Used for simple analysis
527	#[derive(Default)]
528	pub struct Visitors<T> {
529		pub expression_visitors: Vec<ExpressionVisitor<T>>,
530		pub statement_visitors: Vec<StatementVisitor<T>>,
531		pub variable_visitors: Vec<VariableVisitor<T>>,
532		pub block_visitors: Vec<BlockVisitor<T>>,
533	}
534
535	// impl<T, U> Visitor<Expression, T> for U
536	// where
537	// 	U: Fn(&Expression, &mut T),
538	// {
539	// 	fn visit(&mut self, expression: &Expression, data: &mut T, _chain: &Chain) {
540	// 		(self)(expression, data)
541	// 	}
542	// }
543
544	// impl<T, U> Visitor<Statement, T> for U
545	// where
546	// 	U: Fn(&Statement, &mut T),
547	// {
548	// 	fn visit(&mut self, statement: &Statement, data: &mut T, _chain: &Chain) {
549	// 		(self)(statement, data)
550	// 	}
551	// }
552
553	// impl<'a, T, U> Visitor<ImmutableVariableOrPropertyPart<'a>, T> for U
554	// where
555	// 	U: Fn(&ImmutableVariableOrPropertyPart, &mut T),
556	// {
557	// 	fn visit(
558	// 		&mut self,
559	// 		variable: &ImmutableVariableOrPropertyPart<'a>,
560	// 		data: &mut T,
561	// 		_chain: &Chain,
562	// 	) {
563	// 		(self)(variable, data)
564	// 	}
565	// }
566}
567
568mod visitors_mut {
569	use crate::block::BlockLikeMut;
570
571	use super::{BlockItemMut, Chain, Expression, MutableVariableOrProperty, SelfVisitableMut};
572
573	/// A visitor over something which is hooked/is [`SelfVisitableMut`] with some Data
574	pub trait VisitorMut<Item: SelfVisitableMut, Data> {
575		fn visit_mut(&mut self, item: &mut Item, data: &mut Data, chain: &Chain);
576	}
577
578	/// These are a receiver traits of the visitor
579	#[allow(unused_variables)]
580	pub trait VisitorMutReceiver<T> {
581		fn visit_expression_mut(
582			&mut self,
583			expression: &mut Expression,
584			data: &mut T,
585			chain: &Chain,
586		) {
587		}
588
589		fn visit_statement_mut(&mut self, statement: BlockItemMut, data: &mut T, chain: &Chain) {}
590
591		fn visit_variable_mut(
592			&mut self,
593			variable: &mut MutableVariableOrProperty,
594			data: &mut T,
595			chain: &Chain,
596		) {
597		}
598
599		fn visit_block_mut(&mut self, block: &mut BlockLikeMut, data: &mut T, chain: &Chain) {}
600	}
601
602	type StatementVisitor<T> = Box<dyn for<'a> VisitorMut<BlockItemMut<'a>, T>>;
603	type VariableVisitor<T> = Box<dyn for<'a> VisitorMut<MutableVariableOrProperty<'a>, T>>;
604	type BlockVisitor<T> = Box<dyn for<'a> VisitorMut<BlockLikeMut<'a>, T>>;
605
606	/// A utility type which implements [`VisitorMutReceiver`]. Use for running a bunch of different **mutable**
607	/// visitors over a **mutable** AST. Therefore can remove, add or change AST
608	pub struct VisitorsMut<T> {
609		pub expression_visitors_mut: Vec<Box<dyn VisitorMut<Expression, T>>>,
610		pub statement_visitors_mut: Vec<StatementVisitor<T>>,
611		pub variable_visitors_mut: Vec<VariableVisitor<T>>,
612		pub block_visitors_mut: Vec<BlockVisitor<T>>,
613	}
614
615	impl<T> Default for VisitorsMut<T> {
616		fn default() -> Self {
617			Self {
618				expression_visitors_mut: Default::default(),
619				statement_visitors_mut: Default::default(),
620				variable_visitors_mut: Default::default(),
621				block_visitors_mut: Default::default(),
622			}
623		}
624	}
625
626	impl<T> VisitorMutReceiver<T> for VisitorsMut<T> {
627		fn visit_expression_mut(
628			&mut self,
629			expression: &mut Expression,
630			data: &mut T,
631			chain: &Chain,
632		) {
633			self.expression_visitors_mut
634				.iter_mut()
635				.for_each(|vis| vis.visit_mut(expression, data, chain));
636		}
637
638		fn visit_statement_mut(&mut self, mut item: BlockItemMut, data: &mut T, chain: &Chain) {
639			self.statement_visitors_mut
640				.iter_mut()
641				.for_each(|vis| vis.visit_mut(&mut item, data, chain));
642		}
643
644		fn visit_variable_mut(
645			&mut self,
646			variable: &mut MutableVariableOrProperty,
647			data: &mut T,
648			chain: &Chain,
649		) {
650			self.variable_visitors_mut
651				.iter_mut()
652				.for_each(|vis| vis.visit_mut(variable, data, chain));
653		}
654
655		fn visit_block_mut(&mut self, block: &mut BlockLikeMut, data: &mut T, chain: &Chain) {
656			self.block_visitors_mut.iter_mut().for_each(|vis| vis.visit_mut(block, data, chain));
657		}
658	}
659
660	// Implementors for functions...
661	// impl<T, U> VisitorMut<Expression, T> for U
662	// where
663	// 	U: Fn(&mut Expression, &mut T),
664	// {
665	// 	fn visit_mut(&mut self, expression: &mut Expression, data: &mut T, _chain: &Chain) {
666	// 		(self)(expression, data)
667	// 	}
668	// }
669
670	// impl<T, U> VisitorMut<Statement, T> for U
671	// where
672	// 	U: Fn(&mut Statement, &mut T),
673	// {
674	// 	fn visit_mut(&mut self, statement: &mut Statement, data: &mut T, _chain: &Chain) {
675	// 		(self)(statement, data)
676	// 	}
677	// }
678
679	// impl<'a, T, U> VisitorMut<MutableVariablePart<'a>, T> for U
680	// where
681	// 	U: Fn(&mut MutableVariablePart, &mut T),
682	// {
683	// 	fn visit_mut(&mut self, item: &mut MutableVariablePart, data: &mut T, _chain: &Chain) {
684	// 		(self)(item, data)
685	// 	}
686	// }
687}